BatBadBut vulnerability affecting standard libraries of various programming languages

Father

Professional
Messages
2,601
Reputation
4
Reaction score
633
Points
113
Applications that run scripts in bat and cmd format on the Windows platform using standard process startup functions are vulnerable to a vulnerability that allows their code to be executed if arguments are passed at startup without separate escape of special characters. The vulnerability is codenamed BatBadBut and is found in applications that use standard libraries of languages such as Rust, PHP, and Node.js, Python, Ruby, Go, Erlang, and Haskell.

The issue is marked as a vulnerability because it affects library functions such as Command:: arg and Command::args in Rust, which are designed to pass arguments directly to the process without being processed by the command interpreter. This means that the application developer may not check the arguments, since they are passed directly to the running process. If on Unix systems arguments are passed to the process separately in an array, then on Windows, when using the CreateProcess API, arguments are formatted as a single string, which is parsed by the running process.

When running bat and cmd scripts on Windows, the CreateProcess() function implicitly invokes the cmd executable.exe, even if the application doesn't specify it when calling it. The cmd program.the exe contains its own complex argument separation logic to separate its own arguments, the script being run, and the arguments of this script. To protect against argument substitution on the Windows platform, the standard libraries of programming languages use separate escape handlers, which, as it turned out, can be circumvented by manipulating double quotes.

For example, in a program that calls the script '. / test.bat 'with an argument based on the data received from the user, the attacker can pass the value '"&calc.exe', which will be expanded to the string when the script runs C:\Windows\System32\cmd.exe /c .\test.bat ""&calc.exe"' and will start the process calc.exe. This method also works when scripts are run implicitly, when an executable file named "test" is run without specifying an extension, and the file "test.bat"is present in one of the directories mentioned in the PATH environment variable.

Currently, the fix has already been released (CVE-2024-24576) for the Rust standard library and is included in the Rust 1.77 update.2. Updates to fix the vulnerability for Node are in the process of being prepared.js and PHP (the 8.2.18 and 8.3.5 tags are already set, but no releases have been announced yet). Python, Ruby, Go, Erlang, and Haskell projects have so far limited themselves to introducing a warning about vulnerability in the documentation if special characters are not properly escaped.

In Rust 1.77.2, an additional check was added to the standard library, which returns an error if there are special characters in the argument of the script being run that cannot be safely escaped. For developers who implement the escape logic themselves, the CommandExt::raw_arg method is provided, which completely disables escaping on the library call side.

Adding protection is hindered by the fact that simply escaping double quotes is not enough, since the command interpreter processes and exposes variables such as"%PATH%". For example, you can substitute a quotation mark by manipulating the environment variable "%CMDCMDLINE% "by specifying instead of '"&calc.exe' - '%CMDCMDLINE:~-1%&calc.exe'.
 
Top