ret2reg

Using register

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 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.

Any function that returns a pointer to the provided string is a prime target. There are many that do this, including :

  • gets()

  • strcpy()

  • fgets()

  • ...

Code example

#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 :

Exploitation

Using a jmp rax gadget it's possible to jump directly into the user input without knowing the address of it :

Using Buffer Overflow to set the gadget as return and jump into shellcode :

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.

Resources

Last updated