Hackover CTF 2015 – easy-math

This writeup describes the solution for the easy-math challenge in Hackover CTF 2015 held by Chaos Computer Club Hamburg.

The task describes some basic arithmetics to warm up:

Hackover CTF 2015 - easy-math - task description

This file was published: easy-math.tar.gz. It is a 32bit ELF executable. Running the file shows this output:

ruport@zentaur:~/hackover2015$ ./easy_math
Warmup: sh0w m3 h0w 1337 y0u 4r3> rup0rt

It reads some data and does stuff with it. I gonna try GDB to have a detailed look in the operations.
So lets set a breakpoint after the read() functions and single step (si).

(gdb) b *0x0804855d
Breakpoint 1 at 0x804855d
(gdb) display /i $eip
(gdb) run
Starting program: /home/ruport/hackover2015/easy_math 
Warmup: sh0w m3 h0w 1337 y0u 4r3> AAAABBBBCCCC

(gdb) CC
Undefined command: "CC". Try "help".
1: x/i $eip
=> 0x804855d <main+153>:	add    esp,0x10

We already recognize that the binary only takes 10 bytes of input because, 2 bytes of our input (CC) is already passed back to GDB. Then the program does some compares. One of them is very interesting because it checks our input data:

0x0804858b in main ()
1: x/i $eip
=> 0x804858b <main+199>:	cmp    eax,DWORD PTR [ebp-0x10]
(gdb) i r eax
eax            0xe8ab4dca	-391426614
(gdb) x/1x $ebp-0x10
0xffffd3e8:	0x42424141

Okay, so file checks our first part of input data (AABB) for 0xe8ab4dca. Lets fake this step as if our input data was correct and see what happens next:

(gdb) p/x $ebp-0x10
$1 = 0xffffd3e8
(gdb) set *((int*)0xffffd3e8)=0xe8ab4dca
(gdb) si
0x0804858e in main ()
1: x/i $eip
=> 0x804858e <main+202>:	je     0x8048597 <main+211>
(gdb) 
0x08048597 in main ()
1: x/i $eip
=> 0x8048597 <main+211>:	cmp    DWORD PTR [ebp-0xc],0x1337b00b
(gdb) x/1x $ebp-0xc
0xffffd3ec:	0x43434242

Ah, the second part of our input data (BBCC) is checked for 0x1337b00b. Lets fake this part too.

(gdb) p/x $ebp-0xc
$2 = 0xffffd3ec
(gdb) set *((int*)0xffffd3ec)=0x1337b00b
(gdb) si
0x0804859e in main ()
1: x/i $eip
=> 0x804859e <main+218>:	jne    0x80485ac <main+232>
(gdb) 
0x080485a0 in main ()
1: x/i $eip
=> 0x80485a0 <main+220>:	call   0x80484ab <shell>
(gdb) c
Continuing.
$ 

After this check the “shell” function is called an we get a shell. So all we have to do is to submit 2 bytes of trash data, 0xe8ab4dca and 0x1337b00b to the server. Because this contains binary data, I wrote a python script:

#!/usr/bin/env python

import socket
import sys
import struct
import time

trash = "XX"
cmp1 = 0xe8ab4dca
cmp2 = 0x1337b00b

server = ("easymath.hackover.h4q.it", 1337)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(server)

data = sock.recv(2048)
print data

c1 = struct.pack("<I", cmp1)
c2 = struct.pack("<I", cmp2)

sock.send(trash + c1 + c2)

while True:
  input = raw_input("CMD> ")
  sock.sendall(input + "\n")

  data = sock.recv(2048)
  print data

sock.close()

When executing this script, we get a shell on the hackover CTF 2015 server:

Warmup: sh0w m3 h0w 1337 y0u 4r3>
CMD> ls
easy_math
easy_math.start

CMD> ls /home
ctf

CMD> cd /home/ctf

CMD> ls
flag.txt

CMD> cat flag.txt
hackover15{YaY_SiMpLe_diSasM_aNd_mAtH_iS_sImpLe}

The solution is “hackover15{YaY_SiMpLe_diSasM_aNd_mAtH_iS_sImpLe}“.

Leave a Reply

Your email address will not be published. Required fields are marked *