Mark Ku's Blog

Handling a Security Incident

While investigating a security incident, we found that an attacker had left a backdoor script on the server, and the site's JS had been tampered with to redirect users to a fake Flash page. After looking into it, I suspected we'd been hit by a WebShell attack.

What is a WebShell Attack?

WebShell attack diagram showing attacker uploading and executing malicious scrip
WebShell attack diagram showing attacker uploading and executing malicious scrip

Looking at the diagram on the cover image, attackers may have used vectors like:

vulnerabilities in Microsoft products (Windows, IIS, .NET Framework), or an employee's infected machine being used as a stepping stone,

combined with overly broad write permissions on the web server,

to drop a prepared backdoor script

into our web server.

Because the web script engine recognizes the script,

simply opening the page is enough to execute it.

Questions

Looking at this as a developer, a lot of questions came up.

Why did some process have permission to modify our code?

Why is this script even able to run on the server?

Don't we use MVC across the company now? Why is the ASPX engine still around?

Simulating the Scenario

After going through a lot of references, I wrote a PoC script (ASPX) to simulate the situation. Since I couldn't simulate how the file got in, I uploaded it manually instead, and confirmed that the code could indeed write arbitrary files.

<%@ Page Language="C#" %>
<%@ Import Namespace="System"%>
<%@ Import Namespace="System.IO"%>
<%@ Import Namespace="System.Text"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">


        protected void Page_Load(object sender, EventArgs e)
        {
			
			  string currentdir =  HttpContext.Current.Server.MapPath("~")
              string path = currentdir + "/HackTest.txt";


            
                // Create the file, or overwrite if the file exists.
                using (FileStream fs = File.Create(path))
                {
                    byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
                    // Add some information to the file.
                    fs.Write(info, 0, info.Length);
                }

                // Open the stream and read it back.
                using (StreamReader sr = File.OpenText(path))
                {
                    string s = "";
                    while ((s = sr.ReadLine()) != null)
                    {
                        Console.WriteLine(s);
                    }
                }
			
		}

</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>

</body>
</html>

In the end, after reading Will's blog post, I found that IIS's default directory is safe, but once we moved it to drive X, it inherited the extra permissions from drive X. Sure enough, our IIS directory was both writable and modifiable.

My Final Solution

  1. Remove unnecessary script engines from web.config (ASPX, ASP, ...).
  2. Review IIS directory permissions and disable inheritance from drive D — restrict users to read-only, with no script execution or write access.
  3. Review the IIS Request Filtering settings.
  4. Run Windows Update at least every six months. Apply patches early when Microsoft publishes major security advisories. You can check the Windows Update guide site for major security vulnerabilities.

References

IIS execution identity and Windows access control aren't what you think How to Secure a Site in IIS Government Configuration Baseline (GCB) IIS 8.5 Government Configuration Baseline rollout and assessment tool .NET Security Application/Web Development - Overview .NET Security Application/Web Development - Overview - 2 .NET Security Application/Web Development - Overview - 3 .NET Security Application/Web Development - Overview - 3

Author

Mark Ku

擁有 10+ 年經驗的資深軟體工程師,現為 AI 應用 Builder,專注於大型平台架構與簡化複雜系統設計,從電商系統到訂閱與收費平台,結合 AI Agent、AI 整合與自動化開發,打造高效率且可持續演進的產品技術基礎。Read More

Found this useful?

The author's free tools, daily podcasts and newsletter are all here.

Mark Ku · This article is licensed under CC BY 4.0. Credit the author and link back to the original when reusing it.

Comments

Subscribe to Newsletter

Subscribe to get new posts delivered instantly — never miss a tech share.

By submitting, you agree to receive emails. You can anytime.

Popular Posts

View all
Mark Ku
··602

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution
Mark Ku
··490

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.
Mark Ku
··333

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki
Mark Ku
··264

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning
Mark Ku
··221

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1
Mark Ku
··215

Setting Up Samba on Ubuntu to Share Folders with Windows 11

Setting Up Samba on Ubuntu to Share Folders with Windows 11