HTB - Luke
This post is a write-up for the Luke box on hackthebox.eu
Enumeration
Start enumerating the ports on the victim machine by running Nmap
and Masscan
:
Initial recon results in the following information:
- Port 21
- FTP server which allows anonymous login
- Port 22
- SSH server
- Port 80
- HTTP server running PHP (Apache/2.4.38 (FreeBSD) PHP/7.3.3)
- Port 3000
- Node.js Express server likely running a JSON Rest API (application/json; charset=utf-8)
- Port 8000
- HTTP Control Panel called
Ajenti
- HTTP Control Panel called
Check out the FTP Server:
From the FTP server, locate a file called for_Chihiro.txt
.
Thinking about the file, I made a few assumptions:
- Obviously, a Junior Web Developmer - Chihiro
- Someone who is advising him -
Derry
- The web page is likely using a standard framework;
Derry
says thatChihiro
should “know where to look”.
Browsing to the victim machine on port 80 results in a Single Page App (SPA) with a standard template. The page indicates that it uses Bootstrap 4
. Look at the source of the page and notice that the third party sources are in the vendor
directory, while the standard are in css
and js
. This is pretty standard practice in web development. Open the source of css
, and notice a reference to Blackrock Digital’s Start Bootstrap Theme Framework
.
Open the URL referenced in the CSS file and see the directory structure, notice files like LICENSE
and README.md
. Standard practice in framework development. You can confirm this by trying to access them on the victim machine, and as suspected, the files are still available.
After identifying the framework being used, there is nothing too interesting that you can take advantage of. Try running Gobuster
and specify the file type php
to see if there is anything interesting:
From the Gobuster
scan, there are a couple of interesting files and directories.
login.php
member
management
- Password protected directory, returning a 401
config.php
Opening login.php
results in a pretty basic login page, but no credentials have been found yet. The member directory is empty. As suspected, the management directory is password protected, so no access there. config.php
has some pretty basic PHP that connects to a mysql database with the password for root.
Trying these credentials in both the login.php
form and the management page results in 403s, so keep these credentials for later use.
Try to access the server on port 3000. The first thing you see is that this is some form of JSON REST api as it returns a JSON object saying that must be authenticated:
A quick Google search of the returned message results in a post about how to add JSON Web Tokens to a Node.js site. The post indicates that you should login, get a Bearer token, and send it every time you send a request to the victim machine. Enumerate the victim machine using Gobuster
to see if you can find any available endpoint targets. Ideally, one that accepts credentials.
The 2nd Gobuster
scan finds 4 endpoints:
/login
/users
/Login
/Users
The last 2 are just used to allow non-case sensitive queries. Send the credentials you have to this login page and see what happens. Because I love Python so much, I whipped up a script to automate this:
import requests
creds = { "username": "admin", "password": "Zk6heYCyv6ZE9Xcg" }
resp = requests.post("http://10.10.10.137:3000/login", json=creds)
print(resp.json())
Running the script should result in a successful authentication. Note that the credentials we used are from the file config.php we found earlier, but the user has been changed from root to admin. Modify the script to send the token received to the home page. Format the token as described in the earlier post as follows:
#...
token = resp.json()["token"]
headers = { "authorization": "Bearer " + token }
resp = requests.get("http://10.10.10.137:3000/", headers=headers)
print(resp.json())
After successfully authenticating with the token, use it on the /users
endpoint for further enumeration. Modify the Python script again:
#...
import pprint
pp = pprint.PrettyPrinter()
resp = requests.get("http://10.10.10.137:3000/users", headers=headers)
pp.pprint(resp.json())
A list of users! In REST Apis, you can get more detailed information about a resource by accessing the resource id (/resource/:id
). On the victim machine, the resource is users and the usernames or their ids would be the resource id. If you want to access more information about admin
, access either /users/admin
or /users/1
. Try modifying the Python script to test this theory out:
#...
users = resp.json()
for user in users:
resp = requests.get("http://10.10.10.137:3000/users/" + user["name"], headers=headers)
print(resp.json())
The /users/:username
endpoint spits out the password for each of the user. Profit! Try using these credentials on some of the login pages you found earlier. None of the passwords work on /login.php
. Derry
(the same user who wrote the letter to Chihiro) works on the /management
page and spits out another directory listing.
Results of the 2nd directory listing:
config.json
config.php
login.php
Take a quick look at config.php
and login.php
. These files are the same that were found in the root directory. config.json
has a JSON config file for Ajenti
which is an interesting find. Ajenti
is the HTTP Control Panel that was found during the Nmap scan. Important items from this config are the username (root), it's password, and bind port 8000. So this clearly matches the Ajenti HTTP Control Panel
found earlier:
Getting user.txt and root.txt flags
Take these credentials and try them on the Ajenti HTTP Control Panel
. Successful login!
On the Ajenti HTTP Control Panel
, launch a terminal and find out that this victim machine is lacking a lot of IAM controls. Grab user and root flags without any escalation. Look Mom, I'm a hacker!