macOS Electron Applications Injection
Informações Básicas
Se você não sabe o que é o Electron, você pode encontrar muitas informações aqui. Mas por enquanto, saiba que o Electron roda node. E o node possui alguns parâmetros e variáveis de ambiente que podem ser usados para fazê-lo executar outro código além do arquivo indicado.
Fusíveis do Electron
Essas técnicas serão discutidas a seguir, mas recentemente o Electron adicionou vários sinais de segurança para evitá-las. Estes são os Fusíveis do Electron e estes são os usados para prevenir que aplicações Electron no macOS carreguem código arbitrário:
RunAsNode
: Se desativado, impede o uso da variável de ambienteELECTRON_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 arquivoasar
carregado será validado pelo macOS. Prevenindo desta forma a injeção de código ao modificar o conteúdo deste arquivo.OnlyLoadAppFromAsar
: Se isso estiver ativado, em vez de procurar para carregar na seguinte ordem:app.asar
,app
e finalmentedefault_app.asar
. Ele só verificará e usará app.asar, garantindo assim que quando combinado com o fusívelembeddedAsarIntegrityValidation
seja impossível carregar código não validado.LoadBrowserProcessSpecificV8Snapshot
: Se ativado, o processo do navegador usa o arquivo chamadobrowser_v8_context_snapshot.bin
para seu snapshot V8.
Outro fusível interessante que não impedirá a injeção de código é:
EnableCookieEncryption: Se ativado, o armazenamento de cookies no disco é criptografado usando chaves de criptografia de nível de sistema operacional.
Verificando os Fusíveis do Electron
Você pode verificar essas flags de uma aplicação com:
Modificando os Fuses do Electron
Conforme mencionado na documentação, a configuração dos Fuses do Electron é feita dentro do binário do Electron que contém em algum lugar a string dL7pKGdnNz796PbbjQWNKmHXBZaB9tsX
.
Em aplicações macOS, isso geralmente está em application.app/Contents/Frameworks/Electron Framework.framework/Electron Framework
Poderia 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 hexadecimal (0x30
é 0
e 0x31
é 1
) para modificar os valores dos fusíveis.
Note que se você tentar sobrescrever o binário do Framework Electron dentro de um aplicativo com esses bytes modificados, o aplicativo não será executado.
RCE adicionando código a Aplicações Electron
Pode haver arquivos JS/HTML externos que um Aplicativo 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 Aplicativo, então por padrão isso não é mais possível.O arquivo compilado
asap
geralmente tem os fusíveisembeddedAsarIntegrityValidation
e
onlyLoadAppFromAsar
ativados
Tornando este caminho de ataque mais complicado (ou impossível).
Note que é possível contornar o requisito 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 empacotá-lo de volta após tê-lo modificado com:
RCE com ELECTRON_RUN_AS_NODE
ELECTRON_RUN_AS_NODE
De acordo com a documentação, se essa variável de ambiente for definida, ela iniciará o processo como um processo Node.js normal.
Se o fusível RunAsNode
estiver desativado, a variável de ambiente ELECTRON_RUN_AS_NODE
será ignorada e isso não funcionará.
Injeção a partir do Plist do Aplicativo
Conforme proposto aqui, você poderia abusar dessa variável de ambiente em um plist para manter a persistência:
RCE com NODE_OPTIONS
NODE_OPTIONS
Você pode armazenar o payload em um arquivo diferente e executá-lo:
Se o fusível EnableNodeOptionsEnvironmentVariable
estiver desativado, o aplicativo irá ignorar a variável de ambiente NODE_OPTIONS ao ser iniciado, a menos que a variável de ambiente ELECTRON_RUN_AS_NODE
seja definida, o que também será ignorado se o fusível 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.
Injeção a partir do Plist do Aplicativo
Você poderia abusar dessa variável de ambiente em um plist para manter a persistência adicionando estas chaves:
RCE com inspeção
De acordo com este, se você executar uma aplicação 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, a partir do Chrome em chrome://inspect
) e você será capaz de injetar código nela ou até mesmo iniciar novos processos.
Por exemplo:
Se o fusível EnableNodeCliInspectArguments
estiver desativado, o aplicativo ignorará os parâmetros do node (como --inspect
) ao ser iniciado, a menos que a variável de ambiente ELECTRON_RUN_AS_NODE
seja definida, o que também será ignorado se o fusível RunAsNode
estiver desativado.
No entanto, ainda é possível usar o parâmetro electron --remote-debugging-port=9229
, mas a carga útil 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 (pois eles são descriptografados 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:
No postagem do blog, esse debugging é abusado para fazer um chrome headless baixar arquivos arbitrários em locais arbitrários.
Injeção a partir do Plist do Aplicativo
Você poderia abusar dessa variável de ambiente em um plist para manter a persistência adicionando estas chaves:
Bypass TCC abusando de Versões Antigas
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 nele, pois ainda obterá as permissões do TCC (a menos que o Trust Cache o impeça).
Executar Código não JS
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 do TCC. Portanto, se você deseja abusar das autorizações para acessar a câmera ou o microfone, por exemplo, você pode simplesmente executar outro binário a partir do processo.
Injeção Automática
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:
Referências
Last updated