如何通过滥用SSL/TLS绕过Web应用防火墙(WAF)

概述

近年来,Web安全已经成为信息安全领域的一个重要话题。由于Web所具有的优点,越来越多的关键服务都被开发成Web应用程序。但由此,对Web应用程序安全性的需求也逐渐增加,除了要拥有一套良好的开发标准之外,开发人员还应该充分考虑其安全性。Web应用程序防火墙是一个7级的防火墙,用于检查Web流量并尝试防范攻击。在本文中,我将主要描述一个有趣的Web应用防火墙绕过方式,我是在最近对WAF的代码审计工作中发现了这一问题。

 

漏洞成因

最近,我入职某家公司并进行一套WAF的部署测试工作。出于保密需要,我不会透露公司和产品的名称。部署过程的体系结构大致如下:

在我获得所需信息之后,我开始寻找绕过它的不同方法。在测试过程中,我被允许在WAF上进行不同的测试,在测试过程中,发现了一个滥用SSL密码的方式。在我第一次登陆WAF时,看到了一个“不受支持的SSL密码”的警告,这就引起了我的注意。随后,我开始阅读产品文档,并设法找到所有支持的SSL密码。但在进行下一步之前,我想先阐述一下SSL连接的工作原理。
SSL握手主要由3个阶段组成:
1、ClientHello/ServerHello阶段
握手过程开始于发送ClientHello消息的客户端。在该消息中,会包含服务器所需的全部信息。例如各种密码套件和支持的SSL/TLS版本。收到连接后,服务器将使用ServerHello消息进行响应,该消息中包含客户端所需的类似信息。服务器还将返回所使用的密码套件和SSL版本。
2、证书交换
在初始化连接之后,服务器需要向客户端证明其身份。服务器会将SSL证书发送到客户端,客户端会检查该证书,确认它可以信任后再继续连接。
3、密钥交换
在建立了安全隧道之后,服务器和客户端交换密钥,该密钥将用于加密和解密数据。

 

攻击思路

基于以上原理,我突然想到,如果我使用“不受支持的”SSL加密方式来初始化与支持该密码的Web服务器的连接,那么WAF就无法识别攻击行为,因为它这时无法监测到数据。
因此,我查阅了WAF厂商的文档,从中找到了所有受支持的SSL加密方式,如下所示。

SSLv3

SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA

TLS/1.0-1.2

TLS_RSA_WITH_NULL_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_EXPORT1024_WITH_RC4_56_MD5
TLS_RSA_EXPORT1024_WITH_RC4_56_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_RC4_128_MD5 = { 0x000x04 }
TLS_RSA_WITH_RC4_128_SHA = { 0x000x05 }
TLS_RSA_WITH_DES_CBC_SHA = { 0x000x09 }

下一步就是确定Web服务器支持的SSL加密方式。
实际上,有很多方法可以检测服务器支持的加密方式,但我们在这里选用了sslscan,因为该工具易于安装,并且能够提供大量详细信息。

pwn@thinkpad:~$ sudo apt install sslscan 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  sslscan
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 26,7 kB of archives.
After this operation, 81,9 kB of additional disk space will be used.
Get:1 http://al.archive.ubuntu.com/ubuntu bionic/universe amd64 sslscan amd64 1.11.5-rbsec-1.1 [26,7 kB]
Fetched 26,7 kB in 0s (73,8 kB/s)  
Selecting previously unselected package sslscan.
(Reading database ... 177002 files and directories currently installed.)
Preparing to unpack .../sslscan_1.11.5-rbsec-1.1_amd64.deb ...
Unpacking sslscan (1.11.5-rbsec-1.1) ...
Processing triggers for man-db (2.8.3-2) ...
Setting up sslscan (1.11.5-rbsec-1.1) ...
pwn@thinkpad:~$ sslscan http://target/ | grep Accept

输入上面的命令后,将会列出Web服务器支持的SSL/TLS版本和加密方式。
我们将sslscan的结果和产品文档中的内容进行比较,就能够发现Web应用程序防火墙中不支持但Web服务器支持的一些加密方式。

Accepted TLSv1 256 bits ECDHE-RSA-AES256-SHA

Web服务器支持该加密方式,但WAF并不支持。
为了验证我的理论,我创建了一个WAF规则,如果请求的路径是“/ssl-cipher-test”,则会阻止请求。
理论上,我们访问这一路径,WAF将会阻止这一行为,如下图所示。
而我们的绕过方式是,指定客户端的加密方式,只使用能绕过防火墙的特定方式。
我们可以在curl上使用—ciphers指定加密方式,在示例中我选用了ECDHE-RSA-AES256-SHA。

pwn@thinkpad:~$ curl --ciphers ECDHE-RSA-AES256-SHA https://waf-test.lab.local/ssl-cipher-test
<html lang=en>
  <title>HELLO </title>
  <p>Bypass worked</p>
pwn@thinkpad:~$

正如我们在响应中所看到的那样,Web应用程序防火墙被成功绕过。

 

总结

在发表此文章之前,我本想编写一个扫描程序来扫描所有支持的加密方式,并找到一个能够绕过防火墙的加密方式,启动代理监听器,使用这一加密方式转发所有请求。
由于编写过程需要大量时间,因此我还暂时没能完成这项工作,如果大家感兴趣,也可以自行开发这样的利用工具。

 

参考文章

[1] https://security.stackexchange.com/questions/67931/why-cant-i-decrypt-ssl-traffic-with-the-clients-private-key-only
[2] https://www.owasp.org/index.php/TLS_Cipher_String_Cheat_Sheet
[3] https://github.com/curl/curl/blob/13ef623a81736e95da1cc1d13a02dd78e228adee/docs/CIPHERS.md

审核人:yiwang   编辑:边边

(完)