一段绕过Web缓存+防火墙并用SSRF拿到AWS凭据的经历
Hi,朋友。我最近挖到一个有趣的漏洞,正迫不及待地想写出来。这个洞是利用一系列漏洞来绕过不同层的防御,最终拿到全印度最大的股票经纪公司的AWS凭据。下面我来介绍如何绕过Web应用防火墙(WAF)和Web缓存机制,并利用SSRF漏洞获取AWS账户凭据。
(以上操作均在有关公司的明确许可范围内)
一开始测试时,我发现了一个与文件系统交互的端点。于是我直接测试有没有LFI(本地文件包含)漏洞,却发现请求被Cloudflare防火墙挡在了外面——
(Cloudflare WAF)
现在为了绕过防火墙,我必须把请求直接发给原始服务器,希望它们的服务器或负载均衡器没有使用IP白名单策略——
(常见请求调用的场景)
为了找到原始服务器的IP,直接敲命令"dig www.xxx.com"
,并得到了原始服务器IP——
然后我在本地host文件中添加了这条DNS条目,并使用LFI读取/etc/passwd
,以下是得到的响应——
(打过码的示例图片)
我成功绕过防火墙并执行了LFI漏洞。在whois上搜索了此IP的相关信息后,我发现它属于AWS。我觉得它同时也是个SSRF漏洞因为存在一个“页面/URL”的转换特性,那接下来就是利用SSRF漏洞来读取AWS账户凭据。于是我继续调用API来读取AWS实例的元数据(http://169.254.169.254/latest/meta-data/
)——
(读取AWS实例元数据的HTTP请求)
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 06 Apr 2019 14:32:48 GMT
Content-Type: text/css;charset=UTF-8
Connection: close
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15552000
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Proxy-Cache: HIT
Content-Length: 0
响应码是200 OK但没有响应体,这意味着它确实与API进行了交互但最终返回了空响应。但为什么是空的?如果你仔细看一下上图,会发现服务器是一台"Nginx"
而且响应头中含有"X-Proxy-Cache"
。该响应头是由Nginx缓存层设置的,其值为"HIT"
也就意味着在客户端访问AWS元数据API时,服务器首先命中了Nginx缓存并用了缓存中的结果,而这个结果是空的。
现在为了从服务器获得响应,我不得不绕过缓存层。首先,我需要了解nginx缓存系统中的URL缓存分页规则。
一些参考文章——
https://www.digitalocean.com/community/tutorials/how-to-implement-browser-caching-with-nginx-s-header-module-on-centos-7
https://www.howtoforge.com/make-browsers-cache-static-files-on-nginx
我的理解是,一般缓存是基于URL路由路径的。如果URL是https://somewebsite.com/a.html
,并且它与路由路径匹配(根据缓存规则它会匹配),那么请求会指向缓存;如果网址是https://somewebsite.com/a.html?
那么URL路由路径不会匹配任何缓存规则,因此它将略过缓存并从服务器得到响应。于是我继续调用API并以?
或其他特殊字符结尾,来请求AWS实例元数据。这(http://169.254.169.254/latest/meta-data?
)与缓存规则中设置的URL路径路径不匹配,以下是返回的响应——
(绕过Web缓存的Http请求访问AWS实例元数据)
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 06 Apr 2019 14:32:48 GMT
Content-Type: text/css;charset=UTF-8
Connection: close
Vary: Accept-Encoding
Strict-Transport-Security: max-age=15552000
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Proxy-Cache: MISS
Content-Length: 315
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
identity-credentials/
instance-action
instance-id
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
product-codes
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
可以看到"X-Proxy-Cache"
缓存头现在被设置为"MISS"
,意味着API调用没有进入缓存层,而是直接从服务器获取了响应。
我最终成功绕过了缓存层并利用起了SSRF漏洞。现在来读取AWS账户凭证,直接调用AWS实例元数据安全凭证的API(http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance?
)如我所料,现在能获取到了——
我拿到了AWS的访问ID,访问**和令牌,现在能登录他们的AWS账户并访问大量重要内容。
总结一下,首先绕过Cloudflare防火墙使我可以利用LFI,然后绕过Web缓存机制将其升级为SSRF,最后我利用SSRF漏洞获得了AWS账户凭据。
怎么样,这是个有趣的漏洞吧!????