macOS Electron Applications Injection
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Se você não sabe o que é Electron, pode encontrar muitas informações aqui. Mas por enquanto, saiba apenas que o Electron executa node. E o node tem alguns parâmetros e variáveis de ambiente que podem ser usados para fazer com que ele execute outro código além do arquivo indicado.
Essas técnicas serão discutidas a seguir, mas nos últimos tempos o Electron adicionou várias flags de segurança para preveni-las. Estas são as Electron Fuses e estas são as usadas para prevenir que aplicativos Electron no macOS carreguem código arbitrário:
RunAsNode
: Se desativado, impede o uso da variável de ambiente ELECTRON_RUN_AS_NODE
para injetar código.
EnableNodeCliInspectArguments
: Se desativado, parâmetros como --inspect
, --inspect-brk
não serão respeitados. Evitando assim a injeção de código.
EnableEmbeddedAsarIntegrityValidation
: Se ativado, o arquivo asar
carregado será validado pelo macOS. Prevenindo assim a injeção de código ao modificar o conteúdo deste arquivo.
OnlyLoadAppFromAsar
: Se isso estiver ativado, em vez de procurar carregar na seguinte ordem: app.asar
, app
e finalmente default_app.asar
. Ele apenas verificará e usará app.asar, garantindo assim que quando combinado com a fuse embeddedAsarIntegrityValidation
é impossível carregar código não validado.
LoadBrowserProcessSpecificV8Snapshot
: Se ativado, o processo do navegador usa o arquivo chamado browser_v8_context_snapshot.bin
para seu snapshot V8.
Outra fuse interessante que não estará prevenindo a injeção de código é:
EnableCookieEncryption: Se ativado, o armazenamento de cookies no disco é criptografado usando chaves de criptografia em nível de SO.
Você pode verificar essas flags de um aplicativo com:
Como os docs mencionam, a configuração dos Fuses do Electron é configurada dentro do binário do Electron, que contém em algum lugar a string dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
.
Em aplicações macOS, isso está tipicamente em application.app/Contents/Frameworks/Electron Framework.framework/Electron Framework
Você pode carregar este arquivo em https://hexed.it/ e procurar pela string anterior. Após esta string, você pode ver em ASCII um número "0" ou "1" indicando se cada fusível está desativado ou ativado. Basta modificar o código hex (0x30
é 0
e 0x31
é 1
) para modificar os valores dos fusíveis.
Note que se você tentar sobrescrever o binário do Electron Framework
dentro de um aplicativo com esses bytes modificados, o aplicativo não funcionará.
Pode haver arquivos JS/HTML externos que um App Electron está usando, então um atacante poderia injetar código nesses arquivos cuja assinatura não será verificada e executar código arbitrário no contexto do aplicativo.
No entanto, no momento, existem 2 limitações:
A permissão kTCCServiceSystemPolicyAppBundles
é necessária para modificar um App, então, por padrão, isso não é mais possível.
O arquivo compilado asap
geralmente tem os fusíveis embeddedAsarIntegrityValidation
e
onlyLoadAppFromAsar
ativados
Tornando este caminho de ataque mais complicado (ou impossível).
Note que é possível contornar a exigência de kTCCServiceSystemPolicyAppBundles
copiando o aplicativo para outro diretório (como /tmp
), renomeando a pasta app.app/Contents
para app.app/NotCon
, modificando o arquivo asar com seu código malicioso, renomeando-o de volta para app.app/Contents
e executando-o.
Você pode descompactar o código do arquivo asar com:
E empacote-o novamente após tê-lo modificado com:
ELECTRON_RUN_AS_NODE
De acordo com a documentação, se essa variável de ambiente estiver definida, ela iniciará o processo como um processo normal do Node.js.
Se o fuse RunAsNode
estiver desativado, a variável de ambiente ELECTRON_RUN_AS_NODE
será ignorada, e isso não funcionará.
Como proposto aqui, você pode abusar dessa variável de ambiente em um plist para manter a persistência:
NODE_OPTIONS
Você pode armazenar a carga útil em um arquivo diferente e executá-la:
Se o fuse EnableNodeOptionsEnvironmentVariable
estiver desativado, o aplicativo ignorará a variável de ambiente NODE_OPTIONS ao ser iniciado, a menos que a variável de ambiente ELECTRON_RUN_AS_NODE
esteja definida, que também será ignorada se o fuse RunAsNode
estiver desativado.
Se você não definir ELECTRON_RUN_AS_NODE
, você encontrará o erro: Most NODE_OPTIONs are not supported in packaged apps. See documentation for more details.
Você poderia abusar dessa variável de ambiente em um plist para manter a persistência adicionando essas chaves:
De acordo com este, se você executar um aplicativo Electron com flags como --inspect
, --inspect-brk
e --remote-debugging-port
, uma porta de depuração será aberta para que você possa se conectar a ela (por exemplo, do Chrome em chrome://inspect
) e você poderá injetar código nela ou até mesmo iniciar novos processos.
Por exemplo:
Se o fuse EnableNodeCliInspectArguments
estiver desativado, o aplicativo ignora os parâmetros do node (como --inspect
) quando iniciado, a menos que a variável de ambiente ELECTRON_RUN_AS_NODE
esteja definida, que também será ignorada se o fuse RunAsNode
estiver desativado.
No entanto, você ainda pode usar o parâmetro electron --remote-debugging-port=9229
, mas o payload anterior não funcionará para executar outros processos.
Usando o parâmetro --remote-debugging-port=9222
, é possível roubar algumas informações do aplicativo Electron, como o histórico (com comandos GET) ou os cookies do navegador (já que eles são decriptados dentro do navegador e há um endpoint json que os fornecerá).
Você pode aprender como fazer isso aqui e aqui e usar a ferramenta automática WhiteChocolateMacademiaNut ou um script simples como:
Em este post do blog, esse depurador é abusado para fazer um chrome headless baixar arquivos arbitrários em locais arbitrários.
Você poderia abusar dessa variável de ambiente em um plist para manter a persistência adicionando essas chaves:
O daemon TCC do macOS não verifica a versão executada do aplicativo. Portanto, se você não conseguir injetar código em um aplicativo Electron com nenhuma das técnicas anteriores, você pode baixar uma versão anterior do APP e injetar código nela, pois ainda obterá as permissões do TCC (a menos que o Trust Cache impeça).
As técnicas anteriores permitirão que você execute código JS dentro do processo do aplicativo electron. No entanto, lembre-se de que os processos filhos são executados sob o mesmo perfil de sandbox que o aplicativo pai e herdam suas permissões TCC. Portanto, se você quiser abusar de direitos para acessar a câmera ou o microfone, por exemplo, você pode simplesmente executar outro binário a partir do processo.
A ferramenta electroniz3r pode ser facilmente usada para encontrar aplicativos electron vulneráveis instalados e injetar código neles. Esta ferramenta tentará usar a técnica --inspect
:
Você precisa compilá-la você mesmo e pode usá-la assim:
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)