Aplikace, které spouštějí skripty ve formátu bat a cmd na platformě Windows pomocí standardních funkcí pro spouštění procesů, jsou náchylné k zranitelnosti, která umožňuje provedení vlastního kódu při předávání argumentů bez speciálního úniku speciálních znaků. Tato zranitelnost byla pojmenována BatBadBut a projevuje se v aplikacích využívajících standardní knihovny jazyků jako Rust, PHP, Node.js, Python, Ruby, Go, Erlang a Haskell.
Problém byl označen jako zranitelnost, protože se dotýká funkcí knihovny, jako jsou Command::arg a Command::args v Rust, které jsou navrženy pro přímé předávání argumentů procesu bez jejich zpracování příkazovým interpretem. Předpokládá se, že vývojář aplikace nemusí kontrolovat argumenty, protože jsou předávány přímo spouštěnému procesu. Zatímco v Unixových systémech jsou argumenty předávány procesu jednotlivě v poli, v systému Windows, při použití API CreateProcess, jsou argumenty formátovány jako jeden řetězec, jehož analýzu provádí spouštěný proces.
Při spuštění skriptů bat a cmd na platformě Windows funkce CreateProcess() implicitně vyžaduje spustitelný soubor cmd.exe, i když ho aplikace při volání nezařazuje. Program cmd.exe obsahuje složitou logiku pro rozdělení argumentů, aby oddělil vlastní argumenty, argumenty spouštěného skriptu a argumenty tohoto skriptu. Aby se zabránilo substituci argumentů na platformě Windows, používají se ve standardních knihovnách programovacích jazyků samostatné zpracovatele pro únik, které lze obejít manipulací s dvojitými uvozovkami.
Například v programu, který vyvolává skript ‘./test.bat’ s argumentem na základě dat získaných od uživatele, může útočník předat hodnotu ‘»&calc.exe’, která se při spuštění skriptu převede na řetězec ‘C:\Windows\System32\cmd.exe /c .\test.bat «»&calc.exe’ a povede k spuštění procesu calc.exe. Tato metoda funguje i při implicitním spuštění skriptů, kdy se spustí spustitelný soubor s názvem „test“ bez uvedení přípony, zatímco v jednom z adresářů zmíněných v proměnné prostředí PATH existuje soubor „test.bat“.
Oprava pro zranitelnost (CVE-2024-24576) byla nyní vydána pro standardní knihovnu jazyka Rust a je součástí aktualizace Rust 1.77.2. Aktualizace zaměřené na odstranění zranitelnosti pro Node.js a PHP jsou ve fázi přípravy (už byly vydány tagy 8.2.18 a 8.3.5, ale verze ještě nebyly oznámeny). Projekty Python, Ruby, Go, Erlang a Haskell zatím omezily své reakce na zveřejnění varování o zranitelnosti v dokumentaci v případě nedostatečného escaped speciálních znaků.
Ve verzi Rust 1.77.2 byla do standardní knihovny přidána dodatečná kontrola, která vrací chybu, pokud argument spouštěného skriptu obsahuje speciální znaky, které nelze bezpečně zaručeně escapeovat. Pro vývojáře, kteří implementují logiku escapeování, je k dispozici metoda CommandExt::raw_arg, která zcela deaktivuje escapeování na úrovni knihovních volání.
Pro přidání ochrany brání skutečnost, že běžné escapeování dvojitých uvozovek nestačí, protože příkazový interpretr zpracovává a rozděluje proměnné jako "%PATH%". Například lze uvozovku vložit prostřednictvím manipulace s proměnnou prostředí "%CMDCMDLINE%", a místo ‚"&calc.exe‘ uvést ‚%CMDCMDLINE:~-1%&calc.exe‘.
Zdroj: opennet.ru
