Deep understand ASPX file handling and some related attack vectors

Deep understand ASPX file handling and some related attack vectors

Basic concepts

Each IIS server may be include many websites, each website has Site ID, Physical webroot path, bindings and Root application (and more another applications under child directory):

Example website1

For example, website1 have: Site ID = 2, Physical Path = C:\website1, Bindings = http:*:81:, two applications (Root application at C:\website1 and app1 application at C:\website1\app1)

Each IIS website can have many applications (at least Root application). Each application will have AppPool Name, Virtual Path and Physical Path.

Example website1 with admin application

Each Application will run under only one AppPool.

Each AppPool will have:

  • AppPool Name
  • Identity
    • LocalSystem, NetworkService, LocalService
    • ApplicationPoolIdentity (IIS apppool\<apppool_name> - virtual account)
  • Apppool run as C:\windows\system32\inetsrv\w3wp.exe under identity privilege
website1 AppPool

Now, we have basic aspx file handling as following:

  • Step1. User access http://domain:81/index.aspx
  • Step2. Binding http:*.81 -> website1 will handle this
  • Step3. Virtual path /index.aspx -> Root Application will handle this
  • Step4. Root Application runs under website1 apppool -> Launch website1 apppool process (w3wp.exe) under "IIS apppool/website1" identity
  • Step5. Apppool process (w3wp.exe):
    • From virtual path /index.aspx, get physical path C:\website1\index.aspx and read aspx content
    • Translate to C# sourcecode
    • Launch csc.exe to build C# sourcode into dll
    • Load dll, init a Page instance and call Page.OnLoad()

Aspx file build process only runs when the file is accessed for the first time or when the file is changed.

So dll compiled file must be cached at somewhere. The cache algorithm is simple as below:

And this is the folder to save the cache data:

The cache data for virtual path /index.aspx is saved in file index.aspx.cdcab7d2.compiled in folder C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\4c305858\252b41dd\

You will see the assembly and type property. The virtual path /index.aspx will be handled by App_Web_ssm44hrj.dll and type ASP.index_aspx of that assembly.

And now is more information for this data:

Some important parts in cache folder

How I know this information. That's quite simple. I attached w3wp.exe in dnSpy and reverse + debug it. Most related code is in System.Web.Compilation namespace of System.Web.dll

"code gen dir"

Here is the algorithm to calculate "code gen dir" of an application (you need to know the physical path and appid)

algorithm to calculate code_gen_dir

For example, website1 (Site ID=2) have two applications:

  • Root application (physical path = C:\website1\ , appid = /LM/W3SVC/2/ROOT)
  • admin application (physical path = C:\website1\admin , appid = /LM/W3SVC/2/ADMIN)

"Top level files hash"

Calculate the combined hash of (machine.config, web.config,…)

If hash is changed (some configs are changed) then delete all file in "code gen dir" (later rebuild everything)

hash.web file

Besides, the file hash\hash.web is monitored in realtime, if hash is changed then shutdown current AppDomain


Load all assembly in this file; find and run method with PreApplicationStartMethodAttribute

This is for initializing something before apppool running.

Init assembly name

Cache key

That's is the most important part. The cache key for /index.aspx is cdcab7d2   (w3wp.exe will find the cache file index.aspx.cdcab7d2.compiled in "code gen dir" folder to load information - assembly, type,...)

Here is the algorithm to generate cache key for a virtual path:

Algorithm to calculate cache key

Some examples:

Now based on these concepts, we have some possible attack vectors:

  • Attack01 - Stealthy webshell backdoor
  • Attack02 - Support Arbitrary File Read & Unrestricted File Upload in a hardening server
  • Attack03 - Bypass Apppool Isolation
  • Attack04 - Bypass URL Filtering

Attack01 - Stealthy webshell backdoor

Remember the cache file

Hacker can upload a malicious dll in this folder and change the assembly and type property to hijack the normal function.

Hacker don't need to touch and change anything in webroot folder (C:/website1).

I have developed a tool makebackdoor.ps1 to automate this process.

  • Find a normal un-necessary aspx file: /about.aspx
  • Hijack compiled aspx: powershell -File makebackdoor.ps1 -virtualPath /about.aspx
  • Access

This backdoor allow attacker to bypass:

  • Directory monitoring
  • Webshell scanner
  • Access log machine learning
  • And hard to forensic

Attack02 - Support Arbitrary File Read & Unrestricted File Upload in a hardening server

The basic idea is if you cannot read or write in webroot folder, you can read or write in the cache folder.

For example, if attacker have unrestricted file upload bug but the server disallow write permission in C:/website1/ so attacker cannot write a webshell in that folder. Attacker could think to write into the cache folder.

Another example, a few application use the pre-compiled source code and turn off the auto-compile options in production, so attacker can upload a webshell but the webshell is not compiled when it's accessed. Attacker could also think to write into the cache folder.

The hard part is to calculate the cache folder path, you need to know the physical path and appid of an application. One default is Root Application of Default WebSite (physical path = C:\inetpub\wwwroot\ and appid = /LM/W3SVC/1/ROOT)

I don't have any real case for this attack. Hope to see this attack in the future.

Attack03 - Bypass Apppool Isolation

In some cases, there are many websites in the same IIS server (for example, shared hosting)

I ask myself  if a website could attack another one?

This is the permission of folder C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\

The problem is:

Pay attention that all ApplicationPoolIdentity belongs to BUILTIN\IIS_IUSERS. So any apppool account could modify or delete content in the cache folder of another account.

Here is the attack I do in some Plesk based shared hosting services:

I reported this issue to MSRC. And they did not consider this as a vulnerability. They have a guide for this risk.

And I reported to Plesk, they confirmed this bug and fix it.

But I think another shared hosting environment could be vulnerable too. I didn't check all of them. I only test for Plesk.

Attack04 - Bypass URL Filtering

The idea is cache key duplicate. Remember the cache key generation algorithm. It returns 8 hex characters (4 bytes)

The maximum unsigned 4 bytes is 4,294,967,295

The number is quite big but it is still easy to have a collision.

Here is some examples:

If some WAF block you at /admin/index.aspx, you can access at /a583524842/index.aspx

However, this attack vector didn't work anymore because Microsoft patched it in CVE-2020-1476

Here is the advisory: