zoukankan      html  css  js  c++  java
  • 分块传输编码在WEB安全中的应用——sql注入用,可以直接复用chunkSplitPostData还原

    分块传输编码在WEB安全中的应用

    from: https://www.zhihuifly.com/t/topic/1090 讲得非常清晰

    分块传输编码在WEB安全中的应用

    0x01 分块传输编码概念

    维基百科对分块传输编码的描述:

    分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。(使用HTTP 1.0协议,服务器会主动放弃chunked编码。)

    《HTTP权威指南》P373对分块传输编码的解释:

    0x02 分块传输编码格式

    标准的分块传输编码格式如下:

    php [chunk size][ ][chunk data][ ][chunk size][ ][chunk data][ ][chunk size = 0][ ][ ]
    chunk size是以十六进制的ASCII码表示,chunk数据以0长度的chunk块结束,也就是(30 0d 0a 0d 0a)。

    以下格式也可被识别:

    php [chunk size;other data][ ][chunk data]
    其中的分号之后的other data是无关数据。

    0x03 分块传输例子

    一个简单的分块传输HTTP请求如下:

    POST /inject.php HTTP/1.1
    Accept-Encoding: gzip,deflate
    Transfer-Encoding: chunked
    Connection: close
    Accept: */*
    Host: 172.20.10.2:8011
    Cache-Control: no-cache
    Content-Type: application/x-www-form-urlencoded; charset=utf-8
    Content-Length: 48
    
    6;kxebH
    id=123
    b;pAo6m
    12345678911
    0
    

    我们传输的数据主体id=123+12345678911分块后分别是6位和11位,上面的6和b就是块数据长度的16进制数,

    >>> hex(6)
    '0x6'
    >>> hex(11)
    '0xb'
    >>>
    

    我们在服务器输出参数id的值:

    HTTP/1.1 200 OK
    Date: Fri, 24 May 2019 02:17:07 GMT
    Server: Apache/2.4.7 (Ubuntu)
    X-Powered-By: PHP/5.5.9-1ubuntu4.17
    Content-Length: 14
    Connection: close
    Content-Type: text/html
    
    12312345678911
    

    f361cad5200dd8443d5f82150f7e9488

    可见块数据被服务器自动解码合并输出。

    0x04 分块传输应用

    根据分块传输原理,这种发包方式用于Bypass基于流量特征检测的WAF应该会很有作用。
    以SQL注入攻击为例,我们来分析下sqlmap最新版(2019.5.24下载的)如何利用分块传输绕过WAF进行SQL注入。

    lib/core/common.py行5160的chunkSplitPostData()函数实现对数据主体进行分块传输编码:

    def chunkSplitPostData(data):
        """
        Convert POST data to chunked transfer-encoded data (Note: splitting done by SQL keywords)
    
        >>> random.seed(0)
        >>> chunkSplitPostData("SELECT username,password FROM users")
        '5;4Xe90\r\nSELEC\r\n3;irWlc\r\nT u\r\n1;eT4zO\r\ns\r\n5;YB4hM\r\nernam\r\n9;2pUD8\r\ne,passwor\r\n3;mp07y\r\nd F\r\n5;8RKXi\r\nROM u\r\n4;MvMhO\r\nsers\r\n0\r\n\r\n'
        """
    
        length = len(data)
        retVal = ""
        index = 0
    
        while index < length:
            chunkSize = randomInt(1)
    
            if index + chunkSize >= length:
                chunkSize = length - index
    
            salt = randomStr(5, alphabet=string.ascii_letters + string.digits)
    
            while chunkSize:
                candidate = data[index:index + chunkSize]
    
                if re.search(r"%s" % '|'.join(HTTP_CHUNKED_SPLIT_KEYWORDS), candidate, re.I):
                    chunkSize -= 1
                else:
                    break
    
            index += chunkSize
            retVal += "%x;%s
    " % (chunkSize, salt)
            retVal += "%s
    " % candidate
    
        retVal += "0
    
    "
    
        return retVal
    

      

    如上可见,这里严格按照分块传输编码的规范,并对敏感关键词进行分割,敏感关键词在这里定义:

    lib/core/settings.py行808:

    a97b4f5db8858819b84dea35cfb68ea1

    这几个关键词明显不够,我们可以根据自己的需要添加一下。

    对了,还需要添加chunked的请求头,在lib/request/connect.py中:

    ad788d7c51ad9914617d8d7473be044a

    尝试利用他的--chunked参数进行分块传输注入:

    34f7634575e8c2819e2ba9db0ff87fee

    可见完美注入,再查看TCP流量:

    591db52a4be3addf3f37af4e71ac1865

    SQLMAP实现得很优雅。已经不需要自己来写tamper。

    0x05 分块传输应用场景拓展

    基于HTTP的攻击方式怎么能只局限于SQL注入呢,其实绕过WAF进行XSS、CSRF、SSRF、命令注入等攻击都可以通过分块传输来实现。

    1. 代理实现

    以XSS为例:
    使用代理实现请求体更改,已有人实现(https://github.com/4rat/sqlmap\_chunked\_proxy):

    3268c5a3170c1cebd81a9973ed510dfb

    运行脚本即监听9999端口,浏览器配置代理127.0.0.1:9999 。

    进行XSS:

    6b24c1db557b073f028e2063091c6683

    数据包情况:

    297762587cdd1627e7fc1e6263027358

    服务器解析情况:

    8aeaaceeec637db95e2d3f5987291502

    2. burp插件

    https://github.com/c0ny1/chunked-coding-converter

    d1c2ead23ae913e2da40acad2c13b934

    下图是一个最原始的XSS攻击数据包,这里尝试进行一次最原生的XSS攻击,流量特征非常明显了:

    f20149e78e8c7be102346715ceea5c9f

    使用插件进行分块传输:‘

    30f968463b89d44c7c12dcda96765d09

    完美X进去:

    11c8a50159f7e47b85dcbe4203af017c

    0x06 参考

    1. 维基百科:《分块传输编码》
    2. 《HTTP权威指南》
    3. SQL注入利用分块编码传输绕过[该方法可绕某狗]

      原理:
      在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,post请求报文中的数据部分需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的,也不包括分块数据结尾的,且最后需要用0独占一行表示结束。
      1. 开启上个实验中已关闭的content-length自动更新。给post请求包加入Transfer-Encoding: chunked后,将数据部分id=1 and 1=1进行分块编码(注意长度值必须为十六进制数),每一块里长度值独占一行,数据占一行如图八所示。
      在HTTP协议层面绕过WAF
      2.将上面图八数据包的
      id=1 and 1=1
      改为
      id=1 and 1=2
       即将图八中所标的第4块的1改为2。如图九所示没有返回数据,payload生效。
      在HTTP协议层面绕过WAF
       
      注意:分块编码传输需要将关键字and,or,select ,union等关键字拆开编码,不然仍然会被waf拦截。编码过程中长度需包括空格的长度。最后用0表示编码结束,并在0后空两行表示数据包结束,不然点击提交按钮后会看到一直处于waiting状态。
  • 相关阅读:
    LINQTOSQL作为底层ORM框架后,我们的数据基类就变成了这个样子
    一個傳統的C2C網站的用戶充值的过程
    ajax跨域获取数据
    C#+HTML+JS生成的树完整代码
    核心Swing组件(六)
    Swing组件集合的事件处理(六)
    Swing组件集合的事件处理(四)
    核心Swing组件(四)
    核心Swing组件(三)
    核心Swing组件(五)
  • 原文地址:https://www.cnblogs.com/bonelee/p/15188217.html
Copyright © 2011-2022 走看看