在SQL注入中利用MySQL隱形的類型轉換繞過WAF檢測
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>
- <form id="form1" name="form1" method="post" action="login.php">
- <label>UserName
- <input name="user" type="text" id="user"/>
- </label>
- <br/>
- <label>Password
- <input name="password" type="text" id="password"/>
- </label>
- <br/>
- <label>
- <input name="login" type="submit" id="login" value="Login"/>
- </label>
- </body>
- </html>
(2)認證處理login.php
- <?php
- if(isset($_POST["login"]))
- {
- $link = mysql_connect("localhost","root","toor") or die ("cannot connect database".mysql_error());
- mysql_select_db("member") or die ("cannot select the db");
- $query = "select * from user where user='".$_POST["user"]."'and password='".md5($_POST["password"])."'";
- echo $query."<br/>";
- $result = mysql_query($query) or die ("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 對應的數值為0
123dani,123tanjiti對應的數值為123
45dani,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注入的檢測是蠻有想法的。