他们是怎样工作的——Sqlmap源码解析

本文深入探讨了Sqlmap源码中的dirtyPatches()函数,该函数主要负责对Python相关部分进行优化和补丁应用。包括调整HTTP客户端的最大行长度限制,防止双块编码,增强Windows上的inet_pton()支持,以及修改HTTP方法等。此外,还涉及到了对编码检测和随机字符串生成的处理。通过对这些细节的调整,Sqlmap能更好地处理HTTP响应和二进制数据检索。
摘要由CSDN通过智能技术生成
他们是怎样工作的——Sqlmap源码解析

目录
  1. dirtyPatches()

1、dirtyPatches()

从源代码的主函数开始出发,我们遇到了被调用的第一个函数 dirtyPatches()。
dirtyPatches
让我们一起看一看这个函数究竟是干什么的。首先进入 lib/core/patch.py 文件中查看该函数的实现。

def dirtyPatches():
    """
    Place for "dirty" Python related patches
    放置与Python相关的“脏”补丁
    """
    # accept overly long result lines (e.g. SQLi results in HTTP header responses)
    # 接受过长的结果行(例如:SQLi HTTP请求头响应中的结果)
    # _http_client 是对http包里的client.py文件的别名
    # _MAXLINE是读取客户端http请求时的最大行长度限制(原本为65536)
    _http_client._MAXLINE = 1 * 1024 * 1024
    
    # prevent double chunked encoding in case of sqlmap chunking (Note: Python3 does it automatically if 'Content-length' is missing)
    # 在 sqlmap 分块的情况下防止双块编码(注意:如果缺少"Content-length",Python3 会自动运行)
    # 在使用分块传输编码时,数据分解成一系列的数据块,并以一个或多个进行发送,此时 Transfer-Encoding: chunked 将取代 Content-Length 出现在请求头中。
    if six.PY3:
        # 检查 HTTPConnection 中是否有叫 __send_output 的属性,没有则设置
        if not hasattr(_http_client.HTTPConnection, "__send_output"):
            # 不带括号调用的是函数体本身。有点类似于C++中的别名,也就是说我在调用 "=" 前面的函数时,实际上执行的是后面函数所实现的操作。
            _http_client.HTTPConnection.__send_output = _http_client.HTTPConnection._send_output

        # 当 python 版本为3时,对_send_output函数进行调整
        def _send_output(self, *args, **kwargs):
            if conf.get("chunked") and "encode_chunked" in kwargs:
                kwargs["encode_chunked"] = False
            self.__send_output(*args, **kwargs)

        _http_client.HTTPConnection._send_output = _send_output
        
    # add support for inet_pton() on Windows OS
    # 在 windows 操作系统上添加了对 inet_pton()函数的支持
    # inet_pton() 函数用于处理 ipv4 地址,将点分十进制的 IP 地址转换为二进制的 IP 地址
    if IS_WIN:
        from thirdparty.wininetpton import win_inet_pton

    # Reference: https://github.com/nodejs/node/issues/12786#issuecomment-298652440
    # register 用于注册一个编解码器搜索函数;lookup 首先将会在注册表缓存中查找编码,如果未找到,则会扫描注册的搜索函数列表。
    # cp65001 是 UTF-8 的别名
    codecs.register(lambda name: codecs.lookup("utf-8") if name == "cp65001" else None)
    
    # Reference: http://bugs.python.org/issue17849
    if hasattr(_http_client, "LineAndFileWrapper"):
        def _(self, *args):
            return self._readline()

        _http_client.LineAndFileWrapper._readline = _http_client.LineAndFileWrapper.readline
        _http_client.LineAndFileWrapper.readline = _

    # to prevent too much "guessing" in case of binary data retrieval
    # 为了避免在二进制数据检索时出现太多的"猜测"
    # universaldetector是Mozilla公司提供的检测编码方式的工具
    # 设置最低置信度阈值,代表相似度为 最低置信度阈值及以上的目标 都会被标出
    thirdparty.chardet.universaldetector.MINIMUM_THRESHOLD = 0.90

    # 将外部参数用"空格"连接成一个字符串
    # re.search() 方法扫描整个参数字符串,并返回第一个成功的匹配。如果匹配失败,则返回 None。
    # 成功的情况下将获得强制给定的 HTTP 方法
    match = re.search(r" --method[= ](\w+)", " ".join(sys.argv))

    # 如果 HTTP 方法存在,且第一个匹配部分全部转换为大写后不为 POST 方式,则将 POST 方式转换为指定方式
    if match and match.group(1).upper() != PLACE.POST:
        PLACE.CUSTOM_POST = PLACE.CUSTOM_POST.replace("POST", "%s (body)" % match.group(1))

    # https://github.com/sqlmapproject/sqlmap/issues/4314
    # 生成随机字符串
    try:
        # 返回一个有 1个 byte 长度的字符串
        os.urandom(1)
    except NotImplementedError:
        # 执行出错时调用 random 函数,以对应版本的方式生成1个 byte 长度的字节流(1个byte是8位,可生成 0~255 之间的任意整数)
        if six.PY3:
            os.urandom = lambda size: bytes(random.randint(0, 255) for _ in range(size))
        else:
            os.urandom = lambda size: "".join(chr(random.randint(0, 255)) for _ in xrange(size))

文章的注释参考于下面这篇博客,本文是基于该博客的扩充,感谢该博主大佬的努力,如有侵权请联系我。
链接:sqlmap源码阅读(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羽路星尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值