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

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 that Chihiro 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!