SQLMAP 限制 QPS

sqlmap qps控制

0X01 发包函数限制器

首先寻找一下SQLMAP的请求发包函数

sqlmap.py
131 行 main 进入主函数
135 行 进入主流程
经过一系列环境监测、cmdLineOptions参数初始化、init参数应用后等等后
start()  检测SQL注入函数 --> 跳转到 controller.py

==> /lib/controller/controller.py   -- 检测注入处
299 行 for targetUrl, targetMethod, targetData, targetCookie, targetHeaders in kb.targets:
遍历了所有url,如果用 -u,就for一次; 如果有list,就for多次吧。

本次是寻找发包函数,所以直接找到下面的 checkConnection(suppressOutput=conf.forms),一个检测
URL是否能连接的函数,-v 6第一个会发的请求。

==> /lib/controller/checks.py   -- 检测扫描条件
checkconnection函数中,定位到
Request.queryPage(content=True, noteResponseTime=False)
发送请求的代码段,跟进

==> /lib/request/connect.py   -- 请求类
connect.py queryPage根据各种条件发送请求的函数
初始化配置、根据请求方式来发包等功能,但这不是最终最小颗粒度的发包函数

跟进 getPage()函数,这是最小颗粒度的请求发包函数
该函数根据收到的参数拼接原始数据包,websocket的方式发出去。

请求函数为 lib equestconnect.py里的 getPage()函数
所以在getPage函数上加个自定义的装饰器,用来计算每一次的QPS、延迟QPS超标后的请求就好了

0X02 文件修改检测跳过

/lib/core/common.py -- checkIntegrity() 遍历文件检测文件的最新修改时间有没有问题,修改过则不运行了
这里直接在函数开始 return掉

0X03 类型报错

/lib/core/options.py 中 定义了重定向处理 redirectHandler
/libn/requests/redirecthandler.py 跳转302的处理函数 http_error_302 141行

for part in req.headers.get(HTTP_HEADER.COOKIE, "").split(delimiter) + ([headers[HTTP_HEADER.SET_COOKIE]] if HTTP_HEADER.SET_COOKIE in headers else []):

req.headers.get(HTTP_HEADER.COOKIE, "") 如果非空是bytes,delimiter是str,会导致报错

这里修改为 ==>

REQ_COOKIE = req.headers.get(HTTP_HEADER.COOKIE, "")
if type(REQ_COOKIE) == bytes:
    REQ_COOKIE = REQ_COOKIE.decode()
for part in REQ_COOKIE.split(delimiter) + ([headers[HTTP_HEADER.SET_COOKIE]] if HTTP_HEADER.SET_COOKIE in headers else []):

0X04 SQLMAP异常跑出

我们控制QPS的方式是跑出异常 --> celery收到特定的异常,重试任务
另外其他的做法也可以是sleep,但容易造成节点hang住,所以这里QPS采取了抛出异常重试、超过最大重试次数后报错的方式

所以这里将sqlmap的异常修改成抛出

sqlmap.py  main()  251行
    except SystemExit:
        pass
    except QpsLimitError:
        raise QpsLimitError

    except:

如果想在main中收到异常,还需要改一下  __main__

0X05 题外

只提供了思路和修改的地方,没有直接贴代码,因为QPS限制后的动作无法一致。

原文地址:https://www.cnblogs.com/huim/p/12558931.html