Skip to content

Instantly share code, notes, and snippets.

@CSRessel
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CSRessel/0631bd5e6d1e9604922d to your computer and use it in GitHub Desktop.
Save CSRessel/0631bd5e6d1e9604922d to your computer and use it in GitHub Desktop.

Injection 2

Summary

By unioning hard coded values with the prewritten select statement, we can manually control exactly what data the query returns, and thus meet the program’s requirements.

SELECT * FROM users WHERE username='asdf' UNION SELECT 1337 AS a, 1337 AS b, 1337 AS c, 1337 AS d, 1337 AS e LIMIT 1 -- '

(with “1337” entered as the password)

The Program

The source is available here. Examination of the source shows several things. First, we can make injections into the username field. Second, the returned data from the query will need to meet the following requirements to reveal the flag:

  • mysqli_num_rows($result) === 1 — only one row
  • $row["password"] === $password — row’s password must match our given password
  • $row["user_level"] >= 1337 — row’s user_level must be greater than or equal to 1337

Finally, by setting the form’s hidden field “debug” to 1, we receive a nice view of our input and the generated query.

The Injection

By taking a union with a hardcoded query, we can manually control exactly what the returned data contains, and thus meet all the prespecified requirements.

An injection of:

asdf' UNION SELECT 0 AS a LIMIT 1 -- 

Will yield the query:

SELECT * FROM users WHERE username='asdf' UNION SELECT 0 AS a LIMIT 1 -- 

Let’s break that query down: we set the username to be a value unlikely to appear in the database. We then union that SELECT statement with our own, which includes a hard coded value of 0 for the first column. Finally, we return only one of the row with LIMIT 1, to satisfy the aforementioned check for only one row. This gives us the following error:

SQL error: The used SELECT statements have a different number of columns

However, if we add some dummy columns (common sense suggest five columns: username, password, user_level, data created, date last modified), the error disappears. New query:

SELECT * FROM users WHERE username='asdf' UNION SELECT 0 AS a, 0 AS b, 0 AS c, 0 AS d, 0 AS e LIMIT 1 -- 

As we do not know which column will be the user_level, we can simply set all columns equal to 1337, and input a password of 1337 into the form.

The final query:

SELECT * FROM users WHERE username='asdf' UNION SELECT 1337 AS a, 1337 AS b, 1337 AS c, 1337 AS d, 1337 AS e LIMIT 1 -- '

This proves successful! (as the flag appears to be dynamically generated it is not included here)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment