关注这个靶场的其他相关笔记:XSS - LABS ------ 靶场笔记合集-CSDN博客
0x01:过关流程
进入关卡,右击页面,查看页面源代码,搜索 good job!
,查看回显点(这里埋下一个坑):
通过查看源码,我们发现了页面又存在隐藏表单的行为,这里就不再像上一关那样麻烦的,又是让标签显示,又是自己编写提交按钮了,我们根据 name
中的内容,直接构造 GET 请求,查看页面的回显点:
html
?t_link=test1&t_history=test2&t_sort=test3&t_ref=test4
可以发现回显点又是 t_sort
,那么下面我们针对该回显点测试后端过滤规则:
Payload | Echo Print |
---|---|
" |
" |
' |
' |
< |
< |
> |
> |
script |
script |
on |
on |
至此,我们又一次的陷入了死局,无法逃逸出双引号,也没办法创建新的标签。
经过笔者开过天眼后,发现,从本关开始,似乎已经开始将注意力转向了究竟是哪个参数能够触发 XSS 的问题,而不像前 10 关主要都是集中在如何绕过过滤。
在 Level 11 中,之前有个字段一直被我们忽略,就是 t_ref
,我们在测试过,对其传参并不会回显后就直接放弃了对其的测试。然而,本关的突破口就在这,该参数回显的并不是我们通过 GET 传递的数据,而是请求包的 Referer 字段(这能联想?作者这猪脑是联想过了,但是没测试过,不愧是 CTF):
知识拓展:HTTP Referer
HTTP Referer 是 HTTP 请求头的一部分,Referer 字段包含了发起请求的前一个 URL 地址,即用户访问当前页面之前所在的页面地址。当用户通过点击一个链接从一个网页导航到另一个网页时,浏览器会在新的 HTTP 请求中包含 Referer 字段,其值为用户点击链接前所处的页面的 URL。如果用户直接在地址栏输入 URL 或者通过书签、刷新页面等方式访问一个页面,那么 Referer 字段通常不会被发送,或者设置为 null。
修改请求包的 Referer 字段,我们既可以使用 BurpSuite 进行抓包修改,还可以便捷一点,使用浏览器插件 HackBar,HackBar 的详细教程链接如下:
进入关卡,鼠标右击页面,点击检查,选中 HackBar 插件,点击 Load URL,载入当前网址,并勾选 Referer 字段:
我在新添加的 Referer 字段中填写了 123456,并点击 Execute,准备测试一下目标的回显状态:
由上面的图片可知,我们成功找到了注入点,下面就是绕过引号过滤,并且为 input
标签添加事件监听,所以 Payload 如下(同样输入在 HackBar 的 Reference 字段中):
html
" type="text" onmouseover="alert(1)
0x02:源码分析
下面是 XSS LABS Level 11 的源码,以及我对其的部分笔记:
php
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
// 修改 alert 的默认行为,跳转进入下一关
window.alert = function() {
confirm("完成的不错!");
window.location.href = "level12.php?keyword=good job!";
}
</script>
<title>欢迎来到level11</title>
</head>
<body>
<h1 align=center>欢迎来到level11</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"]; // 接收 GET 传参 keyword
$str00 = $_GET["t_sort"]; // 接收 GET 传参 t_sort
$str11 = $_SERVER['HTTP_REFERER']; // 接收 HTTP 请求包中的 Referer 来源字段
$str22 = str_replace(">", "", $str11);
$str33 = str_replace("<", "", $str22);
echo "<h2 align=center>没有找到和" . htmlspecialchars($str) . "相关的结果.</h2>" . '<center>
<form id=search>
<input name="t_link" value="' . '" type="hidden">
<input name="t_history" value="' . '" type="hidden">
<input name="t_sort" value="' . htmlspecialchars($str00) . '" type="hidden">
<input name="t_ref" value="' . $str33 . '" type="hidden">
</form>
</center>'; // $str33 只是过滤了参数中的 <>,并不严格,可以通过 " 逃逸出去,导致 XSS 漏洞
?>
<center><img src=level11.png></center>
<?php
echo "<h3 align=center>payload的长度:" . strlen($str) . "</h3>";
?>
</body>
</html>
通过对后端代码的分析,感觉似乎是遇到了一个瓶颈,是不是,只要一个参数使用了 htmlspecialchars()
且其被包裹在"
内或者不被任何标签包裹,就并无绕过的可能了(像能直接触发javascript:alert(1)
这种不考虑在内)?回想靶场的前几关,我们只在 Level 3 中成功绕过了 htmlspecialchars()
,原因是回显点在'
内,而 PHP 低版本中的 htmlspecialchars()
并不会对 '
号进行 HTML 编码,导致我们成功逃逸,但这个 Bug 在 PHP 8 中已经没了(PHP 8 的 htmlspecialchars()
默认是会对其进行编码的)。
php
<!-- 思考:下面的代码是否存在绕过的方案,在 PHP 5 中(放低要求)? -->
<meta charset="utf-8">
<?php
$keyword = htmlspecialchars($_GET["keyword"]);
// Kind 1:经过 htmlspecialchars 过滤后,直接显示在标签内
echo "<div> 您传递的内容为:" . $keyword . "</div><br>";
// Kind 2:经过 htmlspecialchars 过滤后,显示在不能触发 javascript:alert(1) 的标签内,且标签被 " 号包裹
echo '<input type="text" value="' . $keyword . '">';
?>
0x03:靶场复盘
0x0301:为什么进入关卡后 t_ref 的 value 字段为空?
经过源码分析后,我们发现 t_ref
字段的取值是来自请求头中的 Referer 字段,那么为什么,在过关流程第一步中,我们查看源码时,发现 t_ref
的 value
字段值为空呢(按照常理,我们从 Level 10 跳转到 Level 11 时,请求头中肯定会有 Referer 字段,且值为 Level 10 的过关 URL)?
经过复盘,笔者发现是,可能是笔者一边记笔记,一边过关的缘故,在进入 Level 11 的时候通过地址栏输入 URL 的方式直接访问关卡,导致浏览器没有发送 Referer 字段,进而造成了 Bug:
下面笔者通过询问 AI,总结了几条浏览器不发送 Referer 字段的场景(并未测试,但是感觉挺有意思的):
-
直接访问: 如果用户直接在浏览器的地址栏中输入 URL,或者通过书签访问页面,那么这次请求通常不会包含
Referer
字段,因为没有 "来源" 页面。 -
隐私模式或安全设置: 某些浏览器在隐私模式(无痕模式)下或当用户启用了特定的安全设置时,可能会阻止发送
Referer
字段。 -
HTTPS 到 HTTP 的降级: 如果用户从一个 HTTPS 页面导航到一个 HTTP 页面,出于安全的考虑,某些浏览器可能不会发送
Referer
字段,以防止敏感信息泄露。 -
重定向: 如果请求经过了重定向(比如从 HTTP 重定向到 HTTPS),那么原始的
Referer
字段可能会被清除或修改。 -
浏览器插件或扩展: 安装的浏览器插件或扩展可能会修改或删除 HTTP 请求的头部信息,包括
Referer
字段。 -
浏览器缓存: 在某些情况下,浏览器缓存可能会导致请求看起来没有包含
Referer
字段,但实际上可能是存缓存中加载的内容而不是新的请求。
思维拓展:利用 Referer 攻击?
这里纯属笔者记着记着瞎想的,分享出来,给大家拓宽一下思维。
攻击思路:
Referer 字段的值是上一个请求来源的 URL,而有些网站又会将敏感信息通过 URL 传递。攻击者是否就可以通过 Referer 字段,读取那些敏感信息。
场景假设:
A 网站,被攻击方,喜欢将敏感信息放在 URL 上,还喜欢贴广告赚钱。
B 网站,Hacker 搭建的网站,会记录请求的 Referer 信息。
攻击流程:
客户小红,在 A 网站的管理后台上操作时,不小心点击到了广告链接,此广告会直接跳转到 B 网站(携带 Referer 字段),Hacker 通过查看后台获取的 Referer 字段,成功冒充小红的身份,进入 A 网站。
0x0302:此种类型的 XSS 漏洞如何利用?
本次关卡的 XSS 漏洞点是在 HTTP 请求头的 Referer 字段中。而 Referer 字段是浏览器自行添加的,无法直接通过注入 javascript 代码来进行操作。那么,这种类型的 XSS 漏洞应该如何利用呢?
没有利用价值的漏洞,等于没用。我们不可能期待攻击者自己去修改 Referer 字段,自己攻击自己吧。下面笔者在这里提供几个攻击思路:
1. 编写浏览器插件并发布
如上,我们攻击使用的是 HackBar 插件,它就可以修改请求的 Referer 字段。证明了插件修改请求字段的可行性。
那攻击者是否可以也编写一个插件,内部隐藏攻击代码,如果受害者电脑上安装了此插件,并且访问了指定站点(含有 XSS 漏洞的站点),插件自动触发攻击,重新请求该页面,并修改 Referer 字段,导致页面被篡改。
这个纯属作者臆想,不过作者感觉有搞头。
2. 利用重定向攻击(失败了)
XSS 漏洞点在 Referer 字段利用还是有点难度的,下面是笔者根据臆想写的一个利用站点,但是利用失败了,分享出来,让你们笑一下:
php
<!-- attacker.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XSS Level 11 利用站点</title>
</head>
<body>
<a href='?redirect=true&payload=" type="text" onmouseover="alert(1)'> 这是一个人畜无害的超链接 </a>
<?php
$redirect_sign = $_GET["redirect"];
if ($redirect_sign == "true") {
// 如果存在重定向标志,则重定向到存在漏洞的站点
echo '<script>window.location.href = "http://127.0.0.1/xss-labs/level11.php?keyword=good%20job!";</script>';
}
?>
</body>
</html>
下面是笔者臆想的攻击流程:
下面是来自现实的打脸,Referer 字段是浏览器自动添加的,而且还会对特殊符号进行 URL 编码:
至于 PHP 脚本中用来跳转的语句,为什么要通过输出一个 javascript 脚本来完成,给你们看个图就知道了,下面是我通过 header 跳转后的样子(因为用 header 差点吓得我把之前笔记删了):
问题就出在这,通过 header()
进行重定向,上一个页面的参数并不会被携带,既然不会被携带,还攻击个啥哦。