{
	"id": "9e3faeb5-1482-4538-898b-a0855cff663e",
	"created_at": "2026-04-06T01:30:19.905444Z",
	"updated_at": "2026-04-10T03:30:33.428411Z",
	"deleted_at": null,
	"sha1_hash": "15eebcbb39b364c2912684b65c0f48f9bcba5c0d",
	"title": "Analyzing a Magnitude EK Appx Package Dropping Magniber",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 247584,
	"plain_text": "Analyzing a Magnitude EK Appx Package Dropping Magniber\r\nPublished: 2022-01-02 · Archived: 2026-04-06 00:33:40 UTC\r\nIn this post I’ll work through analyzing an AppX package from Magnitude Exploit Kit that drops Magniber. This adventure\r\ncomes courtesy of a tweet from @JAMESWT_MHT:\r\nThis caught my interest because AppX packages have gotten some mileage as droppers lately courtesy of Bazar and Emotet.\r\nhttps://news.sophos.com/en-us/2021/11/11/bazarloader-call-me-back-attack-abuses-windows-10-apps-mechanism/\r\nhttps://redcanary.com/blog/intelligence-insights-december-2021/\r\nIf you want to play along from home, the file I’m analyzing is here:\r\nhttps://bazaar.abuse.ch/sample/da1729efaaa590d66f46d388680ed5b1b956246ababd277e7cdd14f90fbf60fa/\r\nAnalyzing the AppX Package\r\nTo start off, let’s get a handle on what kind of file an AppX package is. We can do this using file .\r\n1\r\n2\r\nremnux@remnux:~/cases/magnitude/update$ file edge_update.appx\r\nedge_update.appx: Zip archive data, at least v4.5 to extract\r\nThe file command says the magic bytes for the file correspond to a zip archive. This is common with application or\r\npackage archives like AppX, JARs, and more. If we want more confirmation we can always look at the first few bytes with\r\nhexdump and head .\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\nremnux@remnux:~/cases/magnitude/update$ hexdump -C edge_update.appx | head\r\n00000000 50 4b 03 04 2d 00 08 00 00 00 f8 6e 9d 53 00 00 |PK..-......n.S..|\r\n00000010 00 00 00 00 00 00 00 00 00 00 26 00 00 00 49 6d |..........\u0026...Im|\r\n00000020 61 67 65 73 2f 53 71 75 61 72 65 31 35 30 78 31 |ages/Square150x1|\r\n00000030 35 30 4c 6f 67 6f 2e 73 63 61 6c 65 2d 31 35 30 |50Logo.scale-150|\r\n00000040 2e 70 6e 67 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d |.png.PNG........|\r\n00000050 49 48 44 52 00 00 00 e1 00 00 00 e1 08 06 00 00 |IHDR............|\r\n00000060 00 3e b3 d2 7a 00 00 00 09 70 48 59 73 00 00 0e |.\u003e..z....pHYs...|\r\n00000070 c3 00 00 0e c3 01 c7 6f a8 64 00 00 71 fc 49 44 |.......o.d..q.ID|\r\n00000080 41 54 78 9c ec bd 77 90 25 c7 79 27 f8 65 99 e7 |ATx...w.%.y'.e..|\r\n00000090 db 9b e9 ee f1 33 98 19 0c 06 84 77 04 41 18 92 |.....3.....w.A..|\r\nYup, looks like a zip file based on 50 4b 03 04 ! That means we can unpack the archive using unzip .\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\nremnux@remnux:~/cases/magnitude/update$ unzip edge_update.appx\r\nArchive: edge_update.appx\r\n extracting: Images/Square150x150Logo.scale-150.png\r\n extracting: Images/Wide310x150Logo.scale-150.png\r\n extracting: Images/SmallTile.scale-150.png\r\n extracting: Images/LargeTile.scale-150.png\r\n extracting: Images/BadgeLogo.scale-150.png\r\n extracting: Images/SplashScreen.scale-150.png\r\n extracting: Images/StoreLogo.scale-150.png\r\n extracting: Images/Square44x44Logo.targetsize-32.png\r\n extracting: Images/Square44x44Logo.altform-unplated_targetsize-32.png\r\n extracting: Images/Square44x44Logo.scale-150.png\r\n extracting: Images/Square44x44Logo.altform-lightunplated_targetsize-32.png\r\n inflating: eediwjus/eediwjus.exe\r\n inflating: eediwjus/eediwjus.dll\r\n inflating: resources.pri\r\n inflating: AppxManifest.xml\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 1 of 7\n\n18\n19\n20\n21\n inflating: AppxBlockMap.xml\n inflating: [Content_Types].xml\n inflating: AppxMetadata/CodeIntegrity.cat\n inflating: AppxSignature.p7x\nWith the archive unzipped, we can focus on significant files within the package. These are:\nAppxManifest.xml (list of properties and components used by the AppX package)\nAppxSignature.p7x (AppX Signature Object, contains code signatures for AppX Package)\neediwjus/eediwjus.exe (non-default content that is likely executable)\neediwjus/eediwjus.dll (non-default content that is likely executable)\nFirst, we can look at the AppxManifest.xml file. I’ve included the points of interest below.\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\nEdge UpdateMicrosoft IncImages\\StoreLogo.png ... ... First, let’s take a look at the Identity and Properties sections. Identity contains code signature information that should\ntheoretically be included within the AppxSignature.p7x file. The Properties section contains metadata the Windows\nStore/Universal Windows App interface uses to identify the app. From the name Edge Update and publisher name\nMicrosoft Inc , it appears the malware wants to masquerade as a Microsoft Edge browser update. Note how there is no\nlink or control between the publisher display name and the actual signing identity. This is a major problem for victims trying\nto be sure of themselves.\nThe Application section identifies the EXE that will execute when the package is installed and run. In this sample, the EXE\nis eediwjus.exe . In the package content there is also a DLL, but that isn’t mentioned in the manifest. A possibility to\nexplore might be that the EXE uses content from the DLL for execution.\nFinally, the Capabilities section shows the app will execute with internetClient and runFullTrust capabilities.\nDocumented by Microsoft, these capabilities just mean the app can download stuff from the Internet. Now we can jump into\nthe executable content, the EXE file.\nAnalyzing the Application Executable\nThe EXE has these hashes:\n1\n2\n3\nfilepath: eediwjus.exe\nmd5: 3439bbe95df314d390cc4862cdad94fd\nsha1: 92429885d54a05ed87a5c14d34aa504c28ea8b54\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\nPage 2 of 7\n\n4\r\n5\r\n6\r\nsha256: ad4f74c0c3ac37e6f1cf600a96ae203c38341d263dbac0741e602686794c4f5a\r\nssdeep: 48:6/yaz1YKkikwFJSDq6tPRqBHwOul2a3iq:yz1fkigtJkGYK\r\nimphash: f34d5f2d4577ed6d9ceec516c1f5a744\r\nNote the import table hash starting with f34d . That specific import table hash commonly appears with .NET binaries, so if\r\nyou pivot on it in VT or other tools, you’ll find a lot of .NET. Using Detect It Easy in REMnux, we can confirm the\r\nexecutable is a .NET binary.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\nremnux@remnux:~/cases/magnitude/update/eediwjus$ diec eediwjus.exe\r\nfiletype: PE32\r\narch: I386\r\nmode: 32-bit\r\nendianess: LE\r\ntype: GUI\r\n library: .NET(v4.0.30319)[-]\r\n linker: Microsoft Linker(11.0)[GUI32]\r\nSo let’s take a peek with floss from Mandiant to see if there are signs of obfuscation. There aren’t any signs of\r\nobfuscation like randomized, high-entropy strings, but we do get some interesting strings.\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\n18\r\n19\r\nmscorlib\r\nSystem\r\nObject\r\nmhjpfzvitta\r\nMain\r\n.ctor\r\nlpBuffer\r\nargs\r\nSystem.Runtime.Versioning\r\nTargetFrameworkAttribute\r\nSystem.Security.Permissions\r\nSecurityPermissionAttribute\r\nSecurityAction\r\nSystem.Runtime.CompilerServices\r\nCompilationRelaxationsAttribute\r\nRuntimeCompatibilityAttribute\r\nSystem.Runtime.InteropServices\r\nDllImportAttribute\r\neediwjus.dll\r\nSure enough, the EXE references the DLL in the same folder, and it includes the string DllImportAttribute . This is a good\r\nsign that the EXE will load an unmanaged DLL and call an export from it. Unobfuscated .NET code is usually pretty easy to\r\ndecompile from bytecode form into source, so we can give that a shot with ilspycmd . If you’re on Windows you can also\r\nuse ILSpy or DNSpy . The result is a pretty brief source file:\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\nusing System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.InteropServices;\r\nusing System.Runtime.Versioning;\r\nusing System.Security;\r\nusing System.Security.Permissions;\r\n[assembly: TargetFramework(\".NETFramework,Version=v4.5\", FrameworkDisplayName = \".NET Framework 4.5\")]\r\n[assembly: CompilationRelaxations(8)]\r\n[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]\r\n[assembly: SecurityPermission(8, SkipVerification = true)]\r\n[assembly: AssemblyVersion(\"0.0.0.0\")]\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 3 of 7\n\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n[module: UnverifiableCode]\r\nnamespace eediwjus\r\n{\r\npublic class eediwjus\r\n{\r\n[DllImport(\"eediwjus.dll\")]\r\nprivate static extern void mhjpfzvitta(uint lpBuffer);\r\nprivate static void Main(string[] args)\r\n{\r\nuint lpBuffer = 5604u;\r\nmhjpfzvitta(lpBuffer);\r\n}\r\n}\r\n}\r\nThe entry point for the program is the Main function inside the eediwjus class. The DllImport code imports the\r\nfunction mhjpfzvitta() from the DLL and calls it with the argument lpBuffer . That argument contains an unsigned\r\ninteger value of 5604. lpBuffer appears loads of times in Microsoft documentation around Windows calls like\r\nVirtualAlloc and others that need a buffer of memory for operation. It stands to reason that lpBuffer here might\r\ncorrespond to some form of a memory management call.\r\nAnalyzing the Magniber DLL\r\nThe DLL has these hashes:\r\n1\r\n2\r\n3\r\n4\r\n5\r\nfilepath: eediwjus.dll\r\nmd5: e7e4878847d31c4de301d3edf7378ecb\r\nsha1: a93d0f59b3374c6d3669a5872d44515f056e9dbf\r\nsha256: f423bd6daae6c8002acf5c203267e015f7beb4c52ed54a78789dd86ab35e46c6\r\nssdeep: 96:qUG6xykl2J6lc5irN3qjNu47Ru/8IAgecgKDD:qsQMl0u3qjA47RuZAhk\r\nOur pehash command didn’t find an import table hash, so that’s interesting. There may not be an import table in this\r\nbinary or it might be mangled. We can take a look using the Python pefile library.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\nremnux@remnux:~/cases/magnitude/update/eediwjus$ python3\r\nPython 3.8.10 (default, Nov 26 2021, 20:14:08)\r\n[GCC 9.3.0] on linux\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n\u003e\u003e\u003e import pefile\r\n\u003e\u003e\u003e bin = pefile.PE('eediwjus.dll')\r\n\u003e\u003e\u003e bin.get_imphash()\r\n''\r\n\u003e\u003e\u003e bin.get_rich_header_hash()\r\n''\r\nSure enough, the binary doesn’t seem to have an import table hash or rich header hash. Maybe those parts don’t exist? We\r\ncan confirm with pefile again.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n\u003e\u003e\u003e for directory in bin.OPTIONAL_HEADER.DATA_DIRECTORY:\r\n... print(directory)\r\n...\r\n[IMAGE_DIRECTORY_ENTRY_EXPORT]\r\n0x148 0x0 VirtualAddress: 0x2000\r\n0x14C 0x4 Size: 0x4B\r\n[IMAGE_DIRECTORY_ENTRY_IMPORT]\r\n0x150 0x0 VirtualAddress: 0x0\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 4 of 7\n\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n0x154 0x4 Size: 0x0\r\n...\r\n\u003e\u003e\u003e bin.RICH_HEADER\r\n\u003e\u003e\u003e\r\nSure enough, the import table is apparently empty and no rich header exists for the binary. This is slightly unusual, so let’s\r\nsee if we can run some more commands to find capabilities before jumping further into analysis.\r\nThe Mandiant tools floss and capa yield nothing significant.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n+-----------+------------------------------------------------------------------+\r\n| md5 | e7e4878847d31c4de301d3edf7378ecb |\r\n| sha1 | a93d0f59b3374c6d3669a5872d44515f056e9dbf |\r\n| sha256 | f423bd6daae6c8002acf5c203267e015f7beb4c52ed54a78789dd86ab35e46c6 |\r\n| path | eediwjus.dll |\r\n+-----------+------------------------------------------------------------------+\r\nno capabilities found\r\nYara tells us more of what we already know.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\nremnux@remnux:~/cases/magnitude/update/eediwjus$ yara-rules eediwjus.dll\r\nIsPE64 eediwjus.dll\r\nIsDLL eediwjus.dll\r\nIsWindowsGUI eediwjus.dll\r\nImportTableIsBad eediwjus.dll\r\nHasModified_DOS_Message eediwjus.dll\r\nA pedump command gets us some export info. You could also get this with pefile in Python, I just like this output better.\r\n1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n=== EXPORTS ===\r\n# module \"eediwjus.dll\"\r\n# flags=0x0 ts=\"2021-12-29 10:55:45\" version=0.0 ord_base=1\r\n# nFuncs=1 nNames=1\r\n ORD ENTRY_VA NAME\r\n 1 1f74 mhjpfzvitta\r\nThe export mhjpfzvitta() jives with what we expect coming from the EXE previously seen. This is probably our best\r\nentry point to examine the DLL.\r\nGetting Dirty In Assembly\r\nI usually work with Ghidra, but Cutter seemed to have a better representation of the assembly for this binary.\r\nThe entry point export mhjpfzvitta() is fairly brief.\r\n6: mhjpfzvitta (int64_t arg1);\r\n; arg int64_t arg1 @ rcx\r\n0x180001f74 call fcn.18000113f\r\n0x180001f79 ret\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 5 of 7\n\nThe entry point immediately calls a function at offset 18000113f and returns. Once we go to look at the assembly for that\r\nfunction, we see quite a wild execution graph.\r\nOnce entering the function, the sample contains loads of jmp instructions that cause execution to bounce around to various\r\npoints of the binary. This makes it hard for analysts to follow execution, and eventually we see some more evidence of\r\nsuspicious activity in decompiled code.\r\n1\r\n2\r\n3\r\n4\r\n5\r\nundefined8 fcn.180001f8e(int64_t arg1)\r\n{\r\n syscall();\r\n return 0x18;\r\n}\r\nSince the sample doesn’t have an import table, it’s relying on manual syscall calls like one to 0x18 for\r\nNtAllocateVirtualMemory . Avast saw this with Magniber in the past, alongside the jmp obfuscation.\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 6 of 7\n\nWhile I’m not yet skilled enough to tear much more out of the binary through static analysis, my eye was caught by one\r\nsection of code that pushes 0x40 and 0x1000 to registers. These two values sometimes pop up when malware calls\r\nVirtualAlloc . 0x40 refers to PAGE_EXECUTE_READWRITE protection and 0x1000 refers to MEM_COMMIT . Since these values\r\npopped up in the sample, we can hypothesize that the sample may inject or unpack material into a memory space.\r\nHow do we know it’s Magniber?\r\nI didn’t have luck getting Yara rules for Magniber to match this sample, so the best references I have right now are the tweet\r\nfrom @@JAMESWT_MHT and the blog post from Avast showing similar jmp obfuscation and syscall references.\r\nThanks for reading!\r\nSource: https://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nhttps://forensicitguy.github.io/analyzing-magnitude-magniber-appx/\r\nPage 7 of 7",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://forensicitguy.github.io/analyzing-magnitude-magniber-appx/"
	],
	"report_names": [
		"analyzing-magnitude-magniber-appx"
	],
	"threat_actors": [
		{
			"id": "75108fc1-7f6a-450e-b024-10284f3f62bb",
			"created_at": "2024-11-01T02:00:52.756877Z",
			"updated_at": "2026-04-10T02:00:05.273746Z",
			"deleted_at": null,
			"main_name": "Play",
			"aliases": null,
			"source_name": "MITRE:Play",
			"tools": [
				"Nltest",
				"AdFind",
				"PsExec",
				"Wevtutil",
				"Cobalt Strike",
				"Playcrypt",
				"Mimikatz"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775439019,
	"ts_updated_at": 1775791833,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/15eebcbb39b364c2912684b65c0f48f9bcba5c0d.pdf",
		"text": "https://archive.orkl.eu/15eebcbb39b364c2912684b65c0f48f9bcba5c0d.txt",
		"img": "https://archive.orkl.eu/15eebcbb39b364c2912684b65c0f48f9bcba5c0d.jpg"
	}
}