目录
本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到真实原因,讲解XSS的原理并进行渗透实践,本文为XSS第06关-XSS盲打的渗透部分,并且结合源码分析,对比通用的XSS攻击讲解攻击成因。
一、XSS盲打
XSS盲打是一种特殊的存储型XSS攻击,其核心特点是:
攻击者无法立即看到攻击效果:恶意脚本被存储在服务器后,需等待特定用户(如管理员)访问包含该脚本的页面时才会触发。
延迟性攻击:从注入到触发可能间隔数小时甚至数天。
XSS(跨站脚本攻击)指攻击者通过在网页中注入恶意 JavaScript、HTML 等脚本代码,利用网站对用户输入过滤不严格的缺陷,当用户访问被攻击页面时,浏览器会执行这些恶意脚本,从而窃取用户敏感信息、劫持会话、篡改页面内容,严重威胁用户隐私和系统安全。
XSS(跨站脚本攻击)和 XSS 盲打(Blind XSS)主要区别如下:
对比维度 | XSS | XSS 盲打 |
---|---|---|
攻击反馈 | 攻击者能即时看到攻击效果,可通过用户访问含恶意脚本页面,观察脚本执行后的情况,如弹窗等 | 攻击者难以立即知晓攻击是否成功,因为注入点和显示点分离,需等待特定用户访问特定页面触发 |
注入位置 | 注入点与显示点通常在同一页面或同一应用流程中,较易定位和测试 | 注入点和显示点往往不同,可能注入在某个页面,但在其他管理页面显示,增加攻击难度和隐蔽性 |
攻击场景 | 常见于论坛、搜索框等用户输入会即时展示的场景 | 多见于用户输入数据存储后,由管理员或其他特定用户在后台页面查看的场景,如留言反馈、表单提交 |
二、源码分析
1、进入靶场
进入pikachu靶场XSS的06关“XSS盲打”关卡,如下所示是一个留言页面,具体如下所示。
http://127.0.0.1/pikachu/vul/xss/xssblind/xss_blind.php
2、源码分析
打开xss_blind.php文件,可以看到直接将用户提交的时间,内容和用户名通过SQL语句条件到数据库中,没有什么限制。我们输入的内容不会在前端输出,而是提交到了后台,管理员可能会去看。如果我们输入一个JS代码,管理员登录后台管理界面,如果后台把我们的内容输出那后台管理员可能遭受到我们的XSS攻击。具体代码如下所示。
接下来进行详细分析,为何代码存在 XSS 盲打安全风险:
- 缺乏对 XSS 攻击的防护:
escape
函数通常是为防止 SQL 注入而设计,对输入数据进行 SQL 层面的转义。但它没有对可能的 HTML 标签和 JavaScript 代码进行处理,攻击者可以输入包含恶意脚本的内容,如<script>alert('XSS')</script>
,这些内容会被原样存储到数据库中。 - 未对输出内容进行过滤:当管理员或其他用户在其他页面查看这些存储的数据时,由于没有对从数据库取出的数据进行 HTML 实体编码等安全处理,浏览器会将其中的脚本代码解析并执行,从而导致 XSS 攻击。因为攻击的注入点(用户提交数据的页面)和显示点(管理员查看数据的页面)不同,属于 XSS 盲打攻击场景。
对源码进行详细注释,具体如下所示。
<?php
// 调用 connect 函数,该函数应该是自定义的用于建立数据库连接的函数
// 连接成功后将连接对象赋值给变量 $link
$link = connect();
// 初始化一个空字符串 $html,用于存储后续要输出给用户的提示信息
$html = '';
// 检查 $_POST 数组中是否存在键为 "content" 的元素,并且该元素的值不为 null
// 即判断用户是否通过 POST 请求提交了名为 "content" 的数据
if (array_key_exists("content", $_POST) && $_POST['content'] != null) {
// 调用 escape 函数对用户提交的 "content" 数据进行处理
// escape 函数可能是自定义的,用于对输入数据进行转义,防止 SQL 注入
// 将处理后的结果赋值给变量 $content
$content = escape($link, $_POST['content']);
// 同样地,调用 escape 函数对用户提交的 "name" 数据进行处理
// 并将处理后的结果赋值给变量 $name
$name = escape($link, $_POST['name']);
// 获取当前时间,并按照 'Y-m-d g:i:s' 的格式进行格式化
// 例如格式可能为 '2024-10-10 10:10:10'
$time = date('Y-m-d g:i:s');
// 构建一个 SQL 插入语句,用于将用户提交的时间、内容和姓名信息插入到名为 xssblind 的数据库表中
$query = "insert into xssblind(time,content,name) values('$time','$content','$name')";
// 调用 execute 函数执行上述构建好的 SQL 插入语句
// execute 函数应该是自定义的,用于封装执行 SQL 语句的逻辑
$result = execute($link, $query);
// 检查执行 SQL 语句后受影响的行数是否为 1
// 如果为 1,说明插入操作成功
if (mysqli_affected_rows($link) == 1) {
// 若插入成功,向 $html 变量中追加一段提示信息,告知用户提交成功
$html .= "<p>谢谢参与,阁下的看法我们已经收到!</p>";
} else {
// 若插入失败,向 $html 变量中追加一段提示信息,提示用户提交出现异常,需要重新提交
$html .= "<p>ooo.提交出现异常,请重新提交</p>";
}
}
?>
其中escape为防止SQL注入的过滤函数,并没有对JavaScript进行过滤,如下所示。
3、渗透思路
XSS盲打的核心是向隐蔽输入点注入恶意脚本,利用后台管理功能触发攻击,具体流程如下所示。
三、渗透实战
1、探测是否有过滤
进入到pikachu靶场的XSS盲打关卡,点击右上角的提示,提示了后台登录地址与密码。接下来输入关键字判断是否有过滤,关键字包括:单引号、双引号、左右尖括号、问号、&、字符串与数字,第一个框内输入'"<>?&ljn20241019,第二个框内输入'"<>?&ljn20250502,具体如下图所示。
http://127.0.0.1/pikachu/vul/xss/xssblind/xss_blind.php
点击提交后再次进入留言界面,前端没有输出,当然通过上一步的源码分析我们可以看到数据是被保存到后台数据库中的。根据提示我们猜测留言在管理员端可以看到,接下来我们根据提示进入管理员界面查看输出。
2、管理员端查看输出
进入管理员界面,输入暴力破解关卡获取到的用户名admin和密码123456登录,如下所示。
http://127.0.0.1/pikachu/vul/xss/xssblind/admin_login.php
点击登录后发现之前输入的内容记录在后台,且内容没有被过滤掉,如下所示。
右键-查看元素-查看器中搜索关键字ljn,发现输入的内容,是列表展示是在表格td标签内,没有编码,如下所示。
基于此我们可以判断两个输入框的部分均存在XSS安全风险,可以在输入端注入XSS Payload,然后再管理员端查看注入效果。
3、盲打页面注入Payload
回到盲打页面,对两个输入框都进行测试,具体如下所示。
留言部分注入:<script>alert('1019')</script>
姓名部分注入:<script>alert('ljn')</script>
4、管理员查看攻击效果
登录后台,成功出现弹窗,发现输入的payload触发了两次,说明两个输入框都存在xss注入,在一个输入框内输入即可,具体如下图所示。