{
	"id": "f2d2a6c1-b0af-41e1-a280-31127164467f",
	"created_at": "2026-04-06T00:08:38.594803Z",
	"updated_at": "2026-04-10T03:24:23.703768Z",
	"deleted_at": null,
	"sha1_hash": "725b7fba6a93311b4c9675e0837059579e8402a6",
	"title": "SUPERNOVA SolarWinds .NET Webshell Analysis",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 775552,
	"plain_text": "SUPERNOVA SolarWinds .NET Webshell Analysis\r\nBy GuidePoint Security\r\nPublished: 2020-12-14 · Archived: 2026-04-05 15:51:22 UTC\r\nPublished 12/14/20, 9:30am\r\nIntroduction\r\nThe recently announced supply-chain compromise of SolarWinds and FireEye illustrated many of the threats\r\nobserved during that investigation, with particular focus being placed on the SUNBURST SolarWinds Orion\r\nimplant, the memory-resident TEARDROP malware dropper, and usage of Cobalt Strike’s BEACON module. \r\nHowever, in the IOCs listed by FireEye as part of this investigation, a .NET webshell named SUPERNOVA was\r\nidentified with no supplemental analysis as to its method of operation or any behavioral indications of this\r\nwebshell being present in an environment.  \r\nThe GuidePoint Security Digital Forensics and Incident Response Practice closely monitors the on-going threat\r\nlandscape and the emerging state-of-the-practice to ensure that the most up-to-date information and methods are\r\nbeing utilized in the services we provide to our clients.  To that end, this post will describe the SUPERNOVA\r\nwebshell’s operation in-depth, as well as show how this webshell’s activity can be detected within your\r\norganization.\r\nOverview\r\nThe SUPERNOVA webshell is an anonymous code C# webshell written in .NET C# that is specifically written for\r\nusage on SolarWinds Orion servers.  It is deployed as a DLL module that masquerades as a SolarWinds web\r\nservice that returns the current logo image for display by the SolarWinds Orion application.  In normal operation,\r\nthis webshell performs the operation of returning the appropriate logo image as requested by other elements of the\r\nOrion application, requiring a specific set of parameters to be present in the HTTP GET Request for any of the\r\nmalicious code to execute.  This allows the webshell to remain undetected until such time as the attackers decide\r\nto utilize it.  \r\nThe parameters required for webshell remote code execution include the C# code intended to be compiled and\r\nexecuted by the .NET C# compiler, the C# class to be called, the method within that class to be executed, and the\r\nparameters to pass to the requested method.  Upon receiving an HTTP GET Request with the necessary\r\nparameters supplied, the webshell will collect the parameters and pass them to an additional C# method added by\r\nthe attacker which will perform the compilation and memory-resident execution of the requested C# class\r\nmethod.  \r\nOnce this compilation and execution has been completed, the result is returned to the Write() method of the HTTP\r\nResponse object, which is then returned as the HTTP Response.  This execution does not cause or require\r\nexecution of the Windows Command Processor (cmd.exe) or PowerShell, runs all operations within memory, and\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 1 of 7\n\nhas the entirety of the .NET C# API available to the attacker to conduct actions-on-objective.  While anonymous\r\ncode webshells are not new, as webshells like China Chopper have been around for more than a decade, the\r\nmajority of anonymous code webshells are for interpreted languages and are centered around commonly used web\r\nlanguages, such as PHP, ASP, or Java.  Anonymous code webshells utilizing a compiled code language indicate a\r\nsignificant level of sophistication within the threat group that employs them.\r\nAnalysis Detail\r\nSUPERNOVA is implemented as a modification to the existing ‘app_web_logoimagehandler.ashx.b6031896.dll’\r\nmodule of the SolarWinds Orion application.  The purpose of this module, in it’s legitimate form, is to return the\r\nlogo image configured by the user to various web pages of the SolarWinds Orion web application.  This is done\r\nthrough the ProcessRequest() method of the LogoImageHandler class.  In legitimate operation, this class only\r\ncontains the ProcessRequest() and LogoImageHandler() methods, a private static Log object, and public boolean\r\nparameter IsReusable.  The malicious additions made by the threat actors include:\r\nAn extra try/catch block at the beginning of the ProcessRequest() method \r\nAn extra method called DynamicRun() \r\nNow, to discuss each of these in detail, beginning with the ProcessRequest() try/catch block.\r\nProcessRequest() Try/Catch Block\r\nAs the ProcessRequest() method is the primary driver method that parses the incoming HTTP Request, this was\r\nthe most appropriate place for the attacker to implement code to parse and handle the webshell parameters passed\r\nto SUPERNOVA.  As such, the attacker’s implemented their argument-handling code in a try/catch block at the\r\nvery beginning of the ProcessRequest() method.  This code block is shown below:\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 2 of 7\n\nFigure 2: Attacker-Implemented Argument-Handling Try/Catch Block\r\nThe attacker-implemented try/catch block can be broken down into two primary segments, one concerning the\r\nwebshell input and another concerning the webshell output.  The first are the parameter instantiations, in which\r\nthe code determines if the four attacker parameters exist in the HTTP Request, and if they do, then extract the\r\nvalues of those parameters to string objects of corresponding parameter names.  The four attacker parameters, and\r\ntheir purposes, are as follows:\r\n“codes”: Stores anonymous C# code to be compiled and executed by the webshell\r\n“clazz”: Stores the .NET C# class name that the attacker wants to instantiate as part of this execution\r\n“method”: The specific method to be executed within the requested .NET C# class being instantiated by the\r\n“clazz” parameter\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 3 of 7\n\n“args”: A newline-delimeted list of arguments to pass to the executing method requested by the “method”\r\nparameter\r\nThe second segment is comprised of the last two lines of the try{} block, which involves setting values within the\r\nResponse object of the HttpContext ‘context’ object.  As this Response object is the data that will be sent back to\r\nthe attacker in the HTTP Response, this serves as the output mechanism for this webshell.  The first instruction\r\nsets the HTTP Response Content-Type Header Value to ‘text/plain’, indicating that the HTTP Response body will\r\nconsist of plain-text content; this is commonly observed webshell operation.  \r\ncontext.get_Response().set_ContentType(“text/plain”)\r\nFigure 2: Setting of the HTTP Response Content-Type Header\r\nThe last instruction of the try{} block simultaneously calls the DynamicRun() method to execute with the\r\nattacker-supplied parameters, and routes the output of the DynamicRun() method straight to the Write() method of\r\nthe Response object via a nested method call. \r\ncontext.get_Response().Write(DynamicRun(codes, cl azz, method, args))\r\nFigure 3: DynamicRun() Method Call Nested in Write() Method Call of Response Object\r\nSince the second instruction both executes and outputs the result to the Response object, the try{} block completes\r\nand the result is returned to the attacker.\r\nNext, we discuss the attacker-implemented DynamicRun() method.\r\nDynamicRun() Method\r\nThe DynamicRun() method added by the attacker is where the actual compilation and execution of the requested\r\nclass and method take place.\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 4 of 7\n\nFigure 4: DynamicRun() Attacker-Implemented Method\r\nThe majority of instructions in this method are just setup code for compilation of the requested class and method\r\ninto something that can be executed in memory.  However, some instructions stand out as significant or\r\nexplanatory.  First items of interest are instructions seven and eight.\r\n7 val.set_GenerateExecutable(false);\r\n8 val.set_GenerateInMemory(true);\r\nFigure 5: Instructions Setting Memory-Resident Compiled Code Execution Only\r\nInstruction seven tells the compiler not to create an executable on disk to load for execution of the compiled class\r\nand method, with instruction eight telling the compiler to generate the compiled module within memory only. \r\nThese two instructions together ensure that any requested compiled modules will not leave filesystem evidence for\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 5 of 7\n\nincident response analysts to determine what classes and methods were executed by the attacker using this\r\nwebshell.\r\n9 CompilerResults val2 = obj.CompileAssemblyFromSource(\r\n(CompilerParameters)(object)val, codes\r\n);\r\nFigure 6: Passing of Anonymous C# Code in “codes” to .NET Compiler and Compilation\r\nInstruction nine passes the C# code contained in the “codes” string object parameter to the compiler, then the\r\nmodule is compiled by the CompileAssemblyFromSource() method.  This creates the memory-resident module for\r\nexecuting, which is stored in the val2 CompilerResults object.\r\n16 object obj2 = val2.get_CompiledAssembly().CreateInstance(clazz);17 return\r\n(string)obj2.GetType().GetMethod(method)!.Invoke(obj2, args);\r\nFigure 7: Class Instantiation and Method Execution\r\nInstructions 16 and 17 use the compiled module and instantiate its contained class referenced in the “clazz”\r\nparameter, then invokes the target method referenced in the “method” parameter with the attacker-supplied\r\narguments referenced in the “args” parameter.  The result of this method execution is stored in the return value of\r\nthe method, and the DynamicRun() method terminates.  The return value is the value that is used by the Write()\r\nmethod of the Response object that was discussed previously.\r\nDetection\r\nNetwork Dataset\r\nThe key behavioral aspects that we can take from the code reviewed are the requirement for the four attacker\r\nparameters to be present for execution of the malicious code, and the HTTP Response Content-Type Header value\r\nanomaly caused by the execution of the malicious webshell code.  Utilizing these as detection mechanisms allow\r\nus to apply hunting-type dataset reductions with a reasonable level of fidelity on both the Request and Response\r\nside of the malicious network communications.  For the Request side, we would want to implement a ruleset or\r\nquery that would key in on the existence of the four webshell parameters (“codes”, “clazz”, “method”, and “args”)\r\nfor any inbound HTTP connections to logoimagehandler.ashx.  An example of this logic in Lucene-syntax pseudo-query would be as follows:\r\ndirection:inbound AND\r\nrotocol:http AND\r\nuri.filename:logoimagehandler.ashx AND\r\nuri.param:codes AND\r\nuri.param:clazz AND\r\nuri.param:method AND\r\nuri.param:args\r\nFigure 8: Pseudo-Query Logic for SUPERNOVA Webshell Access Identification\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 6 of 7\n\nFor the Response side, we would want to key in on the HTTP Response Content-Type Header value of ‘text/plain’\r\nresulting from a HTTP Request to logoimagehandler.ashx.\r\ndirection:inbound AND\r\nprotocol:http AND\r\nuri.filename:logoimagehandler.ashx AND\r\nhttp.response.contenttype:text/plain\r\nFigure 9: Pseudo-Query Logic for SUPERNOVA Webshell Access Response Identification\r\nLogs\r\nThe access logs for the IIS web server hosting the SolarWinds Orion web application would be the best location in\r\nthe log dataset to identify this activity.  Here, we would take a similar approach as in Figure 8, attempting to\r\nidentify HTTP Requests to logoimagehandler.ashx in which the URI contains the “codes”, “clazz”, “method”, and\r\n“args” parameters.  The query logic would look similar to the logic shown in Figure 8.\r\nuri.filename:logoimagehandler.ashx AND\r\nuri.query contains “codes” AND\r\nuri.query contains “clazz” AND\r\nuri.query contains “method” AND\r\nuri.query contains “args”\r\nFigure 10: Pseudo-Query Logic for SUPERNOVA Webshell Access Identification in IIS Logs\r\nConclusion\r\nWhile webshells are a common access and persistence mechanism leveraged by attackers, characteristics of this\r\nspecific webshell reiterate the targeted nature and sophistication of these specific attacks.  The SUPERNOVA\r\nwebshell was developed specifically for use on SolarWinds Orion systems, does not appear to repurpose code\r\nfrom other well-known webshells, contains various functionality to ensure limited identification or detection\r\ncapabilities, and various other characteristics reemphasizing involvement from a nation-state sponsored actor. \r\nGuidePoint recommends utilizing the aforementioned detection capabilities, in combination with other IOC’s that\r\nhave been released for other components of this threat, to ensure your organization has not been impacted.\r\nSource: https://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nhttps://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MISPGALAXY",
		"Malpedia"
	],
	"references": [
		"https://www.guidepointsecurity.com/blog/supernova-solarwinds-net-webshell-analysis"
	],
	"report_names": [
		"supernova-solarwinds-net-webshell-analysis"
	],
	"threat_actors": [
		{
			"id": "610a7295-3139-4f34-8cec-b3da40add480",
			"created_at": "2023-01-06T13:46:38.608142Z",
			"updated_at": "2026-04-10T02:00:03.03764Z",
			"deleted_at": null,
			"main_name": "Cobalt",
			"aliases": [
				"Cobalt Group",
				"Cobalt Gang",
				"GOLD KINGSWOOD",
				"COBALT SPIDER",
				"G0080",
				"Mule Libra"
			],
			"source_name": "MISPGALAXY:Cobalt",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434118,
	"ts_updated_at": 1775791463,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/725b7fba6a93311b4c9675e0837059579e8402a6.pdf",
		"text": "https://archive.orkl.eu/725b7fba6a93311b4c9675e0837059579e8402a6.txt",
		"img": "https://archive.orkl.eu/725b7fba6a93311b4c9675e0837059579e8402a6.jpg"
	}
}