专家-绕过常见防御-白名单过滤器
  # 实验室:基于白名单的输入过滤器 中的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
 
 回到浏览器页面,实验完成。
