Skip to main content

index

Code Execution

Code execution is a vulnerability where an attacker can make a server run arbitrary code of their choice. This often happens when user input is passed to functions that evaluate, interpret, or execute commands or scripts. It typically leads to full system compromise, letting the attacker read, modify, or control everything on the server.

How to Approach

  • Break the syntax using ', ", //, #, or /* */ and look for errors that reveal code evaluation.
  • Identify the language (PHP, Ruby, etc.) by error messages or string behavior (+ vs . for concatenation).
  • Use same-value tests like "." or "./*test*/" to confirm you can safely modify the syntax.
  • Inject code (e.g., PHP: ".system('id');//") and check if the command output appears.
  • Use time-based payloads (e.g., sleep(10)) to detect blind code execution when no output is visible.

Code Execution via usort() + create_function()

usort in PHP or ORDER BY in SQL are used to sort data based on specific rules or criteria, allowing you to control the order in which results are returned or processed.

Some developers sort data using usort() in PHP, often paired with create_function() to dynamically generate a comparison function. When user input is inserted into this dynamic function without proper filtering, PHP uses eval() internally—creating a code injection point.

Because the generated function is wrapped inside { ... }, an attacker can break out of the code by closing the brackets (}) and commenting out the rest (//). By testing variations like });//, attackers can determine the correct syntax, then inject commands such as:

?order=id);}system('uname -a');//

Reference: CVE-2008-4096


Code Execution via preg_replace() /e Modifier

PHP’s old /e modifier in preg_replace() makes the replacement string get evaluated as PHP code, turning user input directly into executable code. If an attacker can control the pattern or replacement with /e, they can inject PHP functions. First, harmless input like hacker triggers a notice, confirming evaluation. Then, replacing it with phpinfo() proves code execution, and finally using system('id') or similar commands gives remote code execution.

http://example.com/?new=phpinfo()&pattern=/rezydev/e&base=Hello%20rezydev
http://example.com/?new=system(%22id%22)&pattern=/rezydev/e&base=Hello%20rezydev

The /e modifier is deprecated since PHP 5.5, but still dangerous in older systems.


Code Execution via assert()

When misused, PHP’s assert() treats its argument as executable PHP code, allowing attackers to inject code. By breaking the syntax with quotes, you can trigger parse errors and confirm evaluation. Then, reconstructing the syntax (e.g., hacker'.') removes errors and enables injecting functions like phpinfo() or system() — for example: hacker'.phpinfo().'. This results in full code execution. Modern PHP (PHP 7+) no longer evaluates strings in assert(), making this exploit ineffective in newer versions.


Code Execution via Ruby eval

Lets say a application builds a Ruby string using eval "\"Hello "+params['username']+"\"", meaning user input is evaluated as Ruby code. By injecting a double quote to break the string, then adding + for concatenation and a backtick command (e.g., `id`), you can execute system commands. The full payload structure is:

" + `id` + " # (with URL-encoded +).

This allows running arbitrary commands, demonstrating how dangerous eval is in Ruby applications.


Code Execution via Python eval

With OS Module

If the application builds a Python expression using user input, so injecting a double quote causes a syntax error—confirming evaluation.

You can close the string using an encoded + and another quote, then verify it’s Python by injecting %2bstr(True)%2b, which successfully evaluates. Once confirmed, place your payload inside str(), such as str(os.system('id')), where a return value of 01 indicates successful command execution.

To capture command outputs, use os.popen('[CMD]').read().

Without OS Module

If the application evaluates user-controlled Python expressions but doesn’t import os, direct calls like os.system('id') will fail. Instead, you can dynamically load the module using __import__('os') and then call system functions, for example: __import__('os').system('id').

With Base64 to Avoid / in Path

If the route /hello/user disallows using / in the input path, so direct commands like cat /etc/passwd cannot be injected.

To bypass this, encode the command in base64 (removing / from the payload) and have the server decode it during injection. Since base64 isn’t imported, load it dynamically using __import__('base64'), then decode and execute with __import__('os').popen(). This allows running commands normally blocked by path restrictions.

/hello/hacker"+str(__import__('os').popen(__import__('base64').b64decode('Y2F0IC9ldGMvcGFzc3dkCg==')).read())+"

Perl CGI Code Injection

  1. Check if the application uses a Perl CGI script, triggered by JavaScript after loading the index page.
  2. Look if User input is passed directly into the Perl script without sanitization, making it vulnerable to code injection.
  3. Injecting single ' or double " quotes helps break the intended command or string, revealing which delimiter the script uses.
  4. Once the delimiter is known, you can inject Perl command execution using backticks `cmd` or functions like system() or exec().

Footnotes

  1. It will show other response if invalid.