picoCTF2019 Reverse Engineering Asm

Hello, here’s my take on the picoCTF2019 reverse engineering asm challenges. If you don’t know assembly, please watch a few tutorials on it:

asm1 – Points: 200

CMP: Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register according to the results. The comparison is performed by subtracting the second operand from the first operand and then setting the status flags in the same manner as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to the length of the first operand.

JG: Jump short if greater (ZF=0 and SF=OF)

JNE: Jump short if not equal (ZF=0)

	<+0>:	push   ebp # 
	<+1>:	mov    ebp,esp # 
	<+3>:	cmp    DWORD PTR [ebp+0x8],0x37a # 0x345 - 0x37a = -0x35

	<+10>:	jg     0x512 <asm1+37> # -0x35 is greater than 0x512 because it overflowed.
	<+12>:	cmp    DWORD PTR [ebp+0x8],0x345
	<+19>:	jne    0x50a <asm1+29>
	<+21>:	mov    eax,DWORD PTR [ebp+0x8]
	<+24>:	add    eax,0x3
	<+27>:	jmp    0x529 <asm1+60>
	<+29>:	mov    eax,DWORD PTR [ebp+0x8]
	<+32>:	sub    eax,0x3
	<+35>:	jmp    0x529 <asm1+60>

	<+37>:	cmp    DWORD PTR [ebp+0x8],0x5ff # 0x345 - 0x5ff = -0x2BA
	<+44>:	jne    0x523 <asm1+54> # -0x2BA is not equal to 0x523
	<+46>:	mov    eax,DWORD PTR [ebp+0x8]
	<+49>:	sub    eax,0x3
	<+52>:	jmp    0x529 <asm1+60>
	<+54>:	mov    eax,DWORD PTR [ebp+0x8] # eax = 0x348
	<+57>:	add    eax,0x3 # eax = eax + 3
	<+60>:	pop    ebp 
	<+61>:	ret    # return eax

Next Levels

The next levels asm2, asm3 and asm4 got a little more complex and solving them was starting to feel like a chore, my mind was hurting and I didn’t want to keep going the manual way. Lucky, I found noahc3 and this writeup I managed to solve them easily.

We’re going to modify the assembly and compile it with GCC, on my 64 bit Ubuntu I had to install the gcc-multilib package in order to compile 32 bit executables.

Here’s the modified code for the asm3 task:

.intel_syntax noprefix

.global asm3

	push   ebp
	mov    ebp,esp
	xor    eax,eax
	mov    ah,BYTE PTR [ebp+0x8]
	shl    ax,0x10
	sub    al,BYTE PTR [ebp+0xe]
	add    ah,BYTE PTR [ebp+0xc]
	xor    ax,WORD PTR [ebp+0x10]
	pop    ebp

What we’re going to do next is to write a simple main.c program that calls the functions with the required arguments:

#include <stdio.h>

int main(void) {
    printf("Hello World!");
    // printf("Flag: %un", asm2(0xe,0x22));
    printf("Flag: %un", asm3(0xcdc485c1,0xd6bd5e88,0xe4c1548d));
    // printf("Flag: %un", asm4("picoCTF_fdb55"));

Next we’re going to compile the assembly code, the main.c file and the final executable:

 gcc -m32 -c asm3.S -o asm3.o -fno-stack-protector -no-pie
 gcc -m32 -c main.c -o main.o -fno-stack-protector -no-pie
 gcc -m32 -o a.out main.o asm3.o -fno-stack-protector -no-pie

If we execute a.out we should get our flag.

Thanks for reading!

PicoCTF 2019: whats-the-difference (Points 200)

Can you spot the difference? kitters cattos. They are also available at /problems/whats-the-difference… on the shell server

In order to easily solve this challenge, I’ve used xxd and cut to generate an ascii hexdump of the images:

➜  Downloads xxd kitters.jpg | cut -d ' ' -f 11 > kittens_text.txt

➜  Downloads xxd cattos.jpg  | cut -d ' ' -f 11 > cattos_text.txt

Since I wanted to do a per character diff I wrote the following Python script:

def main():
    new = open("cattos_text.txt")
    old = open("kittens_text.txt")
    old_file = old.readlines()
    new_file = new.readlines()
    print("Loaded lines", len(old_file), len(new_file))
    for line in zip(old_file, new_file):
        for number, old_char  in enumerate(line[0]):
            if old_char != line[1][number]:
                print(line[1][number], end="")


And finally run the script:

➜  Downloads python diff.py
Loaded lines 212919 212919

X-MAS CTF 2019: Binary Exploiting & Reversing Write-Ups


Here are my write-ups for the X-MAS CTF 2019 organized by https://htsp.ro/.

Reversing: Santa’s crackme

Santa’s crackme is easy to solve when using Ghidra, all you need to do is open up the binary, read the code and use the XOR Memory script from Ghidra.

The flag is retrieved from flag_matrix and xored by 3.
Select the flag data, right click on Script Manager and execute the XorMemory script
We get the flag, except for the first character

Reversing: X-MAS: Lapland Mission

Since this is an Unity game we can easily patch it using dnSpy.

Open X-MAS Lapland MissionX-MAS_DataManagedAssembly-CSharp.dll and navigate to PlayerControl class and replace the Die() method with a simple return by clicking edit method and compile.

Play the game, kill all robots and get the flag.

Exploitation: SN0WVERFL0W

To get the flag we need to override the return address of the main function during the buffer overflow.

The buffer size is 10 bytes, the frame address is 8 bytes and the return address is also 8 bytes. We can use Python to create a file with the input we need to pass to the binary:

python -c "print('a'*10+'a'*8+'x56x11x40x00x00x00x00x00')" > in.txt

I’ve overridden the return address of main with the return address of the function which prints the flag, you can find that address by inspecting the binary in Ghidra.