{
	"id": "e795b299-605b-4ef8-9d8d-14886bbde696",
	"created_at": "2026-04-06T00:17:28.429943Z",
	"updated_at": "2026-04-10T03:22:12.739291Z",
	"deleted_at": null,
	"sha1_hash": "a23bfab2c2fb8ea04c80c81835467c8d52b76ea5",
	"title": "Glupteba’s .NET dropper deep dive.",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 882225,
	"plain_text": "Glupteba’s .NET dropper deep dive.\r\nBy Otavio M.\r\nPublished: 2024-03-30 · Archived: 2026-04-05 13:51:21 UTC\r\nOverview\r\nGlubteba is a modular malware, meaning that it can deploy and execute a variety of independent code which\r\nimplements different capabilities.\r\nIts main category is a backdoor trojan, usually driven by a botnet operator. Known to steal user credentials and\r\ncookies, mine cryptocurrency on victims, and deploy proxy components targeting Windows systems and IoT\r\ndevices.\r\nIts distribution is mainly through pay-per-install (PPI) networks and traffic distribution systems (TDS).\r\nIn this article, we will be analyzing its first stage, where an executable is dropped and executed on disk.\r\nInitial Analysis\r\nsha256:e70dcf3f915087251224a7db3850669c000a6da68ef2b55e3e2eda196cb01fc3\r\nThe file is a 32-bit executable, written in .NET (v4.0.30319). There are only 3 sections: .text, .rsrc, and .reloc, and\r\nonly one DLL import: mscoree.dll, which is common for .NET applications (as well as the _CorExeMain API\r\nimport).\r\nChecking for strings, the reader can soon see that there are plenty of meaningful strings.\r\nantiSandbox\r\nantiEmulator\r\nDetectVirtualMachine\r\nDetectSandboxie\r\nCheckRemoteDebuggerPresent\r\nDetectDebugger\r\nCheckEmulator\r\nisDebuggerPresent\r\nenablePersistence\r\nenableFakeError\r\nencryptType\r\ncompressed\r\nDecompress\r\nEncryptOrDecryptXOR\r\nEncryptInitializer\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 1 of 10\n\nEncryptOutput\r\nGetResource\r\nRunOnStartup\r\nWriteAllBytes\r\nThose strings can give us some insights related to the malware’s capabilities. The malware likely can detect\r\nsandboxes/debuggers/emulators, persist in the victim’s machine, encrypt and decrypt with XOR, retrieve\r\nsomething from the resources, and manipulate memory.\r\nAlso, They are great indicators of not the final payload, but a dropper instead.\r\nTo confirm it, the reader may have noticed a big chunk of apparently the same encrypted string. If we correlate\r\nthat information with the capabilities listed before, we can assume that this file is actually a dropper, not the final\r\npayload. Furthermore, we can even figure out the general dropping procedure. It is possibly done by XORing this\r\nstring, writing it into some place in memory, then following with its execution.\r\nNotice the pattern being repeated in this chunk, it is likely caused by XOR encryption.\r\nDropper Analysis\r\nAs said before, the file is a 32-bit .NET executable. Open it on dnSpy 32-bit and you’ll soon see that the file is not\r\nobfuscated, making our analysis easier to accomplish. Before continuing to main, the reader needs to pay attention\r\nto an extremely important thing when analyzing .NET binaries, the class constructors.\r\nWhenever a class or a struct is instantiated, its constructor is invoked. The point here is that these constructors run\r\nbefore the execution of the main method, class initializers, and even the executable’s entrypoint. Aware of that, the\r\nreader should always examine the ctor() / cctor() before the main method.\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 2 of 10\n\nAnd that’s what happens in our binary, following the Main entrypoint of the program, we get to the Program\r\nclass, which the reader will see it contains almost all the dropper’s procedures, but if looked closer, there is a\r\ncctor() , which initializer a bunch of lists, paths, and variables.\r\nAnalyzing this constructor, we can see that it sets various flags to false, the field encryptType to\r\n“XORIAIZCNIWw”, cvers to “SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run” (when decoded from\r\nbase 64), and four lists: the first being for the fileNames , the second foe fileTypes , third for fileRunTypes\r\nand the last one for fileDropPaths (ledaing us to believe that the dropped payload will be at the %TEMP%\r\ndirectory).\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 3 of 10\n\nNow the reader can proceed to the Main function at Program class, or in other words, the binary’s entrypoint.\r\nIt first performs a kind o environmental keying, in which there are four functions that tries to detect if the binary is\r\ncurrently being executed inside a controlled or sandboxed environment.\r\nThe first subroutine, Anti.DetectVirtualMachine , executes a WMI query Select * from\r\nWin32_ComputerSystem , which is a WMI class that represents the computer system running Windows. Then, based\r\non the Manufacturer field, it checks whether the machine’s manufacturer is equal to “microsoft corporation”\r\nAND the machine’s model contains “VIRTUAL” OR the machine’s manufacturer is equal to “vmware” OR the\r\nmachine’s model is equal to “VirtualBox”. If so, the subroutine returns true .\r\nNext, at Anti.Sandboxie , the dropper simply tries to retrieve a handle to SbielDll.dll , which is a common\r\nDLL present on the “Sandboxie” project, “a sandbox-based isolation software for Windows that lets you try and\r\nrun untrusted applications” - Sandboxie’s website. If it is not equal to 0, the return value will be true .\r\nFollowing, the next check is at Anti.DetectDebugger , which employs the use of the API\r\nCheckRemoteDebuggerPresent .\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 4 of 10\n\nIntrinsically, CheckRemoteDebuggerPresent calls NtQueryInformationProcess with the parameter 0x7 , which\r\ntranslates to ProcessDebugPort . Then, if the process is being debugged, a DWORD with a value equal to\r\n0xFFFFFFFF (-1) will be returned.\r\nThe last check is made by Anti.CheckEmulator . This subroutine makes a comparison in how much time the\r\nbinary took to accomplish the call to Sleep(10) , which, in case of emulation, will be slightly more than 10L.\r\nIn case of checks being satisfied, the dropper will delay its execution by the value set earlier in the cctor() for\r\ndelayTime times(*) 1000. But in our case, it was set to 0 (as well as every other flag that enable the previous\r\nanti-analysis checks).\r\nNext, if enablePersistence flag is set, RunOnStartup is called. This routine is pretty simple, it gets the\r\napplication domain’s friendly name, or in other words, the executable’s name, and appends an “.exe” to it. Then it\r\nchecks if the executables exists in the specified AppPath (arg2), if not, it copies itself to that location. If Hide\r\n(arg3) is true , it sets the “Hidden” attribute for that specific file, which permits the file to not be included in an\r\nordinary directory listing.\r\nNext, it tries to open the previous set cvers constant, but as a subkey at “LocalMachine” registry path. After\r\nopened, it sets a key of regName (arg1) with the value of the combined AppPath .\r\nFinally, it tries the same procedure above, but for “CurrentUser” registry path.\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 5 of 10\n\nSubsequently to it, the dropping phase starts. For each one of the file names listed at fileNames list (initialized in\r\nthe cctor() ), the dropper sets text to the current iteration’s fileNames , text2 to the current iteration’s\r\nfileTypes , text3 to fileRunTypes and text4 to fileDropPaths .\r\nNext, it calls GetResource to get the resource inside the current iteration’s fileNames and stores it in an array.\r\nGetResource subroutine retrieves the named resource “e3cgcd4b2oq” in Assembly.GetExecutiongAssembly() ,\r\nwhich references the assembly that contains the code that is currently executing. Returning an object for it.\r\nAfter retrieving the resource, it checks if the compressed flag is enabled. If so, call Decompress .\r\nThis subroutine opens two memory streams of type MemoryStream() , deflates the former (which contains our\r\ncompressed resource), and copies it to the latter. Then, returns the copied memory stream in the form of an array.\r\nFollowing, the dropper checks which one of the encryption types was set. If encryptType is equal to\r\n“AwkCZdaodw”, Decrypt routine is called. If it’s equal to “XORIAIZCNIWw”, EncryptOrDecryptXOR is\r\ncalled.\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 6 of 10\n\nBoth of them use “mjsqrfk0ee4” as the key.\r\nThe Decrypt routine returns the result of EncryptOutput in the form of an array.\r\nMoving on, EncryptOutput is basically RC4. It first calls EncryptInitialize , which performs an identity\r\npermutation on the array array , and then it executes the RC4’s KSA, returning the scrambled array array .\r\nReturning to EncryptOutput , The RC4’s PRGA phase is executed, XORing our keystream with each byte from\r\ndata (arg2).\r\nThe EncryptOrDecryptXOR routine is much simpler. It will XOR each byte of the resource with each byte of the\r\nkey, rotating around the key bytes.\r\nAfter the resource gets decrypted, the dropper will combine the %TEMP% ( fileDropPaths ) with text +\r\ntext2 ( fileNames + fileTypes ). Then, Execute is called for this binary.\r\nIf runType is “Run Always”, this function starts the decrypted binary and returns, if it is “Run Once” it does not\r\nreturn.\r\nReturning means that, at the end of execution, the flag variable will be assigned to enableFakeError . This\r\nassignment employs the following screen, which tries to confuse both the victim and the analyst.\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 7 of 10\n\nTo extract the final payload, the reader should put a breakpoint on line 67, at WriteAllBytes call. Then, in the\r\n“Locals” tab, save the content of array . This can be done by the following:\r\nGiving us as result:\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 8 of 10\n\nWe can further analyze the dropped executable, but it will be a subject for another article (As I’m focusing on\r\n.NET for this one).\r\nAnd that’s it for today, hope you enjoyed and learnt something from this article. Thank you!\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 9 of 10\n\nSource: https://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nhttps://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://estr3llas.github.io/gluptebas-dotnet-dropper-deep-dive/"
	],
	"report_names": [
		"gluptebas-dotnet-dropper-deep-dive"
	],
	"threat_actors": [],
	"ts_created_at": 1775434648,
	"ts_updated_at": 1775791332,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a23bfab2c2fb8ea04c80c81835467c8d52b76ea5.pdf",
		"text": "https://archive.orkl.eu/a23bfab2c2fb8ea04c80c81835467c8d52b76ea5.txt",
		"img": "https://archive.orkl.eu/a23bfab2c2fb8ea04c80c81835467c8d52b76ea5.jpg"
	}
}