Switch branches/tags
Nothing to show
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Square CTF 2017



Category: Points: Writeup Author
Exploit 1000 merrychap


Our operatives found this site, which appears to control some of the androids’ infrastructure! There are only two problems. The robots love x86 assembly; the only thing easier for them to work with is binary. And they love terse command codes. Even 7 bytes was too many for this one. This URL is unique to your team! Don't share it with competitors! https://zahir-todyf-movav-fygas-codag.capturethesquare.com


On the page we can find a binary and text, that says:

You can send up to 6 bytes (hex encoded) as the first argument to the binary. The passed in bytes will be executed. The goal is to read the contents of the file in env['WUNTEE_CHALLENGE_FLAG'].

Okay then, the first we have to do is to download the binary and examine its functionality. Using file utility we see that it's 32-bit binary:

Let's open the binary in IDA Pro. First of all, we're faced with argc length checking. From this, we know, that length of argc must be 2.

It means that we pass our 6 bytes through command line parameters. If args is equal to 2, then binary checks length of a passed string. It must be 12 bytes long because each byte presented with 2 symbols

When all checks are completed, the program converts a passed string into 6 real bytes. That is, if you input aabbccddeeff, then program converts it into bytes sequence 0xaa 0xbb 0xcc 0xdd 0xee 0xff. After this, the main function starts:

In this part of the code, the program prints locations of the flag and the shellcode (our input), and then jumps to the shellcode. Sounds pretty nice. We can run the debugger and see all this in action.

I'll use gdb+peda, but you can use whatever debugger you want. Let's set the breakpoint on jmp DWORD PTR [ebp-0x18], because in fact, it's the only one interesting place to debug.

When we try to run the binary, we faced with the problem: we just don't have WUNTEE_CHALLENGE_FLAG environment variable. It's not a problem at all. We create a file named "flag" and write to it the string this_is_sample_flag_created_by_myself. After this let's create the right environment variable:

Try to run it again with aabbccddeeff... Yes, everything is okay.

Once you are at the jmp instruction, step in and see what do we have there.

This is where the real task begins. Let's recall that we have right now. The flag is located in our memory and we can see it. Also, we can control 6 executable bytes. So, the simplest (and the only one) idea is next: we use write syscall to write the flag into the output stream.

Let's examine the registers for that: eax = 0x4; ebx = 0x1; edx = 0x5. It means that we will write to the stdout 5 bytes of a buffer stored in the ecx. But ecx stores something useless! Yes, this is why we need this 6 bytes of our input. You can notice that edi contains flag address, so the goal is to move this address to ecx. We can input lea ecx, [edi]; syscall; (in bytes it's 8d0fcd80)assembly instruction to output first 5 bytes of the flag.

Okay, when we get the first 5 bytes of the flag, we can use an offset in the lea instruction like this: lea ecx, [edi+5] to print next 5 bytes and so on. By the way, you can use rasm2 to convert assembly instructions into bytes.

That's all. Just apply this technique on the CTF server.

For our team flag is: