Post

Exploiting SSRF and Command Injection Vulnerabilities in Python-Based Web Applications

Service Exposure and SSRF Vulnerabilities Server-Side Request Forgery (SSRF) is a critical vulnerability that allows an attacker to manipulate a server into making requests to internal or even external services on behalf of the server itself. This flaw typically occurs in applications that accept user inputs and use them to make HTTP requests without proper validation or sanitization. In a typical SSRF scenario, a data input or file upload form allows users to submit a URL to be processed by the server. However, if the server does not adequately filter the input, an attacker can exploit this functionality to make unauthorized requests to internal services that would otherwise be inaccessible. This is particularly dangerous when the server has access to internal networks or sensitive services, such as internal APIs or administrative applications.

A classic example of SSRF exploitation involves manipulating a URL input to redirect the server’s request to a local or protected service. By sending a malicious request like:

1
http://127.0.0.1:5000/api/internal/resources

the attacker forces the server to request a local service on port 5000, which would typically be inaccessible from outside. If the response from this service contains sensitive information or grants access to administrative functionality, the attacker can use it to further the attack.

During SSRF exploitation, attackers often attempt to enumerate internal services and ports. Discovering services running on ports like 5000, 8080, or 3306 (commonly used by web frameworks and databases) allows the attacker to interact with these services and gather critical information.

This vulnerability becomes especially dangerous when combined with poorly configured internal services, such as APIs or applications that do not require authentication for sensitive endpoints.


Exploitation of Internal Services and Exposure of Git Repositories

After exploiting the SSRF vulnerability, the attacker proceeds to discover internal services running within the network. By manipulating crafted requests, the attacker interacts with ports and services that are only internally exposed, such as a web application on a specific port. This type of access reveals important information, such as software versions, frameworks in use, and even internal APIs that do not require authentication.

In scenarios like this, it is common to find exposed Git repositories. When code repositories are left in public or accessible directories, they can be exploited to obtain sensitive information. The commit history, for example, may contain credentials, API keys, or details about the system’s infrastructure.

Exploring a Git repository can be done with simple commands like:

1
git log

This command allows viewing the history of changes, revealing modifications to the code or sensitive files that were added or removed. Additionally, using tools to recover deleted files or view old commits can provide further information aiding privilege escalation.

In cases of improper configuration or rushed development, repositories may contain exposed credentials that grant access to other internal services, such as databases or production servers. This creates an exploitation chain that can eventually lead to full system control.


###Command Injection in Python Scripts with Elevated Privileges The next stage of the exploitation involves abusing a critical vulnerability in a Python script running with elevated privileges. This type of vulnerability occurs when a script executed with administrative permissions (such as root) accepts external input without proper validation, allowing arbitrary command execution.

The vulnerable script in question is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python3

import os
import sys
from git import Repo

os.chdir('/opt/internal_apps/clone_changes')

url_to_clone = sys.argv[1]

r = Repo.init('', bare=True)
r.clone_from(url_to_clone, 'new_changes', multi_options=["-c protocol.ext.allow=always"])

In this script, the argument url_to_clone is passed directly from the command line without any validation, making it vulnerable to command injection. Since the script runs with root privileges, an attacker can exploit this flaw to execute arbitrary commands. An example of how this injection can be exploited:

1
sudo python3 vulnerable_script.py "ext::sh -c 'touch /tmp/pwned'"

In this case, the attacker injects a malicious command in place of the URL, causing a shell command to be executed instead of the expected operation. This allows the attacker to perform arbitrary actions, such as changing file permissions or even gaining root access.

Once the attacker gains access to the script running with root privileges, they can use the vulnerability to escalate privileges by setting a SUID binary or modifying critical system permissions. This technique is particularly effective in environments where scripts are used to automate administrative tasks but lack proper parameter validation.

This type of vulnerability underscores the importance of rigorous input validation in scripts with elevated privileges and ensuring that external command execution is restricted and properly monitored.

This post is licensed under CC BY 4.0 by the author.