2026-08-31

Privilege escalation from IIS AppPool to NT Authority/SYSTEM via AD CS RPC endpoint

Pranaam to all πŸ™

In this blog post, I am going to demonstrate how to escalate privileges from
[text color="amber" weight="600" ]IIS AppPool\DefaultAppPool[/text] to [text color="amber" weight="600"] NT Authority\SYSTEM[/text] without using any Potato exploit, when we have [mark color="danger"]Remote Code Execution[/mark] on a web application running through an IIS web server with the privileges of [text color="amber" weight="600" ]IIS AppPool\DefaultAppPool[/text] and compromised host is a part of Windows Active Directory Domain.

[h1 color="accent"]Outline[/h1] The key insight behind this technique is a well-documented Windows behaviour:
[note] when an IIS AppPool identity accesses a network-level resource, its identity is silently elevated to the underlying machine account of the host.  [/note] This behaviour is by design and we are going to abuse it to achieve Machine account privileges.

When an IIS AppPool (running as [text color="amber" weight="600" ]IIS AppPool\DefaultAppPool[/text]) makes a request to a network resource in an Actve Directory network such as the [mark]Active Directory Certificate Services (AD CS) RPC endpoint[/mark], Windows automatically translates that identity to the machine account of the host where IIS web server is running.

This means when we submit a [mark]Certificate Signing Request (CSR)[/mark] to the [mark]AD CS RPC/web enrollment endpoint[/mark] from the compromised IIS server, the request will arrive at [mark]AD CS[/mark] as the [mark]machine account[/mark], and [mark]AD CS[/mark] will happily issue a certificate for it using the [text color="amber"]default Machine account certificate template[/text].

By combining this identity shift with an  certificate request, we can obtain a machine account certificate from [mark]AD CS[/mark], and then use that certificate to get a [mark]Ticket-Granting Ticket (TGT)[/mark] for the machine account, ultimately impersonating an Administrator using the [mark]S4U2Self technique[/mark] on the host where we want to escalate privileges. Let's start
🀩

 

[h1 color="accent"]Attack Chain🀘😎🀘 [/h1]

Here is the full chain at a glance:
[steps color="amber"][item]Generate a CSR on an attacker controlled Windows machine[/item][item]Submit CSR to AD CS RPC endpoint using an ASPX code running on compromised IIS host (as machine account)[/item][item]AD CS issues certificate for the machine account [/item][item]Combine the issued certificate with private key on attacker machine to generate a PFX[/item][item]Use Rubeus tool to request a Machine account TGT using the PFX[/item][item]Request an admin user's CIFS TGS using the machine account TGT [/item][/steps] 
[h2 color="accent"]Step 1: Generate CSR on Attacker Machine[/h1]On attacker machine, run a custom PowerShell script to generate a [mark]CSR[/mark] and it's [mark]Private key[/mark]. The script prints both the [mark]CSR[/mark] and the [mark]Private key[/mark] as base64-encoded strings directly to the console.
Let's run the PowerShell script on an attacker controlled Windows machine:

[cmd title="Administrator: Windows PowerShell"] PS C:\Users\b0x\Desktop> .\csr_short.ps1[/cmd]
[note]Note: The [mark]subjectName[/mark] and [mark]altName[/mark] parameters are not mendatory since [mark]AD CS default Machine certificate template[/mark] does not accept user-supplied subject and altname.[/note]

The output will be something like this:

CSR generation

πŸ‘‰ Save the [mark]Private Key[/mark] output into a file (let say [mark]machine_cet.key[/mark]) on the attacker machine. We will need it in Step 4.
 

 
 πŸ‘‰ Copy the base64 encoded [mark]CSR[/mark], we will submit it to [mark]AD CS[/mark] using the compromised IIS host using an ASPX code in next step. While copying the CSR, exclude [mark]-----BEGIN CERTIFICATE-----[/mark] and [mark]-----END CERTIFICATE-----[/mark] lines.

[h2 color="accent"]Step 2: Submit CSR to [mark]AD CS RPC Endpoint[/mark] from Compromised Host[/h1]
 
Download the ASPX code from here:  
 
Upload the ASPX code to compromised server and browse it over HTTP/S, we will see an interface like this:
 
 
 
[text color="amber" weight="600"]1. CA Server Name:-[/text] Specify the [mark]AD CS address[/mark] in this input field. In my case, it was [mark]winbox2.queen.indishell.lab\queen-WINBOX2-CA[/mark]
[text color="amber" weight="600"]2. Template Name:-[/text] Type the default machine account certificate template name i.e. [mark]Machine[/mark]
[text color="amber" weight="600"]3. CSR Text area:-[/text] The base64 encoded content of the [mark]CSR[/mark] copied in previous step, should be pasted in this textarea:


The moment this request hits the [mark]AD CS RPC endpoint[/mark], Windows translates the identity to [mark]WEBSERVER$[/mark] (the machine account). [mark]AD CS[/mark] sees a legitimate machine account requesting a certificate using the default [mark]Machine[/mark] template and issues it 😎
 
[h2 color="accent"]Step 3: Retrieve the Issued Certificate[/h1]

When we submit the [text]CSR[/text] using the ASPX code, [mark]AD CS[/mark] will issue a certificate and will return it as a response to the submitted [mark]CSR[/mark].   


From the output, copy this base64 encoded issued certificate and paste it in a file in attacker machine where we have saved the Private key of the CSR (Generated in Step 1):


In my case, I saved the issued certificate in a file and named it [mark]machine_cert.cer[/mark]. Note that, the content should be pasted in between [mark]-----BEGIN CERTIFICATE-----[/mark] and [mark]-----END CERTIFICATE-----[/mark] lines (Refer the screenshot above):
 
[h2 color="accent"]Step 4: Combine Issued Certificate with Private Key to Create a PFX[/h2]

On the attacker machine, save the issued certificate file and the Private key file in a directory. 
To create a PFX file by combining the issued certificate ([mark]machine_cert.cer[/mark]) with the Private Key ([mark]machine_cert.key[/mark]), use [text color="amber" weight="600"]certutil command[/text] like this:

[cmd title="Administrator: Command Prompt"]C:\b0x> certutil -MergePFX machine_cert.cer machine_cert.pfx [/cmd]

After execution of the above-mentioned command, we need to specify a password that will be configred for the PFX file(in my case [mark]b0x@22[/mark]).
 

Now, we have a PFX certificate named as [mark]machine_cert.pfx[/mark] for the machine account [mark]WEBSERVER$[/mark].

[h2 color="accent"]Step 5: Request a machine account TGT using Rubeus[/h1]

To request a [mark]TGT[/mark] for the machine account [mark]WEBSERVER$[/mark], use the [text color="amber" weight="600"]Rubeus tool[/text] on the attacker machine to authenticate to the KDC using the newly created PFX:
 
[cmd title="Administrator: Command Prompt"]C:\b0x> Rubeus.exe asktgt /user:hostname$ /domain:domain_name /certificate:machine_cert.pfx /password:password_of_the_cert /nowrap[/cmd] 
The requested TGT will be for the machine account of the compromised IIS host.
 
In my case, hostname was [mark]WEBSERVER$[/mark], password of the PFX was [text color="amber"]b0x@22[/text] and domain name was [mark]queen.indishell.lab[/mark], so command was:
[cmd title="Administrator: Command Prompt"]C:\b0x> Rubeus.exe asktgt /user:WEBSERVER$ /domain:queen.indishell.lab /certificate:machine_cert.pfx /password:b0x@22 /nowrap[/cmd] 
 
 

The screenshot shows that a [mark]TGT[/mark] was requested for the machine account [mark]WEBSERVER$[/mark] use the [text color="amber" weight="600"]Rubeus tool[/text] (Command prompt 1). The second command prompt in the screenshot shows that the requested [mark]TGT[/mark] was not injected in the current host and SMB access was possible to the target host [mark]WEBSERVER$[/mark]
 
[h2 color="accent"]Step 6: Request CIFS TGS and Impersonate Administrator[/h2]

With the requested machine account [mark]TGT[/mark] in hand, use [mark color="danger"]S4U2self[/mark] technique to request a [mark]CIFS service ticket[/mark] while impersonating the default Domain Administrator account. We will use the [text color="amber" weight="600"]Rubeus tool[/text] to perform this step on attacker machine. 
Command syntax is:

[cmd title="Administrator: Command Prompt"]C:\b0x> Rubeus.exe s4u /self /impersonateuser:Administrator /altservice:cifs/machine_hostname.domain_name /nowrap /ptt /ticket:base64_encoded_machine_account_TGT[/cmd] 
 
In my case, command was:
[cmd title="Administrator: Command Prompt"]C:\b0x> Rubeus.exe s4u /self /impersonateuser:Administrator /altservice:cifs/WEBSERVER.queen.indishell.lab /nowrap /ptt /ticket:base64_encoded_machine_account_TGT [/cmd] 


If everything goes fine, we will get a [mark]CIFS TGS[/mark] from KDC and it will be injected in our current host (attacker machine).
 
Run the below command to make sure [mark]CIFS TGS[/mark] is injected in the current host, execute below command:
[cmd title="Administrator: Command Prompt"]C:\b0x> klist[/cmd]
 

 The output of the command shows that the [mark]CIFS TGS[/mark] has been injected in our current host.

Since we have a [mark]CIFS TGS[/mark] of user [mark color="warn"]Administrator@queen.indishell.lab[/mark] we can have full access to the local file system as [mark]Administrator[/mark] on the target host [mark]WEBSERVER$[/mark] 🀘😎🀘
 
 
Now, we can even use impacket tool secretsdump to dump NTLM hashes from the host [mark]WEBSERVER$[/mark] using the requested [mark]CIFS TGS[/mark.
 
Here is a video demonstration of this attack chain: 



We have reached the end of this blog post 😎

Special Thanks to:
Dominic sir, Ashwath sir, Vivek sir, Andy sir, Soroush  sir and Marcus sir (for being endless supporters 😍)
Amazing MDSec guys: Dima, Dylan, Daniil, PWS, Juanma, Filip, Jamie and Rio Bhai ji
Partner in crime: Manoj, Samarth, Noman, Owais, Sina, Nish, Alessendro, Konsta, Anurag and Vivek bhai ji
❤️Zero cool and Code breaker ICA ❤️

With Love from
❤️ --==[[ Indishell Crew ]]==-- ❤️


Share this post

0 comments

:) :-) :)) =)) :( :-( :(( :d :-d @-) :p :o :>) (o) [-( :-? (p) :-s (m) 8-) :-t :-b b-( :-# =p~ :-$ (b) (f) x-) (k) (h) (c) cheer

© 2009 Start With Linux | Mannu Linux
Designed by cyb3r.gladiat0r
Posts RSSComments RSS
Back to top