HTB | Mirage

Machine - https://app.hackthebox.com/machines/Miragearrow-up-right

IP - 10.129.248.59

NMAP

└─$ nmap -sS -p- --min-rate 10000 10.129.248.59 -Pn -oA nmap_ports
Starting Nmap 7.95 ( <https://nmap.org> ) at 2025-07-21 17:08 IST
Warning: 10.129.248.59 giving up on port because retransmission cap hit (10).
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
RTTVAR has grown to over 2.3 seconds, decreasing to 2.0
Nmap scan report for 10.129.248.59
Host is up (0.66s latency).
Not shown: 35568 closed tcp ports (reset), 29941 filtered tcp ports (no-response)
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
111/tcp   open  rpcbind
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
2049/tcp  open  nfs
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
4222/tcp  open  vrml-multi-use
5985/tcp  open  wsman
9389/tcp  open  adws
47001/tcp open  winrm
49666/tcp open  unknown
49667/tcp open  unknown
49669/tcp open  unknown
50586/tcp open  unknown
56754/tcp open  unknown
56768/tcp open  unknown
64708/tcp open  unknown
64717/tcp open  unknown
64733/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 79.77 seconds

Port 2049

Let’s see the mount

Foothold/ shell

Shell as nathan.aadam

mounting the share

We can see a MirageReports share available for everyone. Let's mount it and take a look inside.

We can see two pdfs

Analysing PDF

Let's first take a look at the Incident Report Missing DNS Record nats-svc

On May 3, 2025, the Development team reported they were unable to resolve the hostname nats-svc.mirage.htb. This hostname is critical for internal service communication with the NATS messaging system hosted on the Mirage domain.

Another interesting finding in this report is that Dynamic Updates for the mirage.htb zone is set to Nonsecure and secure which means that we should be able to make dns changes without any authentication.

Next let's take a look at Mirage Authentication Hardening Report

This report outlines the phased deprecation of NTLM authentication within the Mirage Active Directory environment. NTLM is a legacy authentication protocol that lacks modern security features and is vulnerable to several attacks, including credential relaying and pass-the-hash. To align with current security best practices, Mirage is moving toward a Kerberos-only authentication model. The transition is designed to be gradual and well-monitored to avoid service disruption and ensure all systems are compliant.

Hijacking nats-svc.mirage.htb via Dynamic DNS Update

What is NATS?

NATS (pronounced “gnats”) is a high-performance messaging system — basically, it's a message broker that allows different services to communicate via publish-subscribe messaging.

Key concepts

Concept
Meaning

Client

An app or service that connects to NATS to send or receive messages.

Server

The central broker that routes all messages.

Subject

A topic string, like "alerts.critical" or "users.login".

Publish

A client sends a message to a subject.

Subscribe

A client listens for messages on a subject (like a channel).

JetStream

NATS's persistent storage feature — kind of like a message queue with history, replay, etc.

Think of NATS like a lightweight, turbo-fast post office inside a network:

  • Apps "drop" letters into named mailboxes (subjects)

  • Other apps are "subscribed" to those mailboxes and receive the letters in real time

  • NATS ensures delivery happens quickly and efficiently

  • With JetStream, NATS can even store the letters for later

EXPLOIT

We are going to exploit a misconfigured DNS server that allowed nonsecure dynamic updates for the mirage.htb domain. This will allow us to hijack the hostname nats-svc.mirage.htb and point it to our machine, where we ran a fake NATS server.

As a result, an internal service connected to our fake NATS server and sent credentials in a CONNECT message.

But before that we need to get the server_id, server_name, version, etc.

We started a listener on port 4222 (default NATS port):

  • This sends a fake INFO banner (expected by NATS clients).

  • We're using Netcat (nc) to passively accept connections and reply.

Hijack nats-svc.mirage.htb via Dynamic DNS

This sends a DNS dynamic update, making nats-svc.mirage.htb resolve to our IP (10.10.16.7) instead of the real NATS server.

⚠️ Requires that the DNS server allows "nonsecure and secure" dynamic updates (as stated in the incident report).

After a short wait, we received this on our listener:

Now we have Dev_account_A ccredentials

AD Access

Attempting to use these against the AD environment doesn't grant authentication. Since these were credentials we got from nats Let's try to authenticate through that

We will use natcliarrow-up-right to connect to the NAT server via Dev_account_A

Let’s take a look t our streams

Let’s take a look at the auth_logs

We have a new set of credentials! david.jjackson:pN8kQmn6b86!1234@

Let's check if we're able to authenticate to AD through ldap.

need to forge ticket

Bloodhound

Since we have valid cred we can use bloodhound-python

IT_ADMINS@MIRAGE.HTB -> MemberOf -> REMOTE MANAGEMENT USERS@MIRAGE.HTB

and NATHAN.AADAM@MIRAGE.HTB -> MemberOf -> IT_ADMINS@MIRAGE.HTB

Kerberaosting

NATHAN.AADAM@MIRAGE.HTB has its SPN set as HTTP/exchange.mirage.htb

Therefore, we can try a kerberoasting attack

We got the hash, we can try to crack it via hashcat

Now we have Nathan’s cred

and we have user.txt

Privilege Escalation

Authenticate as Mark.Bbond

First, we need to upgrade our evil-winrm session to an interactive session. This way, we'll obtain more enumeration capabilities:

We can see in our groups we now are in NT AUTHORITY\\INTERACTIVE, granting us with more enumeration capabilities. Let's see if another account is connected to the box:

We can see mark.bbond is connected to the box with session ID 1. We can use an universal no fix exploit allowing to retrieve the NTLMv2 response of this user called RemotePotato0.exe:

Now we have the mark.bbond hash we can crack it via hashcat

Why this worked (chatgpt)

This was privilege escalation via NTLM relay using RemotePotato0, targeting a user who is actively logged in to the system (mark.bbond). Here's why it worked and how the pieces fit together technically:

Why This Worked: High-Level Overview

We exploited the COM infrastructure and NTLM authentication behavior of Windows to force an already-logged-in privileged user (mark.bbond) to authenticate to a fake RPC server we controlled — and then captured the NTLMv2 response.

This is possible because:

  • We had enough local privileges (as nathan.aadam) to spawn a COM object in another user’s session.

  • That COM object used NTLM authentication when connecting to resources.

  • We redirected RPC traffic (port 135) using socat, so authentication flowed to our fake listener, not the real one.

  • RemotePotato0 relayed the authentication to your listener and captured the NTLMv2 hash.

Detailed Breakdown: Step-by-Step

  1. We got a better shell via runasc.exe

    We used runasc.exe to impersonate user nathan.aadam interactively:

    • This opened a new interactive PowerShell reverse shell to our attacker box (10.10.16.11:1234).

    • The new shell had NT AUTHORITY\\INTERACTIVE, allowing access to more desktop and session-related features (like COM object spawning into other sessions).

  2. We found a privileged user logged in

    Using qwinsta:

    We saw:

    Meaning mark.bbond is actively logged in with session ID 1. This is crucial — RemotePotato0 needs a target user session to spawn a COM object into

  3. We ran RemotePotato0 to force NTLM authentication

    This:

    • Uses mode 2 (DCOM-based coercion)

    • Uses server mode 1 (your fake RPC/HTTP relay server)

    • Sends NTLM authentication to your attack box (-x 10.10.16.11)

  4. We used socat to forward port 135 to our fake RPC listener

    On our attacker box:

    This:

    • Listens on port 135 locally

    • Redirects any DCOM traffic to port 9999 on the target box (our victim)

    • Enables RemotePotato0 to intercept and handle RPC/COM calls (ResolveOxid2)

  5. RemotePotato0 impersonated mark.bbond using COM

    It:

    • Used StandardGetInstanceFromIStorage to spawn a COM object inside session 1 (mark.bbond)

    • That object tried to authenticate via NTLM to a remote resource — our listener at port 135 (really redirected to our port 9999)

    • We captured the NTLMv2 challenge-response hash

    We saw:

How It Works Technically (RPC + COM + NTLM)

  1. COM Activation: Windows allows you to activate COM objects in other user sessions under certain conditions (like being interactive).

  2. NTLM Authentication: When the COM object is initialized, it may attempt to authenticate over RPC using the context of the user it runs as (mark.bbond).

  3. ResolveOxid2 Call: This call is made over DCOM (port 135), and authentication occurs via NTLM challenge-response.

  4. NTLM Relay: You redirected this call to a controlled service that sniffed and captured the NTLMv2 hash — a credential you can now crack or relay.

Authenticate as Javier.Mmarshall

Going back to bloodhound

MARK.BBOND@MIRAGE.HTB -> MemberOf -> IT_SUPPORT@MIRAGE

IT_SUPPORT@MIRAGE -> ForceChangePassword ->JAVIER.MMARSHALL@MIRAGE.HTB

ForceChangePassword

But it gives KDC_ERR_CLIENT_REVOKED

meaning

  • The user account is disabled.

  • The account is locked out due to too many login attempts.

  • The account is expired or otherwise marked as invalid for Kerberos login.

Let’s check if the account is disable or not

Let’s remove this property

Still getting KDC_ERR_CLIENT_REVOKED

If logonHours is set and you're trying to authenticate outside the permitted window, Kerberos and NTLM authentication will fail, potentially with the error:

❌ KDC_ERR_CLIENT_REVOKED

Even though the user’s password is correct and the account is active.

This means the logonHours attribute is empty, which in Active Directory means:

🔒 User is not allowed to log on at any time.

Let’s remove it

Now we can authenticate

Authenticate as Mirage-Service$

Onto Bloodhound again

JAVIER.MMARSHALL@MIRAGE.HTB -> MemberOf -> IT_CONTRACTORS@MIRAGE.HTB

IT_CONTRACTORS@MIRAGE.HTB -> ReadGMSAPassword -> MIRAGE-SERVICE$MIRAGE.HTB

ReadGMSAPassword

Let's read the GMSA password using Javier.mmarshall

Success! We have recovered the credentials of Mirage-Service$

Shell as DC01$

We have write access on mark

ESC10

Doing some enumeration for ESC vulnerabilities, we can find that ADCS is vulnerable to ESC10

Notice the 4 value in the CertificateMappingMethods property which indicates it is vulnerable as per CERTIPY-AD Documentationarrow-up-right

Let's exploit this, first, let's update Mark.bbond's upn.

Step 1: Read the initial UPN of the victim account (Optional - for restoration).

Step 2: Update the victim account's UPN to the target DC's sAMAccountName (suffixed with the domain). The target is the DC's machine account, DC$. We set the victim's UPN to dc01$@mirage.htb.

Step 3: Obtain credentials for the "victim" account (if not already known) and set up Kerberos ccache. Set the Kerberos credential cache environment variable (shell command):

Step 4: Request a client authentication certificate as the "victim" user. victimThe certificate will be legitimately issued to the account (and its SID will be embedded if the template includes the SID security extension), but the UPN in its SAN will be the manipulated dc$@corp.local.

Step 5: Revert the "victim" account's UPN to its original value.( remember to authenticate as MIRAGE-SERVICE$ before doing so**)**

Step 6: Authenticate to LDAPS (Schannel) as the target DC using the certificate. Certipy's auth command with the -ldap-shell option will attempt to connect to the DC's LDAPS port (636) using the provided certificate for Schannel client authentication.

RBCD

We have the DC01$ ldap access, let's allow our machine account to RBCD

We will use ldap-shell

Secretsdump

Now we will use S4U2Self to impersonate Administrator

This generates a service ticket to cifs/dc01.mirage.htb for Administrator, usable by Mirage-Service$.

Now we can secretsdump

We can obtain a shell as Administrator with his NThash:

Last updated