Using ret2reg
Source
Any function that returns a pointer to the string once it acts on it is a prime target. There are many that do this, including stuff like gets(), strcpy() and fgets(). We''l keep it simple and use gets() as an example.
#include <stdio.h>
void vuln() {
char buffer[100];
gets(buffer);
}
int main() {
vuln();
return 0;
}Analysis
First, let's make sure that some register does point to the buffer:
$ r2 -d -A vuln
[0x7f8ac76fa090]> pdf @ sym.vuln
; CALL XREF from main @ 0x401147
┌ 28: sym.vuln ();
│ ; var int64_t var_70h @ rbp-0x70
│ 0x00401122 55 push rbp
│ 0x00401123 4889e5 mov rbp, rsp
│ 0x00401126 4883ec70 sub rsp, 0x70
│ 0x0040112a 488d4590 lea rax, [var_70h]
│ 0x0040112e 4889c7 mov rdi, rax
│ 0x00401131 b800000000 mov eax, 0
│ 0x00401136 e8f5feffff call sym.imp.gets ; char *gets(char *s)
│ 0x0040113b 90 nop
│ 0x0040113c c9 leave
└ 0x0040113d c3 retNow we'll set a breakpoint on the ret in vuln(), continue and enter text.
We've hit the breakpoint, let's check if RAX points to our register. We'll assume RAX first because that's the traditional register to use for the return value.
And indeed it does!
Exploitation
We now just need a jmp rax gadget or equivalent. I'll use ROPgadget for this and look for either jmp rax or call rax:
There's a jmp rax at 0x40109c, so I'll use that. The padding up until RIP is 120; I assume you can calculate this yourselves by now, so I won't bother showing it.

Awesome!
Last updated
Was this helpful?