Dear QA TryHackMe Walkthrough
Hello guys back again with another walkthrough this time we are going to be tackling the room Dear QA from TryHackMe. I liked the room a lot since it teaches the basics of buffer overflow. If you are a beginner and interested in learning buffer overflow i recommend the room without a doubt. The room provides you an ELF binary that is 64 bit and asks you to analyze. Good thing the binary is not stripped making it so easy to analyze. We are going to using two tools for analyzing the binary namely gdb for dynamic analysis (Finding the offsets and memory addresses) and ghidra for static code analysis (source code analysis). We are also going to be coding an exploit script using python with the library pwntools. Without much say let’s jump in.
As always we start off with a nmap scan of the box to find which ports are open. This are the port we are going to be focusing on when looking for exploits on the machine. Looking at the result we have four ports that are open namely SSH, RPC and two other ports that are known.
SSH first of all reveals that the server is running Debian as the operating system. This may come in handy when we are performing some kind of binary exploitation since we want to mimic the target as close as possible to avoid errors in our exploit.
Next i tried enumerating RPC but never got anywhere. Looking at the nmap we can see that we get similar content on port 5700 as what we get when we execute the binary. This means that the binary is running on port 5700. This information has also been given on tryhackme’s website
Next i decided next to focus on the binary given to analyze
I downloaded the binary to my box and renamed to dear_qa. Before even performing any analysis, i ran file command against the binary just to get a feel of exactly what kind of binary it is.
And looking at the result we see that it’s a 64 bit binary that’s not stripped meaning it still has symbols
It’s also dynamically linked meaning the binary rely on shared-libraries for parts of it’s functionality. This allows processes to share code and eliminates the need to store shared library code in every executable.
Next i ran strings on the binary to see if there was any sensitive information leaked by the binary like credentials. Most often you’ll find that developers hardcode secrets and credentials on binaries
Looking at the screenshot above i did not find anything that interesting but There was mention of /bin/bash making me believe that the binary might be calling system at some point. Opening up the binary with ghidra we get a standard source code and memory addresses
The function local_28 looks vulnerable to a buffer overflow. But the main function of the program seems useless. It just takes input of a user and prints it out to the screen
But taking a look at the binary again we can see that there’s another function called vuln that executes bash whenever called
But since the function has not been called in main we theoretically shouldn’t be able to execute it. It’s just ‘dead’ code sitting in the binary that’s useless unless we find some way of calling it.
Looking at the screenshot above we can see that i executed the binary and the system call wasn’t executed at any point in the binary since it’s not called . Earlier we had said that the binary is vulnerable to a buffer overflow. Buffer overflow vulnerability occurs when you give a program too much data. The excess data corrupts nearby space in memory and may alter other data. We are going to take advantage of this vulnerability and jump to the vuln function and thus getting system access to the server.
But first we need to find the exact protections the binary has. The protections makes it harder for these kind of vulnerability to be exploited . It’s a way in which systems are hardened these days. I’ll use GDB to find the exact protections that are in place
We can see that all security protections have been turned off making exploiting the buffer overflow even easier. Next we need to find the exact offsets where we begin to overflow the binary.
First i created a string which had 50 characters using the pattern create command
Next i copied the string and ran the binary and pasted the string as a name. The reason why i used pattern create was because it creates a cyclic redundant pattern which is never repeating this will help us find the exact place where the binary crashed
We can see that the binary seg faulted. But let’s examine the memory addresses
From the screenshot above we can see that the binary crashed after 40 characters of input. This is because the RSP didn’t have a valid memory address to jump to. But we can control the RSP to show this. I’ll run the binary again and replace RSP with all B’s
Looking at the screenshot above we notice that the RSP variable has been replaced by B’s. If we put a valid address on RSP we will cause the program to continue through execution of the program. The function that we intend to jump to is the vuln function
Looking at the security protections that the binary had we noticed that ASLR was disabled(PIE) meaning the binary will contain the same exact memory addresses every time the binary starts
My goal now is after overflowing the binary i just jump to the vuln function which has a memory address of 0x00400686
After knowing this i started creating my exploit using python
First i started by defining the host and port as variable in the python script
Next i initialed the environment that pwntools will be using
After this i connected to the binary using the remote command
After this i added some explanation to make the script looks much more appealing. It just prints information to screen about whats happening
Next i crafted my payload which included the 40 A’s which acted as junk and followed by the memory address i wanted to jump to
Remember that after the 40 A’s we start overwriting the RSP which controls where the program jumps to in our case is the memory address of the vuln function
Next i sent the payload through the socket that had been opened by pwntools and used interactive to always keep the socket open after the data has been sent
N/B: Everything must be in byte format since that’s how python3 likes it. I saved the script and executed it on the command line
And looking at the screenshot below it seems like we get a shell on the system
That’s cool i tried executing commands but i never got an output
To confirm if i had actually got a shell i tried pinging myself from the target server and as you can see in the screenshot below i got call back from the server
Meaning our exploit was successful. Next i just tried getting a reverse shell from the box
And it worked i had a shell from the box. And with the shell i got the flag
Below is the snippet of the code we just created and used to exploit the server
#!/usr/bin/env pyhon3from pwn import *
import sysif len(sys.argv) != 2:
print("[~] Usage: python3 exploit.py <HOST>")
sys.exit(1)host = sys.argv
port = 5700context(terminal = ['tmux', 'new-window'])
#make sure you put the correct binary name and path below
binary = context.binary = ELF("./DearQA.DearQA")
context(os = "linux", arch = "amd64")connect = remote(host, port)
log.info("[+] Starting buffer Overflow")
connect.recvuntil(b"What's your name: ")
log.info("[+] Crafting payload")payload = b'A' * 40
payload += p64(0x00400686)
log.info("[+] Sending Payload to the remote server")
And the box is pretty much done. I hope you enjoyed the walkthrough if so don’t forget to clap for me down below and follow miss so that you won’t miss any upcoming walkthrough.