用户
搜索
  • TA的每日心情
    开心
    前天 18:04
  • 签到天数: 116 天

    连续签到: 1 天

    [LV.6]常住居民II

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    11

    主题

    37

    帖子

    2001

    魔法币
    收听
    0
    粉丝
    4
    注册时间
    2018-6-2

    i春秋签约作者

    发表于 2020-11-7 22:32:55 24673
    本帖最后由 dll_s 于 2020-11-7 22:38 编辑

    0x40 Burpsuite练兵场-HTTP走私(一)


    好久不见各位,前段时间因为一些事情停更了下,今天这一章节来介绍一个较为新鲜的高端操作,HTTP请求走私(HTTP request smuggling),这个词在web渗透的文章中出现还是比较少的,初看可能会觉得有些莫名其妙,但理解了原理后就会发现这个取名非常的形象

    HTTP请求走私(HTTP request smuggling),简单的讲就是利用不同设备对HTTP协议的实现不同从而绕过特征检测,走私HTTP报文数据。考虑这样一个场景,我们需要访问一台载有web内容的服务器A,在这服务器前有一个进行特征检测的防火墙设备B。然后我们对A发起SQL注入测试,该HTTP报文发送到B后由于特征语句遭到了拦截,这时候我们可以利用HTTP走私技术,使设备B忽略报文中的SQL注入语句,从而在服务器A中成功执行。

    以上是从宏观角度理解HTTP走私的大致原理,接下来通过具体细节对如何实现HTTP走私进行剖析:

    大多数HTTP请求走私漏洞的出现,是因为HTTP规范提供了两种不同的方式来指定请求的结束位置

    Content-Length头:以字节为单位指定消息体的长度,例如:

    POST /search HTTP/1.1
    Host: normal-website.com
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 11
    
    q=smuggling

    Transfer-Encoding头:使用chunked指令时指定报文体使用分块编码。这意味着报文体中包含一个或多个数据块,每个块由以字节为单位(以十六进制表示)的块大小组成,用换行分割数据块,报文体以大小为零的块结束。例如:

    POST /search HTTP/1.1
    Host: normal-website.com
    Content-Type: application/x-www-form-urlencoded
    Transfer-Encoding: chunked
    
    b(代表报文块长度)
    q=smuggling
    0

    其他Transfer-Encoding可使用的编码方式参阅:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Transfer-Encoding

    注意:在每一个分块的开头需要添加当前分块的长度,以十六进制的形式表示,后面紧跟着 '\r\n' ,之后是分块本身,后面也是'\r\n' 。此类报文终止块后面是一个挂载(trailer),由一系列(或者为空)的实体消息首部构成。简单的说我们在走私数据时最好在终止块0后添加多个换行符,如:

    POST /search HTTP/1.1
    Host: normal-website.com
    Content-Type: application/x-www-form-urlencoded
    Transfer-Encoding: chunked
    
    0
    
    smuggling(走私数据)

    HTTP规范提供了这两种不同的方法来指定HTTP报文的长度,这导致了一个问题,如果在单个消息中同时使用两种方法就会引起冲突。为了避免这个问题,HTTP规定如果 Content-LengthTransfer-Encoding同时存在,那么应该忽略Content-Length。但并不是所有服务器都会遵循这一规范来实现HTTP传输操作,所以当有两个或多个服务器连接在一起时就会出现一些问题:

    • 一些服务器不支持解析HTTP报文中的Transfer-Encoding请求头
    • 一些支持Transfer-Encoding解析的服务器可能在解析混淆的报文头时出现问题

    所以如果前置服务器和后台服务器对Transfer-Encoding的解析支持不同,就会产生不一样的报文长度判断,以此导致HTTP走私漏洞的产生

    可能光看文字介绍不是很好理解,接下来进入实验进一步深入

    实验内容


    前面介绍了HTTP请求走私的原理,在实验开始前介绍一下如何进行具体的攻击操作

    请求走私攻击包括将Content-LengthTransfer-Encoding头放到单个HTTP请求中,并对它们进行操作,以便观察前端和后端服务器对请求的处理方式。具体的攻击方式取决于两个服务器的行为:

    • CL.TE: 前端服务器解析Content-Length ,后端服务器解析Transfer-Encoding
    • TE.CL: 前端服务器解析 Transfer-Encoding ,后端服务器解析Content-Length
    • TE.TE: 前后端服务器都支持Transfer-Encoding头解析,但其中一台在面对混淆的HTTP报文(同时包含Content-Length头和Transfer-Encoding头)时会忽略解析

    另外,在实验环节中可以看到提示我们可以使用Burpsuite提供的插件HTTP Request Smuggler进行自动化漏洞检测和利用,但这涉及到对另一插件Turbo Intruder的深入定制操作,所以会在后续合适的章节中进行讲解

    实验一:CL.TE情境

    实验提示:这个实验涉及到了两台服务器,前端服务器不支持分块编码传输(即不支持Transfer-Encoding解析),后端服务器拒绝GET和POST之外的请求

    实验要求:走私一个HTTP请求到后端服务器,使得其处理的下一个请求看起来使用的是GPOST方法

    img

    同样先浏览网页,查看报文

    我们所要做的就是使用分块传输,将前一个报文中的数据G进行走私,使得后端服务器在处理后一请求时会将G添加到POST之前

    将这一请求发送到Repeater模块

    img

    根据提示,我们可以知道前端服务器仅通过CL进行报文长度判断,而后端服务器支持TE请求头,那么我们可以构造这样的报文进行数据走私,将GET修改为POST,然后添加了分块数据

    img

    当我们发送这个报文时,前端服务器通过CL判断这为一整个报文,并将其传输给后端服务器。后端服务器接收后通过TE字段将报文分块,读取到终止块时判断这一请求结束,而剩余的数据G即被留在了信道中

    当我们再次发送这一报文时,前面流程相似,不同的是留存在信道中的G被添加到了新的POST请求之前,使得报文请求方式变为了GPOST,至此就完成了这一实验

    img

    注意:

    • HTTP中的换行\r\n编码为0d0a,在CL中的长度为2
    • 通常情况下这两台服务器中的信道会被重复使用,不会被关闭,导致前一请求报文中的分块可能会干扰后一请求报文

    实验二:TE.CL情境

    实验提示:这个实验涉及到了两台服务器,后端服务器不支持分块编码传输(即不支持Transfer-Encoding解析),前端服务器拒绝GET和POST之外的请求

    实验要求:走私一个HTTP请求到后端服务器,使得其处理的下一个请求看起来使用的是GPOST方法

    img

    与之前的实验类似,只不过需要变换一下具体逻辑,我们首先来看一下在这种情境中走私报文的逻辑

    POST / HTTP/1.1
    Host: vulnerable-website.com
    Content-Length: 3
    Transfer-Encoding: chunked
    
    8
    SMUGGLED
    0

    当前端服务器接收到此报文时,会忽略Content-Length报文头,将该报文分割为SMUGGLED和终止块,然后转发到后端服务器。由于后端服务器不支持解析Transfer-Encoding消息头,因此会通过Content-Length:3将报文分割为8和后续的数据块,数据块8被成功处理,而后续的数据块则被作为了序列中后续请求的开头

    进入实验,首先需要去掉勾选Update Content-Length防止Buprsuite自动更新Content-Length字段

    img

    尝试使用上一实验的走私方式,发现G后的0也被走私了

    img

    所以需要完整构造GPOST报文请求,如下图(注意0后面需要有两个回车 \r\n\r\n

    img

    这里的分块长度5c比较难以计算,后续会讲解自动化利用,所以可以直接复制下面的payload

    Content-length: 4
    Transfer-Encoding: chunked
    
    5c
    GPOST / HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 15
    
    x=1
    0

    实验三:混淆的TE头

    实验提示:这个实验涉及到了两台服务器,这两个服务器以不同的方式处理混淆的HTTP请求头,前端服务器拒绝GET和POST之外的请求

    实验要求:走私一个HTTP请求到后端服务器,使得其处理的下一个请求看起来使用的是GPOST方法

    img

    在实验开始前,我们先来看看BP学院中的讲解

    在这种情况下,两台服务器均支持解析Transfer-Encoding头,但其中的一台服务器面对模糊的请求头时会出现问题,比如以下这些

    Transfer-Encoding: xchunked
    Transfer-Encoding : chunked
    Transfer-Encoding: chunked
    Transfer-Encoding: x
    Transfer-Encoding:[tab]chunked
    [space]Transfer-Encoding: chunked
    X: X[\n]Transfer-Encoding: chunked
    Transfer-Encoding
    : chunked

    之所以在处理这些请求头时会出现问题,是因为在实际的HTTP协议实现中,很少有代码精确的遵循了其中的规范,以此导致面对变形的请求头时会出现不同的处理方式。而我们所要做的就是找到其中存在问题的服务器,然后使用类似前两个情形的攻击报文走私数据

    使用的payload如下

    Content-length: 4
    Transfer-Encoding: chunked
    Transfer-encoding: cow
    
    5c
    GPOST / HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 15
    
    x=1
    0

    猜测背后的逻辑是这样的:前端服务器成功识别出了混淆的TE头,成功将报文分为两块转发。而后端遇到混淆头时放弃了解析,遵循CL头对报文进行分块,导致5c后的报文被留在了复用的信道中,干扰了下一个请求报文

    注意同样需要去掉勾选Update Content-Length

    img

    成功完成实验

    总结


    这一章节主要是对HTTP请求走私的初步了解,所以不必纠结于如何在实际环境中如何发现和利用这一漏洞,这些内容会在后续环节介绍

    关于如何防范HTTP走私:

    • 禁止后端服务器之间的信道重用,以便通过单独的网络连接发送每个后端请求
    • 对于后端连接使用HTTP/2,因为该协议可以防止请求之间的边界不明确
    • 在前端和后端服务器上使用完全相同的web服务器软件,以便它们对请求之间的边界达成一致

    扩展阅读


    协议层的攻击——HTTP请求走私 https://paper.seebug.org/1048/

    发表于 2020-11-7 22:38:19
    另外,现在正在评选i春秋荣誉作家,如果喜欢我的技术分享那就帮我投出您宝贵的一票吧,谢谢啦
    我是dll_s,投票链接:https://www.ichunqiu.com/20201111

    使用道具 举报 回复
    dll大佬!!!
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册