Saturday, March 26, 2022

Two Modest Writeups from Insomni'Hack 2022 CTF

This year the Insomni'Hack security conference took place again after the last two editions were cancelled due to Covid-19. It was great to see everyone IRL again, and indeed the place was crowded. After two days of conferences the legendary capture the flag (CTF) hacking competition took place on Friday night. A couple of colleagues from Compass Security and Swisscom teamed up to solve the challenges. My personal CTF experience is very limited, for that reason I was very happy to be able to solve two beginners' challenges on my own. Let's dig in.

Wordle

This challenge is themed on the web-based word game which gained enormous popularity in 2022. In order to solve the challenge, you need to analyze a Linux binary to which you must provide a specific input – a typical crackme. Here's what happens when executed several times:


As in the original game, one needs to guess a five letter word. Interestingly, one of the solutions is /bin/sh. I used the Ghidra open source reverse engineering tool to understand what's going on behind the scenes. Let's first have a look at strings in the binary. The .rodata memory segment contains the string constants that we can recognize from the program output:

Using Ghidra's decompiler view, we can identify the logic when processing user input:

On line 15, a string provided by the user is read from standard input (stdio) using the insecure gets() function. It will get stored in the .bss memory segment at address 0x003020c0. Next on line 16, memory contents located 32 byte further in memory at address 0x003020e0 are compared with the specific dword value 0xdeadbeef. Using a five character string as input, program execution will take the else-branch at line 21 which results in the output seen above: "Nice try but the word was XXXXX". There we see the use of an array PTR_s_PWNED_00302020 which is used to refer to the list of wordle strings. The value of index iVar2 originates from FUN_00100bad() in line 10, which is most probably a random number generator.

We need to provide a longer input in order to take the if-branch in line 17. Specifically, 32 arbitrary bytes (padding) and then the magic 0xdeadbeef value. We see the same array access providing a random wordle string, which is used as argument to system(). This means, we need to execute the program repeatedly, until the "/bin/sh" string is returned, effectively providing a shell on the target system. Here's my python solution using pwntools:



Gothard

The next challenge is a network forensic challenge. A pcap file is provided containing the captured network traffic from a compromised system. Not sure if the typo was intended, but if referring to the Swiss mountain an association to the tunnel & network tunneling can be made.

When opening the file with Wireshark, we see traffic between two hosts. All packets are of type ICMP type 8 & 0 – echo (ping) request & reply respectively. The outbound ping packets are unusually big. We also see embedded HTTP traffic in the hexdump. Obviously data is being exfiltrated using the arbitrary ping payload bytes. As a guess, I thought this could relate to ping tunneling. A Google search returns the ptunnel utility as a first result. ptunnel uses a simple protocol to encapsulate network traffic, as can be seen on their website:

So obviously we need to parse the header, ignore the retransmitted packets and concatenate the payloads of the remaining packets to reassemble the exfiltrated data. I used python and the pyshark wrapper for tshark:

This resulted in a tar.gz archive and the flag was stored inside of file home/inso/Documents/Audit/Client_Y/0.null/Conf_SCRT_findings.jpg:





1 comment: