Luanne — HackTheBox Writeup

Aniket Badami
9 min readMar 27, 2021

This is a practical Walkthrough of “Luanne” machine from HackTheBox. Credit goes to polarbearer for making this machine available to us.

Passwords, hashes and Flags will be redacted to encourage you to solve those challenges on your own.


“Luanne” is marked as easy difficulty machine that features nginx and supervisor to host website and to control process system. The website has basic HTTP authentication enabled, but a certain http directory is wide open to get weather information of UK cities by querying manually. Web application is connected to a lua script which generates random data about city’s weather. Taking advantage of that we execute a lua one-liner to get inital access. We get user’s ssh private keys by querying certain directory using locally running port. Using sudo alternative application “doas”, current user has permission to get root shell if we have password. Upon decryption of encrypted tar file we get the user password and we get the root shell.

Skills Required

  • Web Enumeration
  • Lua Code Injection
  • NetBSD Enumeration

Skills Learned

  • Lua Code Injection
  • NetBsd Enumeration



Initial Nmap scan reveals that SSH (22) and HTTP (80) (9001) running on target. Robots.txt on port 80 has a disallowed entry “/weather”, HTTP basic authentication is enabled on both HTTP ports and target is running NetBSD OS. BTS, I ran directory brute force to find any directories but couldn't able to get any information.


Robots.txt has an entry /weather and they have commented that “it’s returning 404 not found error but still harvesting cities”. Let’s run gobuster on /weather directory.


We got /forecast directory from gobuster. Let’s visit it.


It says to to view all cities in the list use parameter “city=list”, lets try it.


We have list of cities from United Kingdom. Let’s try one of the city.

weather report

We got weather report of “London”, so I cross checked with current weather condition in London and seems like the above data is randomly generated.

Let’s move towards HTTP 9001 port, according to Nmap result the service version is Medusa httpd 1.12 (Supervisor Process Manager). Upon quick search on Google I found that this is a application named “Supervisor”, it is a process control system.

Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems. Read More

So, I searched for “Supervisor” exploit and landed on a metasploit exploit module. It said if the affected version is 3.0a1 to 3.3.2, then authenticated user can run arbitrary shell commands to get the reverse shell. If we access the service then it ask for username and password.


As you can see HTTP Basic Authentication is enabled on 9001 port. The message also says “default”. My guess is, it is using default configuration of “supervisor”. Let’s check its official documentation for any default credentials.

default creds

The official document has a pair of default creds. If we try it now with those credentials then we can able to access the service.

supervisor processes

If we check “processes” then we’d get some crucial information.


As you can see the target is using “Lua” script to display weather information. Other than that we have a information under which user this process in running. Now we have authentication credentials, let’s try Metasploit exploit.


Okay, we didn't get the reverse shell. My guess is, the running version might be not vulnerable, or the fact that we are using linux payload/exploit and the target is NetBSD OS. We will confirm once we get the shell.

Initial Access

Alright, so far we only got new information is that target is using “Lua” scripts for weather report and it is taking input from client side. So we can try to perform code injection via “city=” parameter.

We have to combine two things before we create our payload. First is, we need lua shell command, we can use os.execute(“cmd”) from gtfobins. Second we need NetBSD netcat on-liner (cmd), we can get from PayloadAllThings. Now we need to modify IP:PORT accordingly and create a combined payload. Also we need to encode in URL format, you can use burp suite to do that.

encoded payload

Setup a netcat listener to get reverse shell.

netcat listener

Now we are all set to execute the encoded url payload via ‘city=’ parameter.

execute url

Aight, *hacker voice* we are in. Its not a user account, its service account, now we need get user shell.

As I said earlier that the HTTP service is using Basic HTTP Authentication, for that to work there has to be “.htpasswd” file on server. Most of the time it’s in same location as index.html. We already have the authentication of HTTP 9000 port, we can grab the HTTP 80 password from default location of our current shell.


The password is stored in hash format. We need to identify the hashing algorithm.

hash algo

It’s a ‘MD5 Crypt’ hash and we can crack the hash with hashcat application.

crack hash

We go the password, now let’s visit the webpage and input the credentials.


There is nothing interesting on that web page.

Privilege Escalation — User

Let’s run LinPeas and gather information on local host.

port 3000

Our initial Nmap scan didn’t show port 3001 in the result. Probably it’s only for internal use. ‘httpd’ is being used for HTTP service with different flags. Let’s look into what those flags means. From its man page;

-u — Enables the transformation of Uniform Resource Locators of the
form /~user/ into the directory ~user/public_html
-X — Enables directory indexing. A directory index will be gener-
ated only when the default file (i.e. index.html normally) is
not present.
-s — Forces logging to be set to stderr always
-i — Causes address to use used as the address to bind daemon mode.
-I — Causes httpd to use port instead of the default “http” port.
-L — Adds a new Lua script for a particular prefix.
-P — Causes bozohttpd to create a PID file in pidfile when run in
daemon mode with the -b option.
-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

So, the above flags are being used.

Binded to loopback address and port (3001), users home directory (r.michaels) is being served as “public_html” and running as background service.

Let’s curl the localhost and port.

curl localhost port

Unauthorized access. We have the credentials of webapi user, let’s use them.

curl with creds

Default page.

If we look at the -u flag from “httpd”, we can look for any files/directories inside the /~user/ (/~r.michaels/) and -X is being used so there is a possibility of directory listing.

curl public_html

There’s a id_rsa (ssh private key) in the directory. We can read it via curl.


Copy the key to Kali Linux, change the permission of file and ssh into that.

user shell
user flag

Privilege Escalation — root

If we run LinPeas from current user, then we’d see that we have permission to run ‘doas’ as root.

The ‘doas’ program acts as an alternative to sudo in NetBSD OS.

doas conf

But to run ‘doas’ program we need current users password. There’s a backup directory in current user folder, which has an encrypted tar file.


Let’s check the for GPG files in local user home directory.


Okay, we have public key and private key for GPG, so we don’t need to brute force to get the data.

As this is an NetBSD OS, we can use ‘netpgp’ application to decrypt it.


We don’t have permission to write anything current user home directory, so we have to dump this in /tmp directory.

Backup directory has a user hash. It’s different from the previous one. Let’s crack it the same way.

Note: there’s a cleanup job is running for /tmp directory every 3 minute. So, make sure to do everything in that time.

crack hash

We go the password. Now we can try this with ‘doas’ application to get root shell.

root shell and flag

We got all the flags required to complete this machine.


I was wondering why didn't msf exploit work. So I checked the running version and it’s “3.8”. That msf exploit only works on version 3.0a1 to 3.3.2.

supervisor version

When I uploaded bash scripts to enumerate localhost to /tmp they all vanished and it happened same with encrypted tar.gz file. So, I looked into root directory and found script.

As you can see this script is finding and removing decrypted tar.gz file, it’s directory and everything which is in /tmp directory too.

So I looked into crontab and found that this script is getting executed every minute by root, check the last entry.


Thank you for reading this blog. While attempting this challenge I learned so many things. This was unique target with unique vulnerability.