HTB Luke Writeup

writeup for HTB Luke Box




Nmap Scan

We begin our reconnaissance by running an Nmap scan checking default scripts and testing for vulnerabilities.

nmap -sC -sV -oA nmap/tcpInitial -vv
21/tcp   open  ftp     syn-ack ttl 63 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
|      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 4
|      vsFTPd 3.0.3+ (ext.1) - secure, fast, stable
|_End of status
22/tcp   open  ssh?    syn-ack ttl 63
80/tcp   open  http    syn-ack ttl 63 Apache httpd 2.4.38 ((FreeBSD) PHP/7.3.3)
| http-methods: 
|   Supported Methods: GET POST OPTIONS HEAD TRACE
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.38 (FreeBSD) PHP/7.3.3
|_http-title: Luke
3000/tcp open  http    syn-ack ttl 63 Node.js Express framework
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Site doesn't have a title (application/json; charset=utf-8).
8000/tcp open  http    syn-ack ttl 63 Ajenti http control panel
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Ajenti

From the above output it is clear that we have ports 21,22,80,3000 and 8000 giving us a lot of surface to attack so let us recon each of the services running on the found port.

Port 21 FTP

FTP anonymous login is enabled so we can login to the ftp and see the public shares.

ftp connect

We have a single file available to download, we can download this file and see the contents.

ftp file content

The Following message hints that the source code is available to public so we can keep this in mind to look for that while enumerating other services.

Port 80 Web Server

Accessing the web server on firefox reveals nothing interesting as it’s just a template site.

web browser access

We can now run gobuster to see the available directories or some files which are not directly linked on the webpage.

web gobuster

Gobuster reveals a lot of folders and files, analysing each of them one of them stands out config.php accessing this php script outputs a database username and password we should add this to out list of usernames and passwords in case we need to login somewhere in the future.

web config.php

$dbHost = 'localhost';
$dbUsername = 'root';
$dbPassword  = 'Zk6heYCyv6ZE9Xcg';
$db = "login";
$conn = new mysqli($dbHost, $dbUsername, $dbPassword,$db) or die("Connect failed: %s\n". $conn -> error);

Another one of the interesting reveal is the /management/ directory which is basic auth protected and requires password to login.

web config.php

Port 3000 Node.js API

Accessing the Node.js reveals nothing interesting as it requires login, we can use the password found in config.php here.

node api web access

Running the gobuster on this application to see the available endpoints.

node api gobuster

it reveals /login/ and /users/ endpoints as the application requires authentication this seems natural and so we can use /login/ to login to the application.

Port 8000 Ajenti http control panel

This seems like the ultimate goal to access as this is afterall a adminitration service, trying default passwords doesn’t work.

ajenti web access


Port 3000 Node.js API

Loading the requests in burp repeater so that we can manipulate them easily.

Node.js API Login Node.js API Login

let us start with /login/ endpoint by looking up the documentations for the similiar API’s i found the correct request to login to the application i tried to login with root:Zk6heYCyv6ZE9Xcg first but it failed so after some guessing i tried admin:Zk6heYCyv6ZE9Xcg and it worked i was authenticated to the API.

Node.js API Login Node.js API Login

So again looking through the documentation i found the way to pass authentication cookie to the server so that i can access the API.

Node.js API Login Node.js API Login

So now we can access the /users/ endpoint and accessing it reveals a list of users.

Node.js API Login Node.js API Login

Again going through some random documentations found online and using some CTF intituations i guessed that accessing /users/<username> will reveal and some more data about the users and to my surprise it worked and i could get the password for each user.

Node.js API Login Node.js API Login

So using the same technique i dumped all the passwords for all the usernames in a file including the password i found in config.php so that i can use them.

Port 80 Web Server /management/

As i had few usernames and passwords my first try was at basic auth at /management/ as it is the easiest thing to bruteforce with a list of usernames and passwords so fired up hydra and one username and password combo got a hit.

web hydra

so the correct username and password to login to the /management/ was Derry:rZ86wwLvx7jUxtch hence i used this to login to /management/

web management

Here one file seems particularly interesting config.json opening it reveals that it is a config file for Ajenti http control panel and contains root password.

    "users": {
        "root": {
            "configs": {
                "ajenti.plugins.notepad.notepad.Notepad": "{\"bookmarks\": [], \"root\": \"/\"}", 
                "ajenti.plugins.terminal.main.Terminals": "{\"shell\": \"sh -c $SHELL || sh\"}", 
                "ajenti.plugins.elements.ipmap.ElementsIPMapper": "{\"users\": {}}", 
                "ajenti.plugins.munin.client.MuninClient": "{\"username\": \"username\", \"prefix\": \"http://localhost:8080/munin\", \"password\": \"123\"}", 
                "ajenti.plugins.dashboard.dash.Dash": "{\"widgets\": [{\"index\": 0, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.MemoryWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.SwapWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.dashboard.welcome.WelcomeWidget\"}, {\"index\": 0, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.uptime.UptimeWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.power.power.PowerWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.cpu.CPUWidget\"}]}", 
                "ajenti.plugins.elements.shaper.main.Shaper": "{\"rules\": []}", 
                "ajenti.plugins.ajenti_org.main.AjentiOrgReporter": "{\"key\": null}", 
                "ajenti.plugins.logs.main.Logs": "{\"root\": \"/var/log\"}", 
                "ajenti.plugins.mysql.api.MySQLDB": "{\"password\": \"\", \"user\": \"root\", \"hostname\": \"localhost\"}", 
                "": "{\"root\": \"/\"}", 
                "ajenti.plugins.tasks.manager.TaskManager": "{\"task_definitions\": []}", 
                "ajenti.users.UserManager": "{\"sync-provider\": \"\"}", 
                "ajenti.usersync.adsync.ActiveDirectorySyncProvider": "{\"domain\": \"DOMAIN\", \"password\": \"\", \"user\": \"Administrator\", \"base\": \"cn=Users,dc=DOMAIN\", \"address\": \"localhost\"}", 
                "ajenti.plugins.elements.usermgr.ElementsUserManager": "{\"groups\": []}", 
                "ajenti.plugins.elements.projects.main.ElementsProjectManager": "{\"projects\": \"KGxwMQou\\n\"}"
            "password": "KpMasng6S5EtTy9Z", 
            "permissions": []
    "language": "", 
    "bind": {
        "host": "", 
        "port": 8000
    "enable_feedback": true, 
    "ssl": {
        "enable": false, 
        "certificate_path": ""
    "authentication": true, 
    "installation_id": 12354

And so i hopped straight back to ajenti control panel to login.

Port 8000 Ajenti http control panel

I logged in using the username and password root:KpMasng6S5EtTy9Z found in the /management/ and it worked.

Ajenti web panel

So opening a terminal i had root access directly.

Ajenti web panel


This box required a lot of enumeration. It required that we can scan for all the possible files and directories and save all the details and passwords found in the enumeration. This box used a lot of username and passwords we needed to find and use their combination in various wasy to gain access to the system.


A passionate geek who loves to break stuff and then make it again, with interests in cloud infrastructure, network security, reverse engineering, malware analysis and exploit development. Codacker