I am currently auditing a plugin and have the following situation (simplified for example purposes):
<?php
$post_id = false;
$absolute_path = "/var/www/html/wordpress/cache";
$extension = ".min.css";
$filename = $_GET['filename']; // I have complete control over the $filename variable
$absolute_path = $absolute_path . "/{$post_id}/{$filename}-[0-9]*{$extension}";
$files = glob($absolute_path);
foreach($files as $file) {
unlink($file);
}
?>
The point is that I want to leverage this situation to delete arbitrary files on the system, which might lead to remote code execution. The issue is that I control $filename
, but something will be appended later.
glob()
is a function in PHP that uses pattern matching to find files and directories. glob
uses the wildcards of the system.
When you expand the $absolute_path
variable, this is the result:
/var/www/html/wordpress/cache//I-HAVE-CONTROL-OVER-THIS-PART-[0-9]*.min.css
My goal is to get the following result: Have glob()
return the path to wp-config.php
(/var/www/html/wordpress/cache/../../wp-config.php
)
In order to achieve this, I would have to somehow get glob
to "ignore" everything that comes after the part I control or some other bypass. Is there any way to do this?
I already tried debugging glob()
itself but I just don't know any further.
glob
does not usebash
. It is documented as being modeled after libcglob
which is a bit different tobash
in what can be done (at least if no flags are used as in your example). – Steffen Ullrich May 20 '18 at 13:04