跨平台通杀看不懂?老师傅带你读懂网络协议漏洞
一般而言,我们对漏洞有三种传统分类:Web漏洞、二进制漏洞、逻辑漏洞。
而把“协议漏洞”单列一类基本上有如下的原因:
大部分都是协议设计阶段引入的问题,而不是软件实现阶段;
大部分存在跨软件、跨操作系统,甚至是跨硬件平台的通杀现象;
漏洞利用的目标通常是实现通信劫持,而不是RCE/ACE;
说了那么多“虚”的东西,现在来看点“实”的例子。从拒绝服务开始,首先给大家介绍的是一类叫 CPDoS(Cache Poisoning Denial of Service)的漏洞。这是 Web 缓存投毒的一种:CPDoS通常出现在通过反向代理给Web server提供静态资源 cache 服务的场景中,也就是 CDN。CDN 的 cache 可以理解成一个key-value 索引,多数情况下这个 key 就是 HTTP 请求中的 URL + Host + 一些关键 header,这里不会把所有header都纳入key,原因就是有些header会随着时间或者用户而变化(例如cookie),如果将其纳入key那么会把一份静态资源 cache 多次,产生浪费。而在这种场景下如果对HTTP请求中key以外的部分后端 web server 和 cache server 有不同的解析方式的话,就有可能出现 CPDoS 问题。
CPDoS case 1
如果此时 Client 请求的是 /index.html,Host 为 example.org,Cache key为 URL+Host,那刚刚 Client 的请求所产生的400 Cache 就会影响到其他同样访问 example.org/index.com 的用户,由此实现一例 DoS 攻击。
CPDoS case 2
一部分的 Web Server 支持一种叫做 “HTTP Method Override” 的技术,也就是用一个 header 来覆盖掉 HTTP 请求中的 Method,最常见的就是“X-HTTP-Method-Override” header,当 Client 发送一个 GET 请求并带上X-HTTP-Method-Override = POST 时,这个请求实际会被 Web Server 或者Web 中间件当作 POST 请求处理。
......,这里省略了一些细节,更全面的内容可以参考以下链接:
https://cpdos.org/
从 CPDoS 的例子里面大家可以发现,单独把 Cache Server 或者 Web Server 拆出来看都没有问题,但是当他们放在一起使用的时候就会出现问题。对,就是这么奇怪!而且这种问题还会因为 Cache Server 和Web Server 对 HTTP 协议解析细节的各种不同而产生细分变体,再加上多级缓存结构和 Web 应用所形成的协议特点最终让 CPDoS 在实际环境下变得五花八门。
而这时你应该会意识到:
(1)CPDoS 不是某个具体软件的问题,而是软件组合使用+不恰当的 Cache 策略导致的;
(2)修复 CPDoS 大概率不是软件开发层面的事情,而是运维层面的事情。
其实这里就引入了新的问题:HTTP 是一个以“报文”为基本传输单位的协议,但 TCP 是一个以“流”为基本传输单位的协议;这两者并不是天然兼容的,要在一个“流”上面准确的传输多个“报文”需要额外的分割策略。所谓“分割策略”最简单的例子就是分隔符(例如连续两个”\r\n”就可以用来分割 HTTP header 和body)。HTTP 上最基本的两种“分割策略”是:
(1) Content-Length
(2) Transfer-Encoding=chunked
第一种就是在 HTTP header 中使用一个 Content-Length 来指定当前报文的长度,超出这个长度的数据就属于下一个报文。第二种则是按照一种特殊的编码方式组织数据,例如这样:
POST /test.action HTTP/1.1\r\n
Host: example.org\r\n
Content_type: text/plain\r\n
Transfer-Encoding: chunked\r\n
\r\n
\r\n
4\r\n
Test\r\n
5\r\n
Pages\r\n
0\r\n
\r\n
其中的 4\r\n,Test\r\n,就是一个 chunk,数字4代表后面跟了4个字节,而 \r\n 是分隔符。当 Client 发送的 HTTP 请求里面同时包含这两种分割策略时不同的 Server 可能对这个请求会有不同的理解,例如下面这样:
GET / HTTP/1.1\r\n
Host:localhost\r\n
Content-length:56\r\n
Transfer-Encoding: chunked\r\n
Dummy:Header\r\n\r\n
0\r\n
\r\n
GET /tmp HTTP/1.1\r\n
Host:localhost\r\n
Dummy:Header\r\n
\r\n
GET /tests HTTP/1.1\r\n
Host:localhost\r\n
Dummy:Header\r\n
\r\n
如果 Server 对 Content-length 的解析优先于 Transfer-Encoding 的话,这段数据会被理解为三个 HTTP 请求,但如果反过来的话则只会被理解为两个 HTTP 请求。和上文中的 CPDoS 类似,在 CDN 的场景下,如果前后两个Server 对 HTTP 协议的理解不同的话就会出现问题。例如在第三方用户的请求里面插入一段攻击者指定的数据:
细节参考链接:https://xz.aliyun.com/t/6878。
HTTP Request Smuggling 和 CPDoS 有很多相似之处:
(1)都存在跨软件的广泛影响;
(2)都很难通过软件开发者的漏洞修补去解决问题。
这张图里面就是一个单方向 NAT(SNAT)的地址映射,内网发往外网的IP报文的源地址与源端口会被 NAT 网关篡改,变成 NAT 网关自己对外的 IP 和端口,而此时就需要维护一个内网 IP+端口到外网 IP+端口的映射表。当外网的数据回来时就可以按这张映射表来把 IP 包的目的地址和目的端口再改回来。
FTP 在主动模式下需要 Client 和 Server 都主动连接对方,只能单向通行的 SNAT 就无法 cover 这种需求了,所以又有了一个叫 ALG(Application Level Gateway)的技术:
REGISTER sip:192.168.2.89 SIP/2.0
Via: SIP/2.0/UDP 192.168.2.161:10586
Max-Forwards: 70
From: <sip:01062237496@192.168.2.89>;tag=ca04c1391af3429491f2c4dfbe5e1b2e;epid=4f2e395931
To: <sip:01062237496@192.168.2.89>
Call-ID: da56b0fab5c54398b16c0d9f9c0ffcf2@192.168.2.161
CSeq: 1 REGISTER
Contact: <sip:192.168.2.161:10586>;methods="INVITE, MESSAGE, INFO, SUBSCRIBE, OPTIONS, BYE, CANCEL, NOTIFY, ACK, REFER"
User-Agent: RTC/1.2.4949 (BOL SIP Phone 1005)
Event: registration
Allow-Events: presence
Content-Length: 0
这个漏洞的特殊之处在于:
(1)它不是程序实现上的失误导致的,而是 ALG 这种 NAT 上补充出来的技术在设计上就存在缺陷;
(2)这带来的一个很棘手的现实状况:没有完美的修补方案。要么完全不用 ALG,要么只能通过限制 ALG 的功能来缓解问题;
(3)NAT Split Streaming 也是一个跨软件甚至跨硬件的漏洞,从各个厂牌的家用路由器到商用防火墙均有中招的例子。
公众号内回复“协议”,可获取PDF版报告
微步情报局招聘通道
❖
安全服务工程师 戳我查看岗位详情
❖
安全分析师(威胁追踪方向)戳我查看岗位详情
❖
安全分析师(主机检测方向-Java)戳我查看岗位详情
第一时间为您推送最新威胁