专家-绕过常见防御-白名单过滤器
# 实验室:基于白名单的输入过滤器 中的SSRF
# 题目
此实验室具有库存检查功能,可从内部系统获取数据。
要解决实验室问题,请将库存检查的 URL 更改为http://localhost/admin
,以此访问管理界面并删除carlos
用户。
开发人员部署了一个反 SSRF 防御,你需要绕过它。
- name: 实验室-专家
desc: 基于白名单的输入过滤器 中的SSRF >>
avatar: https://fastly.statically.io/gh/clincat/blog-imgs@main/vuepress/static/imgs/docs/burpsuite-learn/public/lab-logo.png
link: https://portswigger.net/web-security/ssrf/lab-ssrf-with-whitelist-filter
bgColor: '#001350'
textColor: '#d112fe'
2
3
4
5
6
# 实操
根据题意,可得实验目标:
- 找到 库存检查 功能并更改参数的 URL 值,尝试绕过 SSRF 防御,然后访问管理界面并删除 carlos 用户。
点击 “ACCESS THE LAB” 进入实验室。

来到首页,点击任意商品下方的 “View details” 进入详情页。

在商品详情页的下方,可以看到一个库存检查功能。
启用浏览器代理,然后点击 “Check stock” 检查库存。

查看捕获的数据包,在 POST 中存在一个参数stockApi
,它直接请求了一个 URL 链接。

通过 Repeater 功能模块,修改其中的stockApi
参数为http://localhost/admin
。
访问失败,请求的主机名必须为stock.weliketoshop.net
。

# 失败的绕过
根据前面学习到的理论知识,可以通过@
符号进行绕过,格式为http://预期主机名:假密码@恶意主机名/
。
构造 URL 链接:
http:/
发送请求数据包,访问失败。

方法2,通过#
符号进行绕过,格式为http://恶意主机名#预期主机名/
。
构造 URL 链接:
http:#stock.weliketoshop.net/
发送请求数据包,依然访问失败。

方法3,尝试拼接自己的 FQDN ,格式为http://预期主机名.恶意主机名
。
经过尝试,连网站自己的子域名都不行,更别说我们的主机名了。

方法4,尝试 URL 编码绕过,依然失败。
方法5,结合以上方法进行绕过。
# 成功的绕过
在经过六十多次、多种组合的方式之后,终于绕过成功了。(我是菜b,那么久才成功)
需要结合以下三种绕过方法:@
符号 + #
符号 + URL二次编码。

首先,结合 @、# 这两种方式,构造出以下 URL 链接:
http:#:123456@stock.weliketoshop.net/
请求失败,说明白名单过滤器进行了以下操作:
- 过滤器会识别
@
和#
符号,而#
后面是锚点链接,不属于主机名的一部分; - 所以,过滤器会忽略
#
后面的内容,优先取#
前面的内容; - 最终,获得主机名
localhost
,不符合预期规则,拒绝访问。

然后,结合 @、#、URL编码 这三种方式,构造出以下 URL 链接:
对符号 # 进行了一次URL编码
http:/
2
请求失败,说明白名单过滤器进行了以下操作:
- 过滤器先对 stockApi 进行了一次 URL 解码;
- 然后,识别
@
和#
符号,而#
后面是锚点链接,不属于主机名的一部分; - 所以,过滤器会忽略
#
后面的内容,优先取#
前面的内容; - 最终,获得主机名
localhost
,不符合预期规则,拒绝访问。

第三次组合,结合 @、#、URL二次编码 这三种方式,构造出以下 URL 链接:
对符号 # 进行了两次URL编码
http:/
2
请求成功!响应状态码为 200 。
说明白名单过滤器进行了以下操作:
- 过滤器先对 stockApi 进行了一次 URL 解码。此时,
%25%32%33
变为%23
,并没有变成井号; - 然后,由于井号被编码了,过滤器认不出来;
- 所以,过滤器只会识别
@
符号,@
前面的内容被认为是 用户名:密码,@
后面的内容被认为是主机名; - 最终,获得主机名
stock.weliketoshop.net
,符合预期规则,允许访问。
允许访问之后,到了请求 URL 这一步骤:
- 应用程序请求该 URL 之前,会对 stockApi 进行多次 URL 解码。此时,
%25%32%33
变为#
; - 然后,应用程序会识别
@
和#
符号,而#
后面是锚点链接,不属于主机名的一部分; - 所以,应用程序会忽略
#
后面的内容,优先取#
前面的内容; - 最终,程序获得主机名
localhost
,并请求该链接。
从而造成 SSRF 漏洞。

为刚刚构造的 URL 加上路径,成功访问管理界面。
http:/admin

最后,访问删除用户的 URL ,并删除 carlos 用户。
http:/admin/delete?username=carlos

回到浏览器页面,实验完成。
