Learn Pentesting: Manually Testing for OS Command Injection

OS command injection is a critical vulnerability that can allow an attacker to execute arbitrary commands on the host operating system via a vulnerable web application. In this post, we’ll walk through the process of manually testing for OS command injection during web-application penetration tests. We’ll cover common vulnerable patterns, payload crafting, manual testing techniques, and provide practical code examples to aid in your testing efforts.


Understanding OS Command Injection

OS command injection occurs when an application passes unsafe user-supplied data (such as a form parameter or HTTP header) to a system shell. If the input isn’t properly sanitized or validated, attackers may append additional commands to the intended command, allowing them to execute arbitrary system-level commands.

Key Characteristics:


Common Vulnerable Patterns

When reviewing web applications for OS command injection, look for instances where user input is integrated into system commands without proper sanitization or escaping. Common patterns include:


Manual Testing Techniques

Manually testing for OS command injection involves injecting payloads and analyzing the application’s response. Here’s a systematic approach:

1. Identify Injection Points

Review input fields, URL parameters, headers, or cookies that may be used to construct system commands. Common candidates include:

2. Crafting Payloads

Payloads are designed to break out of the intended command and introduce new commands. Common payloads include:

3. Observing Responses

A successful injection may result in:


Practical Code Examples

Below are some sample scripts and HTTP request examples that demonstrate how you might test for OS command injection manually.

Example 1: Testing with Python

Using Python’s requests library, you can craft and send HTTP requests with injection payloads:

import requests

# Target URL of the vulnerable endpoint (replace with the actual target)
url = "http://target-website.com/vulnerable.php"

# Example payload for a Linux-based system
payload_linux = {"ip": "127.0.0.1; id"}

# Send the request and capture the response
response_linux = requests.get(url, params=payload_linux)
print("Linux Injection Test Response:")
print(response_linux.text)

# Example payload for a Windows-based system
payload_windows = {"ip": "127.0.0.1 & whoami"}
response_windows = requests.get(url, params=payload_windows)
print("Windows Injection Test Response:")
print(response_windows.text)

What to Look For:

Example 2: Manual Testing in a Browser or Proxy

If you’re using an intercepting proxy like Burp Suite, you can manually modify parameters:

  1. Intercept a Request:
    Capture a request that sends user-supplied input to the backend.

  2. Modify the Parameter:
    Change the value from a benign input (e.g., 127.0.0.1) to an injection payload (e.g., 127.0.0.1; id).

  3. Analyze the Response:
    Observe if the output includes unexpected command output or error details.

Tips for Reliable Testing:


Escalation & Mitigation Considerations

While this post focuses on detection, it’s important to understand how to mitigate these vulnerabilities.

Mitigation Strategies:

Escalation Testing:


Conclusion & Further Resources

OS command injection remains a potent threat, and manual testing is a fundamental skill in a penetration tester’s toolkit. By understanding the vulnerable patterns, crafting precise payloads, and carefully analyzing responses, testers can uncover and remediate these vulnerabilities before they are exploited maliciously.

Further Reading:

This post is part of our “Learn Pentesting” series at Numorian, where we dive deep into the techniques and tools that every penetration tester should know. Happy testing!

Ready to see how Numorian can help your business?

Contact us today to learn more about our services and how we can support your business.