PicoCTF 2014 Write-ups

Injection 1 - 90 (Web Exploitation)

Writeup by patil215

Created: 2014-11-07 18:38:50

Last modified: 2014-11-09 23:32:37


Daedalus Corp. has been working on their login service, using a brand new SQL database to store all of the access credentials. Can you figure out how to login?


What happens if username or password contains a single quote (')?



Format a SQL injection that terminates the query statement early, causing the server not to check the password and only the admin username we provide.


SQL is a programming language designed for manipulating databases. A SQL Injection attack consists of sending a SQL query to a server so that it gives you data back. You can read more about SQL injections here

How do we send a SQL query?

At the bottom of the page is the source. Reading through it, you'll see that line 7 contains a $query that takes in what is typed in the username and password box and uses it to find a user in the database that matches. The creators of the website naively assumed that you would be typing normal inputs for the username and password. However, what you can do is instead submit usernames and passwords that modify the SQL query - a SQL injection! This is because they don't 'escape' their input (meaning they don't filter it so that it doesn't run as code).

First let's turn on debug mode so we can see our queries. Go into the inspector console in Chrome (right click -> Inspect Element), then find the line saying

<input type="hidden" name="debug" value="0">

and set the value to 1. Now, when we send our queries we'll be able to see what they were and if they failed.

Now let's work on this injection. The line we want to exploit is the SQL query:

$query = "SELECT * FROM users WHERE username='$username' AND password='$password'";

The server checks if that query returns exactly one user and then returns the flag if it does:

if (mysqli_num_rows($result) !== 1) {
  echo "<h1>Login failed.</h1>";
} else {
  echo "<h1>Logged in!</h1>";
  echo "<p>Your flag is: $FLAG</p>";

What we want to do is make it so that our query is guaranteed to return a user. However, we don't know the password - so what we need to do it make sure the query doesn't check for the password, eliminating the AND password='$password'" part.

Since it's a string, we can close it with ' (hence the hint). This will let us supply our own username and terminate the string. But what we really want to do is terminate the string early so that the password is never checked. In SQL, -- is a comment (make sure you have the space afterwards), meaning it invalidates the rest of the line. What this means is that if we type it in the username box we can make the query only check the username!

So let's write our exploit:

admin' --

That's it! The ' closes the string for our username, and -- makes the SQL query end early, so it doesn't check for our password. admin is there because the server checks if there's exactly 1 username that matches the query. We guess that admin is a likely username, and sure enough it is. Typing the above exploit into the username box and anything for the password (it doesn't matter because it doesn't check the password anyways) gives us our flag.