Solving TryHackMe’s Malware and Reverse Engineering Challenges — Dear QA

Jafar Pathan
5 min readMar 29, 2024

--

Hey there, let’s continue with our series to solve the TryHackMe’s Reverse Engineering and Malware Analysis Challenges.

Let’s download the file and jump straight to the analysis.

︻デ═一××> file DearQA-1627223337406.DearQA                                                                                                                                          15:31:33
DearQA-1627223337406.DearQA: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8dae71dcf7b3fe612fe9f7a4d0fa068ff3fc93bd, not stripped

After analyzing the challenge binary with ‘file’ command, it is clear that this is linux executable. Using above output we can answer the Question 1 of Task 2 ‘What is the binary architecture?`. Let’s import this file into ghidra for further analysis.

As soon as I imported the file in ghidra and opened it in Code Browser, I noticed the main() and vuln() functions. Let’s analyze the main() function.

And here it is The BufferOverflow, the __isoc99_scanf(&DAT_00400851,local_28) function reads the input from STDIN and stores it in string format in ‘local_28’. Here the ‘DAT_00400851’ is ‘%s’ which can be found in assembly as shown below.

Now, the issue here is, the scanf() function will read the input until it receives ‘\n’ new line character or EOF (End Of File) character. This allows us (the user) to insert large amount of input causing the various CPU registers’ values to be overwritten resulting in segmentation fault. To read more this, refer this.

This is the analysis of main() function. Let’s analyze the second function vuln().

This function prints some messages on console and then executes /bin/bash . This is clear indication that we need to call this function by causing buffer overflow and write address of ‘vuln()’ function to EIP to make call this to function.

Let us run the binary to see what happens when we give normal input and large amount of input.

When given normal input like ‘zinjacoder’ the program prints “Hello: zinjacoder” and exists. Now let’s give it large amount of data like 100 characters long.

Here I am using ‘cyclic’ utility from pwntools to generate random string. When given large amount of data, as expected the program crashes with (Address boundary error).

Now let’s find the exact number of bytes after which the program crashes. Load the program in GDB.

Start the program using r and press enter as shown below.

Paste our previous payload which 100 bytes long.

After getting the segmentation fault, get the value RSP register which is stack pointer to get the number of bytes after which the value is written on EIP register. Use x $rsp to get the value of RSP.

RSP holds address 0x7fffffffe468 which holds the values 0x6161616b. Let’s find this value in our payload using cyclic as shown below.

Hence we get the number of bytes after which the content EIP register is overwritten.

So we will supply random 40 bytes then the address of ‘vuln()’ function so the address of ‘vuln()’ function is written over EIP which will then call this function.

The address of the ‘vuln()’ can be found using ghidra as shown below —

The address of the vuln() function is ‘00400686’. Now let’s write some code in python to send the (random 40 bytes) + ‘00400686’.

from pwn import *

target = process("/home/zinjacoder/Downloads/DearQA-1627223337406.DearQA")
target.recvuntil(b"What's your name: ")

payload = cyclic(40)
payload += p64(0x00400686)

target.sendline(payload)
target.interactive()

Here, in above script we start the binary then for binary to print the “What’s you name: “ then we generate random 40 bytes and append the address of the ‘vuln()’ function. Now let’s run the script.

And we successfully exploited the buffer overflow attack on local machine. Now we will do the same for remote machine. We have to tweak our script little bit to attack the remote process running on port 5700.

Here I have replaced target = process() with target = remote() and provide remote host’s IP and process’s port.

Now this will target the remote process as shown below —

We got the shell but it not giving back any input, to solve this issue, try to start the terminal in raw mode using — stty raw

After that we can get the flag as follows —

Thanks for reading, Next I will continue with more Malware and Reverse Engineering Challenges from TryHackMe. If you found any mistake or have any suggestion, please reach out to me —

Found above post informative? Learned something new? Why not support me. Kindly support my work via ko-fi -> https://ko-fi.com/zinjacoder

https://ko-fi.com/zinjacoder

LinkedIn

X (formally Twitter)

GitHub

Discord

TryHackMe

JafarPathan

--

--

Jafar Pathan

Working Professional in field of Cyber Security who is Stuck in the loop of - 'Hack->Code->Secure->Repeat' Support my content at -> https://ko-fi.com/zinjacoder