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].
[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:
π 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]
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:
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:
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:
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.
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 ❤️
0 comments