No cON Name CTF Quals 2014 - MISCall (100pts) writeup

The challenge description was: No hints :( Just go and get the flag.

mrt:~/ctf/MISCall$ file miscall
miscall: POSIX tar archive (GNU)

So the downloaded file is a tar archive and after decompressing it we had the following files:

mrt:~/ctf/MISCall/misc/ctf$ ls
total 16
drwxr-xr-x 3 mrt mrt 4096 Jul 24 17:45 .
drwxr-xr-x 3 mrt mrt 4096 Sep 19 15:27 ..
-rw-r--r-- 1 mrt mrt 37 Jul 24 17:45 flag.txt
drwxr-xr-x 8 mrt mrt 4096 Jul 24 17:45 .git

Sounds too good to be true..

mrt:~/ctf/MISCall/misc/ctf$ cat flag.txt
Nothing to see here, moving along...

Yeah.. so obviously we will have to dig inside the .git folder to find out what happened to the flag.

mrt:~/ctf/MISCall/misc/ctf$ cd .git

mrt:~/ctf/MISCall/misc/ctf/.git$ ls
total 56
drwxr-xr-x 8 mrt mrt 4096 Jul 24 17:45 .
drwxr-xr-x 3 mrt mrt 4096 Jul 24 17:45 ..
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:14 branches
-rw-r--r-- 1 mrt mrt 15 Jul 24 15:16 COMMIT_EDITMSG
-rw-r--r-- 1 mrt mrt 159 Jul 24 15:16 config
-rw-r--r-- 1 mrt mrt 73 Jul 24 15:14 description
-rw-r--r-- 1 mrt mrt 23 Jul 24 15:14 HEAD
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:14 hooks
-rw-r--r-- 1 mrt mrt 137 Jul 24 17:45 index
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:14 info
drwxr-xr-x 3 mrt mrt 4096 Jul 24 15:16 logs
drwxr-xr-x 20 mrt mrt 4096 Jul 24 17:45 objects
-rw-r--r-- 1 mrt mrt 41 Jul 24 15:17 ORIG_HEAD
drwxr-xr-x 4 mrt mrt 4096 Jul 24 17:45 refs

If you want to know what each of these files/folders do you can visit this link: GIT Tutorial: Directory Structure

The objects folder is interesting because it stores commits allowing us to find earlier versions of objects. We are looking for a flag, let's see if there is an earlier version of flag.txt

To view the content of an object you can use the git cat-file command with the -p parameter for pretty print as the following:

git cat-file -p [folder-name][object-name]

Let's list the content of the objects folder and start digging into the history of these files.

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ ls
total 80
drwxr-xr-x 20 mrt mrt 4096 Jul 24 17:45 .
drwxr-xr-x 8 mrt mrt 4096 Jul 24 17:45 ..
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:21 00
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:17 1b
drwxr-xr-x 2 mrt mrt 4096 Jul 24 17:45 1f
drwxr-xr-x 2 mrt mrt 4096 Jul 24 17:45 26
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:16 2c
drwxr-xr-x 2 mrt mrt 4096 Jul 24 17:45 31
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:17 40
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:21 42
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:17 6a
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:21 6d
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:17 7a
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:20 84
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:16 be
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:16 cf
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:17 ef
drwxr-xr-x 2 mrt mrt 4096 Jul 24 17:45 f4
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:14 info
drwxr-xr-x 2 mrt mrt 4096 Jul 24 15:14 pack

To search into all these folders easily I made a simple one liner bash script which will run the git cat-file command automatically and see if flag.txt is in there:

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ for d in *; do for f in $d/*; do git cat-file -p $d$(basename "$f"); done; done | grep flag.txt

For each directory (variable $d) and for each files in that directory (variable $f) I run the git cat file command and see the content and pipe the result to grep trying to find a match for flag.txt. Here is the output:

100644 blob 8453c323f4f79ea037961d5d68c38d1beecf786e    flag.txt
with open("flag.txt", "rb") as fd:
100644 blob 1b7848d1971e508fa2250a114bae2dcb6f504ced flag.txt
100644 blob 8453c323f4f79ea037961d5d68c38d1beecf786e flag.txt
100644 blob 2c3a41560e7cdbb75d94b5c39665642b2e038338 flag.txt
with open("flag.txt", "rb") as fd:
fatal: Not a valid object name info
fatal: Not a valid object name pack

We do have a couple results, and we have something looking like a python script using the file flag.txt. Let's run the same command but instead of piping the result to grep let's pipe to less and manually check what is going on:

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ for d in *; do for f in $d/*; do git cat-file -p $d$(basename "$f"); done; done | less
parent 42315b094279665ca93b51e3d305a22d89c81e73
author Linus Torvalds <torvalds@klaava.Helsinki.Fi> 1406229666 +0200
committer Linus Torvalds <torvalds@klaava.Helsinki.Fi> 1406229666 +0200

WIP on master: bea99b9 Initial commit
I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu) for 386(486) AT clones.
tree 268b590ea5ed43bba780555299b3e8aef4eed7c4
parent bea99b953bef6cc2f98ab59b10822bc42afe5abc
parent f4058e28e544888eaf18cce48a3ca2ec4ecf9555
author Linus Torvalds <torvalds@klaava.Helsinki.Fi> 1406238314 +0200
committer Linus Torvalds <torvalds@klaava.Helsinki.Fi> 1406238314 +0200

WIP on master: bea99b9 Initial commit
100644 blob 8453c323f4f79ea037961d5d68c38d1beecf786e flag.txt
100755 blob 3162f4bdb488ca067f6833a2b421a76599d0f5e5 s.py
Nothing to see here, moving along...
#!/usr/bin/env python
from hashlib import sha1
with open("flag.txt", "rb") as fd:
print "NCN" + sha1(fd.read()).hexdigest()

...

I will ignore the rest of the output since we found what we were looking for, flag.txt and s.py. What is going on here is the python script s.py is reading flag.txt and output the result as a SHA1 hash and prepend NCN in front of it. Let's output the content of 8453c323f4f79ea037961d5d68c38d1beecf786e into flag.txt and the content of 3162f4bdb488ca067f6833a2b421a76599d0f5e5 to s.py and run the python script:

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ git cat-file -p 8453c323f4f79ea037961d5d68c38d1beecf786e > flag.txt

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ git cat-file -p 3162f4bdb488ca067f6833a2b421a76599d0f5e5 > s.py

mrt:~/ctf/MISCall/misc/ctf/.git/objects$ python s.py

NCN4dd992213ae6b76f27d7340f0dde1222888df4d3

We got our flag:

NCN4dd992213ae6b76f27d7340f0dde1222888df4d3

The original content of flag.txt is a famous email from Linus Torvalds about minix:

From: mailto: torvalds@klaava.Helsinki.Fi (Linus Benedict Torvalds)
To: Newsgroups: comp.os.inix
Subject: What would you like to see most in minix?
Summary: small poll for my new operating system
Message-ID:

Hello everybody out there using minix — I’m doing a (free) operating
system (just a hobby, won’t be big and professional like gnu) for 386
(486) AT clones. This has been brewing since april, and is starting to
get ready. I’d like any feedback on things people like/dislike in
minix, as my OS resembles it somewhat (same physical layout of the
file-system (due to practical reasons) among other things).

I’ve currently ported bash (1.08) and gcc (1.40), and things seem to
work. This implies that I’ll get something practical within a few
months, and I’d like to know what features most people would want. Any
suggestions are welcome, but I won’t promise I’ll implement them :-).

Linus (mailto: torvalds@klaava.helsinki.fi)

PS. Yes — it’s free of any minix code, and it has a multi-threaded fs.
It is NOT protable (uses 386 task switching etc), and it probably
never will support anything other than AT-harddisks, as that’s all I
have :-(.