Ghost Whisper
Monthly Challenge - 46

Description
An OS command-injection vulnerability exists in the web application's message-processing workflow. Due to incorrect input handling and the order of text transformations, certain Unicode characters (for example, "smart" or fullwidth quotes) can be converted into ordinary shell metacharacters just before the application runs a system command. An attacker can exploit this vulnerability to execute arbitrary shell commands within the web process, potentially leading to the disclosure of sensitive data (including environment variables and flags), full container/process compromise, and service disruption.
Exploitation
To identify potential vulnerabilities within an application, analysing the source code is an effective approach as it reveals insecure coding practices, such as improper input validation or the misuse of certain libraries. In this scenario, we are presented with a web application that accepts user input, which is then parsed by the program, potentially influencing the contents returned to the user.
Vulnerable Code Analysis
The application constructs a shell pipeline using untrusted input inside a single-quoted shell literal:
Before that, it attempts to sanitize ASCII single quotes with:
Because the code calls replace("'", "_") before Unicode normalization, visually-similar Unicode quote characters (for example, U+FF07 Fullwidth Apostrophe) are not replaced and are converted by NFKC into ASCII apostrophes. This allows an attacker to inject ' (U+FF07)characters that become ASCII "'" after normalization, closing the single-quoted literal and enabling arbitrary shell injection.
Root cause
Order-of-operations bug: input sanitation replace("'", "_") occurs before Unicode canonicalization (NFKC). Unicode characters that normalize to ASCII single quote are not sanitized and can be converted into a dangerous character after sanitization. Additionally, the use of os.popen/shell interpolation with unsanitized user input permits shell metacharacter interpretation.
PoC
A payload containing full-width quotes is URL-encoded and sent as the message. After decoding and normalization, those characters become ordinary single quotes ('), which closes the intended quoted string in the constructed shell command and allows injection of commands. The output is then returned in the web response.

As the response contains the process user (the ID output), this PoC conclusively demonstrates that injected shell commands were executed in the web process.
The objective to prove the vulnerability was to get the content of the environment variable that had been set as follow :
A command to print the variable has been used. Here is the poc code :
Risk
This vulnerability enables unauthenticated remote command execution in the web process with trivial, low-effort payloads. Likelihood of exploitation: high.
Impact: full container/process compromise, disclosure of secrets (env vars, files), service disruption, and potential lateral movement if host isolation is weak.
Business consequences include data loss, regulatory exposure, service outage, and reputational damage.
Remediation
Replace
os.popen()withsubprocess.run()or an equivalent function that does not invoke a shell. Pass user input as data (stdin or arguments).Apply Unicode normalization before any replacement or sanitization, so no dangerous characters are reintroduced after cleaning.
Accept only expected characters (letters, numbers, limited punctuation). Reject or escape all others. Implement a strict allowlist policy for user inputs.
Reference
Last updated