安全測試===sqlmap(零)轉載
本文轉自:https://blog.werner.wiki/sqlmap-study-notes-0/
感謝作者的整理,如有侵權,立刪
零、前言
這篇文章是我學習Sqlmap的用法時做的筆記,記錄了Sqlmap的常見、基礎用法。 學習的主要方法是閱讀官方手冊(sqlmap/doc/README.pdf)。
一、Sqlmap是什麽
Sqlmap是開源的自動化SQL註入工具,由Python寫成,具有如下特點:
- 完全支持MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、IBM DB2、SQLite、Firebird、Sybase、SAP MaxDB、HSQLDB和Informix等多種數據庫管理系統。
- 完全支持布爾型盲註、時間型盲註、基於錯誤信息的註入、聯合查詢註入和堆查詢註入。
- 在數據庫證書、IP地址、端口和數據庫名等條件允許的情況下支持不通過SQL註入點而直接連接數據庫。
- 支持枚舉用戶、密碼、哈希、權限、角色、數據庫、數據表和列。
- 支持自動識別密碼哈希格式並通過字典破解密碼哈希。
- 支持完全地下載某個數據庫中的某個表,也可以只下載某個表中的某幾列,甚至只下載某一列中的部分數據,這完全取決於用戶的選擇。
- 支持在數據庫管理系統中搜索指定的數據庫名、表名或列名
- 當數據庫管理系統是MySQL、PostgreSQL或Microsoft SQL Server時支持下載或上傳文件。
- 當數據庫管理系統是MySQL、PostgreSQL或Microsoft SQL Server時支持執行任意命令並回現標準輸出。
二、安裝Sqlmap
Sqlmap的開源項目,托管在github,最簡單的安裝方式便是使用git,執行如下命令:
git clone https://github.com/sqlmapproject/sqlmap.git
片刻後命令執行完畢,可以看到當前目錄中多了一個名為“sqlmap”的目錄, 該目錄中保存著Sqlmap的Python源碼、配置文件和文檔。 由於Python是解釋執行的語言,不用編譯,所以至此最新版的Sqlmap已經安裝完成。 cd到“sqlmap”目錄中,用命令“python sqlmap”啟動Sqlmap,如下圖所示:
當想要更新Sqlmap時,進入到“sqlmap”目錄中執行命令“git pull”即可。
三、輸出級別(Output verbosity)
參數:-v
Sqlmap的輸出信息按從簡到繁共分為7個級別(和葫蘆娃一樣多),依次為0、1、2、3、4、5和6。使用參數“-v <級別>”來指定某個等級,如使用參數“-v 6”來指定輸出級別為6。默認輸出級別為1。各個輸出級別的描述如下:
- 0:只顯示Python的tracebacks信息、錯誤信息[ERROR]和關鍵信息[CRITICAL];
- 1:同時顯示普通信息[INFO]和警告信息[WARNING];
- 2:同時顯示調試信息[DEBUG];
- 3:同時顯示註入使用的攻擊荷載;
- 4:同時顯示HTTP請求;
- 5:同時顯示HTTP響應頭;
- 6:同時顯示HTTP響應體。
各個級別輸出的信息詳細到什麽程度,還需要自己嘗試下,親眼見到,才會有明確的認識。
四、指定目標
Sqlmap運行時必須指定至少一個目標,支持一次指定多個目標。有以下幾種指定目標的方式:
1.直接連接數據庫
參數:-d
使用參數“-d”直接連接數據庫,該參數後跟一個表示數據庫的字符串,該字符串有以下兩種格式:
(1).當數據庫管理系統是MySQL、Oracle、Microsoft SQL Server或PostgreSQL等時格式為:
DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME
(2).當數據庫管理系統是SQLite、Microsoft Access或Firebird等時格式為:
DBMS://DATABASE_FILEPATH
我用如下命令連接裝在本機上的Mysql:
python sqlmap.py -d "mysql://root:[email protected]:3306/DISSchool"
卻出現了錯誤,錯誤為:
[CRITICAL] sqlmap requires ‘python-pymysql‘ third-party library in order to directly connect to the DBMS ‘MySQL‘. You can download it from ‘https://github.com/petehunt/PyMySQL/‘. Alternative is to use a package ‘python-sqlalchemy‘ with support for dialect ‘mysql‘ installed
意思是我沒有安裝Python連接Mysql用的第三方庫python-pymysql。雖然我安裝了python-mysqldb可以使Python連接Mysql,但顯然Sqlmap使用的是python-pymysql而不是python-mysqldb。使用如下命令安裝python-pymysql:
git clone https://github.com/petehunt/PyMySQL/
cd PyMySQL/
sudo python setup.py install
安裝好python-pymysql後再執行命令:
python sqlmap.py -d "mysql://root:[email protected]:3306/DISSchool"
這次沒有報錯,成功的連接到了數據庫。只是除了檢測數據庫確實是Mysql版本號大於等於5.0.0之外便什麽都沒有做。讓Sqlmap做點什麽需要用其他參數指定,這些參數我們稍晚些再學習。
2.指定目標URL
參數:-u 或 --url
使用參數“-u”或“--url”指定一個URL作為目標,該參數後跟一個表示URL的字符串,可以是http協議也可以是https協議,還可以指定端口,如:
python sqlmap.py -u "http://192.168.56.102:8080/user.php?id=0"
3.從Burp或WebScarab的代理日誌中解析目標
參數:-l
使用參數“-l”指定一個Burp或WebScarab的代理日誌文件,Sqlmap將從日誌文件中解析出可能的攻擊目標,並逐個嘗試進行註入。該參數後跟一個表示日誌文件的路徑。
WebScarab我沒有用過,Burp倒是常常會用。Burp默認不記錄日誌,想要記錄日誌需要手動開啟,設置方法如下圖所示:
只用勾選代理中的請求數據就足夠了,日誌文件路徑可隨意設置,這裏我設置日誌文件名為proxy.log,放在用戶主目錄中。
設置瀏覽器的代理為Burp,隨便瀏覽幾個網頁後發現proxy.log竟然已經有70多K大,查看其內容,部分輸出如下:
werner@Yasser:~$ more proxy.log
======================================================
7:22:52 PM http://ocsp.digicert.com:80 [117.18.237.29]
======================================================
POST / HTTP/1.1
Host: ocsp.digicert.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-SG,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Length: 83
Content-Type: application/ocsp-request
DNT: 1
Connection: close
0Q0O0M0K0I0 +
????Pr?Tz?
======================================================
======================================================
7:23:00 PM http://blog.csdn.net:80 [47.95.49.160]
======================================================
GET /pyufftj/article/details/21469201 HTTP/1.1
Host: blog.csdn.net
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
...
可以看到該日誌文件不僅記錄了GET參數,還記錄了cookie和POST參數。現在使用如下命令讓Sqlmap解析該日誌文件,自動尋找目標,檢測註入漏洞:
python sqlmap.py -l ../proxy.log
註意日誌文件的路徑要寫正確。執行該命令時,每找到一個可能的攻擊目標,Sqlmap都會詢問是否要檢測該目標。,默認回答為“Y”,想要測試該目標,直接按回車鍵就行。
當日誌較大時會有很多可能目標,雖然有詢問機制但依舊麻煩,因為不能一路按回車而要進行判斷。若是可以對日誌進行過濾就好了!確實是可以的,參數為“--scope”,詳情見“五.18”。
4.從站點地圖文件中解析目標
參數:-x
為便於搜索引擎收錄,許多網站專門為搜索引擎生成了xml格式的站點地圖,如百度Sitemap支持xml格式。Sqlmap可以直接解析xml格式的站點地圖,從中提取攻擊目標,對一個網站全方位無死角地進行註入檢測,此時使用的參數是“-x”,如:
python sqlmap.py -x http://www.6eat.com/sitemap.xml
但執行該命令的結果卻是:
[WARNING] no usable links found (with GET parameters)
沒有找到有GET參數的可用鏈接。就我有限的經驗而言,站點地圖中的URL很少包含GET參數,POST參數就更不用說了。所以Sqlmap的這一功能似乎有些雞肋。
5.從文本文件中解析目標
參數:-m
參數“-u”一次只能指定一個URL,若有多個URL需要測試就顯得很不方便,我們可用將多個URL以一行一個的格式保存在文本文件中,然後使用參數“-m”,後跟該文本文件路徑,讓Sqlmap依次讀取文件中的URL作為攻擊目標。
如我們有文件url.txt,內容為:
www.target1.com/vuln1.php?q=foobar
www.target2.com/vuln2.asp?id=1
www.target3.com/vuln3/id/1*
然後可用使用如下命令讓Sqlmap測試這些URL是否存在註入漏洞:
python sqlmap.py -m url.txt
同樣,執行該命令時,Sqlmap會很貼心地一個個詢問:“do you want to test this URL?”
6.從文件載入HTTP請求
參數:-r
可以將一個HTTP請求保存在文件中,然後使用參數“-r”加載該文件,Sqlmap會解析該文件,從該文件分析目標並進行測試。
設有如下所示的HTTP請求保存在文件get.txt中:
GET /user.php?id=1 HTTP/1.1
Host: 192.168.56.101:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-SG,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
則使用如下命令讓Sqlmap解析該文件,以該文件中HTTP請求目標為攻擊目標進行測試:
python sqlmap.py -r get.txt
7.將Google搜索結果作為攻擊目標
參數:-g
Sqlmap能自動獲取Google搜索的前一百個結果,對其中有GET參數的URL進行註入測試。當然,所處的網絡環境要能訪問Google才行。下面是Sqlmap手冊中“-g”參數的例子:
python sqlmap.py -g "inurl:\".php?id=1\""
8.從配置文件中載入攻擊目標
參數:-c
使用參數“-c”指定一個配置文件(如:sqlmap.conf),Sqlmap會解析該配置文件,按照該配置文件的配置執行動作。配置文件中可以指定攻擊目標,實際上除了攻擊目標外,配置文件還可以指定各種參數的值。
Sqlmap的按照目錄中有一個名為sqlmap.conf的文件,該文件是配置文件的模板,看看該文件內容,就能明白配置文件是什麽意思了。
五、請求
HTTP是一個復雜的協議。HTTP請求有很多種方法(method),可以在不同位置(GET、POST、cookie和User-Agent等)攜帶不同參數。往往只有在特定位置攜帶了特定參數以特定方法發起的請求才是合法有效的請求。Sqlmap運行時除了需要指定目標,有時還需要指定HTTP請求的一些細節。下面這些參數都用於指定HTTP請求細節。
1.HTTP方法
參數:--method
一般來說,Sqlmap能自動判斷出是使用GET方法還是POST方法,但在某些情況下需要的可能是PUT等很少見的方法,此時就需要用參數“--method”來指定方法。如:“--method=PUT”。
2.POST數據
參數:--data
該參數指定的數據會被作為POST數據提交,Sqlmap也會檢測該參數指定數據是否存在註入漏洞。如:
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --data="id=0&name=werner"
3.指定分隔符
參數:--param-del
上一個例子中“--data”的數據“id=0&name=werner”其實由兩個部分組成:“id=0”和“name=werner”,默認地以“&”作為分隔符。我們可以使用“--param-del”來指定分隔符,如:
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --data="id=0;name=werner" --param-del=";"
4.cookie
參數:--cookie、--cookie-del、--drop-set-cookie和--load-cookies
有兩種情況會用到這些參數:
- 要測試的頁面只有在登錄狀態下才能訪問,登錄狀態用cookie識別
- 想要檢測是否存在cookie註入
當“--level”設置為2或更高時,Sqlmap會檢測cookie是否存在註入漏洞,關於“--level”的更多信息見下文。
(1).“--cookie”和“--cookie-del”
在瀏覽器中登錄目標網站後復制出維持登錄狀態的cookie,用參數“--cookie”來指定這些cookie,如:
python sqlmap.py -u "http://192.168.56.102:8080/user.php" --cookie "JSESSIONID=E5D6C8C81;NAME=werner;"
與POST參數不同,cookie默認的分隔符為“;”,想要指定cookie中的分隔符,使用參數“--cookie-del”。
(2).“--drop-set-cookie”
若HTTP響應頭中有“Set-Cookie”,Sqlmap會自動設置“Set-Cookie”設置的cookie,並對這些cookie進行檢測。若不想讓Sqlmap這麽做,添加參數“--drop-set-cookie”即可,這樣,Sqlmap會忽略“Set-Cookie”。
(3).“--load-cookies”
該參數用於從文件中載入Netscape或wget格式的cookie。
wget可以保存和載入cookie,示例如下:
# Log in to the server. This can be done only once.
wget --save-cookies cookies.txt --post-data ‘user=foo&password=bar‘ http://server.com/auth.php
# Now grab the page or pages we care about.
wget --load-cookies cookies.txt -p http://server.com/interesting/article.php
5.User-Agent
參數:--user-agent和--random-agent
默認情況下Sqlmap發送的HTTP請求中的User-Agent值為:
sqlmap/1.0-dev-xxxxxxx (http://sqlmap.org)
使用參數“--user-agent”可以指定一個User-Agent值。但正常的User-Agent值長什麽樣我們可能並不記得,所以有了參數“--random-agent”,使用該參數,Sqlmap會從文件./txt/user-agents.txt中隨機地取一個User-Agent。註意,在一次會話中只有使用同一個User-Agent,並不是每發一個HTTP請求包,都隨機一個User-Agent。
用如下命令統計user-agents.txt行數:
cat sqlmap/txt/user-agents.txt | wc -l
結果為4211,當然其中還包含空行、註釋等,但總的來說該文件中存儲的User-Agent也有4千多個。
當“--level”設置為3或更高時,Sqlmap會檢測User-Agent是否存在註入漏洞,關於“--level”的更多信息見下文。
6.Host
參數:--host
使用該參數可以手動指定HTTP頭中的Host值。
當“--level”設置為5或更高時,Sqlmap會檢測Host是否存在註入漏洞,關於“--level”的更多信息見下文。
7.Referer
參數:--referer
使用該參數可以指定HTTP頭中的Referer值。Sqlmap發送的HTTP請求頭部默認無Referer字段。
當“--level”設置為3或更高時,Sqlmap會檢測Referer是否存在註入漏洞,關於“--level”的更多信息見下文。
8.額外的HTTP頭
參數:--headers
使用該參數可以在Sqlmap發送的HTTP請求報文頭部添加字段,若添加多個字段,用“\n”分隔。如命令:
python sqlmap.py -u "http://192.168.56.101:8080/" -v 5 --headers "X-A:A\nX-B: B"
發送的HTTP請求包為:
GET / HTTP/1.1
X-B: B
Host: 192.168.56.101:8080
Accept-encoding: gzip,deflate
X-A: A
Accept: */*
User-agent: sqlmap/1.1.10#stable (http://sqlmap.org)
Connection: close
加參數“-v 5”是為了讓Sqlamp輸出發送的HTTP請求包,便於我們觀察。
9.身份認證
參數:--auth-type和--auth-cred
這些參數用於進行身份認證。“--auth-type”用於指定認證方式,支持以下三種身份認證方式:
- Basic
- Digest
- NTLM
“--auth-cred”用於給出身份認證的憑證,格式是“username:password”。
如:
python sqlmap.py -u "http://192.168.136.131/sqlmap/mysql/basic/get_int.php?id=1" --auth-type Basic --auth-cred "testuser:testpass"
10.基於證書的身份認證
參數:--auth-file
若Web服務器要求客戶端提供證書則可以使用此參數指定一個PEM格式的證書文件。我們知道SSL協議的客戶端認證是可選的,實踐中一般都只用服務器端提供自己的證書供客戶端驗證,很少要求客戶端提供自己的證書。
11.忽略401
參數:--ignore-401
使用該參數忽略401錯誤(未認證)。
12.HTTP(S)代理
參數:--proxy、--proxy-cred、--proxy-file和--ignore-proxy
使用參數“--proxy”來設置一個HTTP(S)代理,格式是“http(s)://url:port”。若代理需要認證,使用參數“--proxy-cred”來提供認證憑證,格式是“username:password”。
使用參數“--proxy-file”指定一個存儲著代理列表的文件,Sqlmap會依次使用文件中的代理,當某個代理有任何連接問題時就會被棄用而換下一個代理。
使用參數“--ignore-proxy”忽略本地代理設置。
13.Tor匿名網絡
參數:--tor、--tor-type、--tor-port和--check-tor
不管出於什麽原因,如果想要保持匿名狀態與其使用單個的HTTP(S)代理,不如安裝類似Privoxy這樣的軟件按照Tor的安裝指導配置一個Tor客戶端。設置好後使用參數“--tor”讓Sqlmap自動設置使用Tor代理。
如果想要手動指定Tor的類型和端口可以使用參數“--tor-type”和“--tor-port”,如:
--tor-type=SOCKS5 --tor-port 9050
如果要求高度的匿名性可以使用參數“--check-tor”,加上該參數後Sqlmap會確保所有流量都走Tor代理,若Tor代理失效,Sqlmap會發出警告並退出。檢測方法是訪問Are you using Tor?。
14.HTTP請求之間添加延遲
參數:--delay
過於頻繁地發送請求可能會被網站察覺或有其他不良後果。使用參數“--delay”來指定HTTP請求之間的延遲,單位為秒,類型是浮點數,如“--delay 1.5”表示延遲1.5秒。默認是沒有延遲的。
15.超時
參數:--timeout
超時時間默認為30秒,可以用參數“--timeout”指定超時時間,如“--timeout 44.5”表示設置超時時間為44.5秒。
16.超時後最大重試次數
參數:--retries
超時後Sqlmap會進行重試,最大重試次數默認為3,可以用參數“--retries”指定最大重試次數。
17.隨機化參數值
參數:--randomize
使用該參數,Sqlmap會隨機生成每次HTTP請求中參數的值,值的類型和長度依照於原始值。
18.用正則表達式過濾代理日誌
參數:--scope
指定一個Python正則表達式對代理日誌進行過濾,只測試符合正則表達式的目標,如:
python sqlmap.py -l burp.log --scope="(www)?\.target\.(com|net|org)"
19.避免錯誤請求過多而被屏蔽
參數:--safe-url、--safe-post、--safe-req和--safe-freq
有時服務器檢測到某個客戶端錯誤請求過多會對其進行屏蔽,而Sqlmap的測試往往會產生大量錯誤請求,為避免被屏蔽,可以時不時的產生幾個正常請求以迷惑服務器。有以下四個參數與這一機制有關:
- --safe-url: 隔一會就訪問一下的安全URL
- --safe-post: 訪問安全URL時攜帶的POST數據
- --safe-req: 從文件中載入安全HTTP請求
- --safe-freq: 每次測試請求之後都會訪問一下的安全URL
這裏所謂的安全URL是指訪問會返回200、沒有任何報錯的URL。相應地,Sqlmap也不會對安全URL進行任何註入測試。
20.關閉URL編碼
參數:--skip-urlencode
Sqlmap默認會對URL進行URL編碼,可以使用該參數關閉URL編碼。
21.繞過CSRF保護
參數:--csrf-token和--csrf-url
現在有很多網站通過在表單中添加值為隨機生成的token的隱藏字段來防止CSRF攻擊,Sqlmap會自動識別出這種保護方式並繞過。但自動識別有可能失效,此時就要用到這兩個參數。
“--csrf-token”用於指定包含token的隱藏字段名,若這個字段名不是常見的防止CSRF攻擊的字段名Sqlmap可能不能自動識別出,需要手動指定。如Django中該字段名為“csrfmiddlewaretoken”,明顯與CSRF攻擊有關。
“--csrf-url”用於從任意的URL中回收token值。若最初有漏洞的目標URL中沒有包含token值而又要求在其他地址提取token值時該參數就很有用。
22.強制使用SSL
參數:--force-ssl
23.在每次請求前執行特定Python代碼
參數:--eval
直接看例子:
python sqlmap.py -u "http://www.target.com/vuln.php?id=1&hash=c4ca4238a0b923820dcc509a6f75849b" --eval="import hashlib;hash=hashlib.md5(id).hexdigest()"
每次返送請求前,Sqlmap都會依據id值重新計算hash值並更新GET請求中的hash值
安全測試===sqlmap(零)轉載