{
	"id": "c73de666-f27c-47eb-838f-286443e5e382",
	"created_at": "2026-04-06T01:31:26.86888Z",
	"updated_at": "2026-04-10T03:20:21.261599Z",
	"deleted_at": null,
	"sha1_hash": "c90eda83b017149ebf1216261a9cf0bc84cbdff0",
	"title": "Dridex Reloaded: Analysis of a New Dridex Campaign",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1381127,
	"plain_text": "Dridex Reloaded: Analysis of a New Dridex Campaign\r\nBy Oleg Boyarchuk, Jason Zhang, Giovanni Vigna\r\nPublished: 2021-03-29 · Archived: 2026-04-06 00:14:39 UTC\r\nDridex is a banking Trojan. After almost a decade since it was first discovered, the threat is still\r\nactive. a report published by Check Point [1], Dridex was one of the most prevalent malware in 2020. The\r\nrecent Dridex campaign detected by VMware demonstrates that this ongoing threat constantly evolves with new\r\ntactics, techniques, and procedures (TTPs), which exhibit great differences with respect to the\r\nvariants we’ve collected from campaigns since April 2020 (as discussed in the section Comparison with old\r\nDridex samples). \r\nIn this blog post, we first examine the recent Dridex attack by looking into some of VMware’s NSX Advanced\r\nThreat Prevention telemetry, which showcases the magnitude of the campaign. We then present the analysis for\r\nthe most distinctive aspects of the attack, from the techniques leveraged by the XLSM downloader to the main\r\nfunctionality of the DLL payloads. Finally, we provide a comparison to some other Dridex variants seen in the\r\npast, which leads to the conclusion that the Dridex variant from the January 2021 campaign is very\r\ndifferent from previous variants. \r\nThe chart below shows the detection timeline of the campaign that affected some of our customers in the APAC\r\nregion, mostly universities. As we can see, the campaign started on January 11, and peaked on January 21\r\nbefore fading away.  \r\nDetection timeline of the campaign that affected some of our customers in the APAC region.\r\nTo entice potential victims to activate a malicious payload, attackers often use social engineering techniques in\r\nspam emails. Typical examples include using logistics invoices and online order confirmations as lures. In the\r\nrecent Dridex campaign, the malspam appears to come from the customer service department of a logistic\r\ncompany, with subject lines saying that new invoices are available to be viewed. The screenshot below shows the\r\nemail sender names, subject lines, and attachment filenames of some typical emails from the campaign we\r\ndetected.  \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 1 of 21\n\nExamples of typical email header and attachment names from the Dridex campaign.\r\nThe email attachments are weaponized XLSM spreadsheet documents, which serve as the Dridex downloaders in\r\nthe campaign, as discussed in the following section.  \r\nXLSM Downloader \r\nTo better understand the attack, we analyzed one of the XLSM samples from the campaign, as shown in the table\r\nbelow: \r\nMD5  a47b6adc87b8000c91a706d3c5ed540f \r\nSHA1  5337c9cd3d3813178bd5e7d1e1334ab973bdbb3f \r\nSHA256  fa8ed75cfc69a06cf1e809531f7371b5c75fd480339ae65568785b76387ceaa0 \r\nFile name  1 Total New Invoices-Thursday January 21 2021.xlsm \r\nSize  30953 bytes \r\nType  application/msoffice-xlsm \r\nThe properties of a typical XLSM sample from the campaign.  \r\nLike typical weaponized Office documents, this document uses social engineering to ask for enabling macro\r\nexecution upon opening the file: \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 2 of 21\n\nThe opening page of the XLSM sample.\r\nThe . \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 3 of 21\n\nProtected VBA macro.\r\nThe VBA macro is locked (as shown above). Protecting a VBA macro is not necessarily malicious, but this feature\r\nis seldom used in benign documents. For this reason, NSX catches this suspicious behavior as follows: \r\nNSX detection: VBA Project is not viewable.\r\nExploring the embedded macro reveals that it leverages URLDownloadToFileA to download a DLL payload.\r\nCalling URLDownloadToFileA takes into account both 32-bit and 64-bit operating systems: \r\n#If VBA7 And Win64 Then\r\n Private Declare PtrSafe Function X_resize_Page1 Lib \"urlmon\" _\r\n Alias \"URLDownloadToFileA\" ( _\r\n ByVal pCaller As LongPtr, _\r\n ByVal szURL As String, _\r\n ByVal szFileName As String, _\r\n ByVal dwReserved As LongPtr, _\r\n ByVal lpfnCB As LongPtr _\r\n ) As Long\r\n#Else\r\n Private Declare Function X_resize_Page1 Lib \"urlmon\" _\r\n Alias \"URLDownloadToFileA\" ( _\r\n ByVal pCaller As Long, _\r\n ByVal szURL As String, _\r\n ByVal szFileName As String, _\r\n ByVal dwReserved As Long, _\r\n ByVal lpfnCB As Long _\r\n ) As Long\r\n#End If\r\nLeveraging the API function URLDownloadToFileA to download a DLL payload.\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 4 of 21\n\nNSX detects the network traffic attempting to download the payload: \r\nNSX detection: attempting to download an executable file.\r\nThe payload is saved to the system’s %TEMP% directory upon successful download, which NSX detects as\r\nsuspicious behavior: \r\nNSX detection: dropping an executable file.\r\nThe downloaded DLL is then loaded with regsvr32.exe, which is detected by NSX as malicious behavior: \r\nNSX detection: document is executing regsvr32.exe.\r\nDLL Payload \r\nThe downloaded DLL (swwwbudo.dll) has the following basic properties: \r\nMD5  002c56165a0e78369d0e1023ce044bf0 \r\nSHA1  78ebfe4167a851bc75d9702aa1aea5efe1514b0c \r\nSHA256  a5ffce2a8d98ddc0ccc20744e88443eac323caf1cd8a218b8ccd50bc5ab8f1ac \r\nFile name  swwwbudo.dll \r\nSize  856064 bytes \r\nType  application/x-pe-dll-32bit-i386 \r\nThe properties of the downloaded DLL (swwwbudo.dll). \r\nThe code inside the DLL is obfuscated with multiple arithmetic operations using arbitrary integers, which\r\nmakes static analysis challenging. The obfuscated code is shown below: \r\nHRESULT __stdcall DllRegisterServer()\r\n{\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 5 of 21\n\nint v0; // edi\r\n int v1; // edx\r\n int v2; // ebx\r\n int v3; // eax\r\n int v4; // ecx\r\n int v6; // [esp+Ch] [ebp-4h]\r\n v0 = dword_6B50F03C;\r\n if ( dword_6B50F040 \u003e= (unsigned int)dword_6B50F03C )\r\n {\r\n word_6B50F020 -= dword_6B50F040;\r\n v0 = dword_6B50F03C - dword_6B50F040 - 12716;\r\n dword_6B50F03C = dword_6B50F03C - dword_6B50F040 - 12716;\r\n }\r\n dword_6B50F040 = (unsigned __int16)word_6B50F004 - v0 + 22;\r\n word_6B50F004 += dword_6B50F040 - v0 + 99;\r\n v1 = sub_6B49A180(0);\r\n v2 = (unsigned __int16)word_6B50F004 - dword_6B50F040 - v0;\r\n v6 = (unsigned __int16)word_6B50F004 + dword_6B50F040 + 49737;\r\n byte_6B50F006 += 2 - v2 - v6;\r\n word_6B50F044 += v2 - v1 + 99;\r\n if ( (unsigned __int16)word_6B50F022 - (unsigned __int16)dword_6B50F018 == 208 )\r\n {\r\n v3 = 2 * (unsigned __int16)v2 - 91;\r\n v4 = v1 - v2 + 12716;\r\n }\r\n else\r\n {\r\n v4 = v1 + 4 * (unsigned __int16)dword_6B50F018;\r\n LOWORD(v3) = word_6B50F004 - dword_6B50F040 + 8;\r\n }\r\n word_6B50F004 = v3;\r\n dword_6B50F040 = (unsigned __int16)v3 - v4 - v1;\r\n dword_6B50F000 = sub_6B49A180(v6);\r\n return (unsigned __int16)word_6B50F004;\r\n}\r\nCode obfuscation with multiple arithmetic operations using arbitrary integers.\r\nThe payload performs several steps: \r\n1. The shellcode gets is extracted into the .data section; \r\n2. The shellcode decrypts itself; \r\n3. The decrypted shellcode runs a copy of itself; \r\n4. The decrypted shellcode runs an embedded core DLL; \r\n5. The embedded core DLL communicates with the C\u0026C external host. \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 6 of 21\n\nMore details are discussed below. \r\nShellcode: first stage \r\nThe first–stage shellcode is stored in encrypted form in the .rdata section of the DLL. There are two functions\r\nresponsible for the shellcode decryption: \r\n1. The first one writes the shellcode into the .data section; \r\n1. The second one decrypts it. The decryption process gets called repeatedly until the code is successfully\r\ndecrypted. \r\nThe decryption takes ~30 seconds, generating an unusually high CPU load. The decrypted shellcode contains\r\nanother encrypted layer. There is a short code at the beginning of the shellcode that loops through the bytes\r\nand decrypts the XOR-encrypted code: \r\nseg000:6B511260 81 E9 4F DE 00 00 sub ecx, 0DE4Fh\r\nseg000:6B511266 E8 00 00 00 00 call $+5\r\nseg000:6B51126B 5B pop ebx\r\nseg000:6B51126C 8D 43 52 lea eax, [ebx+52h]\r\nseg000:6B51126F 81 C7 33 F0 00 00 add edi, 0F033h\r\nseg000:6B511275 BF F0 A0 78 50 mov edi, 5078A0F0h\r\nseg000:6B51127A 66 B9 7B 50 mov cx, 507Bh\r\nseg000:6B51127E B9 CE 09 00 00 mov ecx, 9CEh\r\nseg000:6B511283 66 81 C2 A9 B0 add dx, 0B0A9h\r\nseg000:6B511288 89 FA mov edx, edi\r\nseg000:6B51128A 31 DB xor ebx, ebx\r\nseg000:6B51128C\r\nseg000:6B51128C decryption_loop:\r\nseg000:6B51128C 81 EE 6D C4 00 00 sub esi, 0C46Dh\r\nseg000:6B511292 89 CE mov esi, ecx\r\nseg000:6B511294 83 E6 03 and esi, 3\r\nseg000:6B511297 75 1A jnz short do_xor\r\nseg000:6B511299 66 BB 1D 46 mov bx, 461Dh\r\nseg000:6B51129D 89 FB mov ebx, edi\r\nseg000:6B51129F 66 01 DA add dx, bx\r\nseg000:6B5112A2 66 F7 DA neg dx\r\nseg000:6B5112A5 6B D2 03 imul edx, 3\r\nseg000:6B5112A8 C1 CA 09 ror edx, 9\r\nseg000:6B5112AB 81 EF 81 FC 00 00 sub edi, 0FC81h\r\nseg000:6B5112B1 89 D7 mov edi, edx\r\nseg000:6B5112B3\r\nseg000:6B5112B3 do_xor:\r\nseg000:6B5112B3 30 10 xor [eax], dl\r\nseg000:6B5112B5 40 inc eax\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 7 of 21\n\nseg000:6B5112B6 E2 D4 loop decryption_loop\r\nseg000:6B5112B8 E9 46 05 00 00 jmp run_second_stage\r\nDecryption loop to decrypt the inner encrypted code.\r\nAfter the decryption, the shellcode finds the address of VirtualAlloc. It does so via a module list traversal taken\r\nfrom the PEB: \r\n1. Get pointer to _PEB: \r\n64 FF 35 30 00 00 00 push large dword ptr fs:30h\r\n58 pop eax\r\n2. Get pointer to _PEB_LDR_DATA from _PEB.Ldr: \r\n8B 40 0C mov eax, [eax+0Ch]\r\n3. Get pointer to _LDR_DATA_TABLE_ENTRY.InLoadOrderLinks from\r\n_PEB_LDR_DATA.InLoadOrderModuleList. This is the first structure that belongs to ll.dll: \r\n8B 48 0C mov ecx, [eax+0Ch]\r\n4. Enumerate _LDR_DATA_TABLE_ENTRY structures one that belongs to kernel32.dll. \r\nThis is a known technique widely used by malware. NSX detects this technique as well: \r\nNSX detection: presence of position independent code (shellcode).\r\nInstead of comparing strings of function names character–by–character, the DLL implements a string hashing\r\nalgorithm, as shown below:  \r\nseg000:6B5113EC hash_string:\r\nseg000:6B5113EC 8A 10 mov dl, [eax]\r\nseg000:6B5113EE 80 CA 60 or dl, 60h\r\nseg000:6B5113F1 01 D3 add ebx, edx\r\nseg000:6B5113F3 D1 E3 shl ebx, 1\r\nseg000:6B5113F5 03 45 10 add eax, [ebp+arg_8]\r\nseg000:6B5113F8 8A 08 mov cl, [eax]\r\nseg000:6B5113FA 84 C9 test cl, cl\r\nseg000:6B5113FC E0 EE loopne hash_string\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 8 of 21\n\nseg000:6B5113FE 31 C0 xor eax, eax\r\nseg000:6B511400 8B 4D 0C mov ecx, [ebp+arg_4]\r\nseg000:6B511403 39 CB cmp ebx, ecx\r\nseg000:6B511405 74 01 jz short loc_6B511408\r\nseg000:6B511407 40 inc eax\r\nThe string hashing code.\r\nThis is a known API hashing algorithm s, which was also seen in the Ursnif downloaders. This implies that the\r\nAPI hashing algorithm has been reused by both Ursnif and Dridex (code reuse by different malware writers is\r\ncommon. NSX identifies this specific technique:  \r\nNSX detection: makes use of a known API hashing algorithm.\r\nAfter successfully finding the address of VirtualAlloc, the shellcode then runs the second stage: \r\n1. Uses VirtualAlloc to allocate 0x3000 bytes of RWE memory; \r\n2. Uses the REP MOVSB to copy itself into the allocated chunk of memory; \r\n3. Calls JMP EAX to transfer execution to the copy of the code. \r\nIt’s worth pausing on the obfuscated offset used to access the shellcode’s memory. Instead of having zero\r\nas an offset, like a benign code would normally have, an extremely large offset 0x658871 was subtracted\r\nfrom the EBX register before retrieving the addresses of the functions stored in shellcode’s memory.\r\nE8 00 00 00 00 call $+5 ; Beginning of the shellcode\r\n5B pop ebx\r\n81 EB 71 88 65 00 sub ebx, 658871h\r\n...\r\nFF 93 68 88 65 00 call dword ptr [ebx+658868h] ; Pointer to VirtualAlloc\r\nA large offset is used to access shellcode’s memory.\r\nThe shellcode remembers that it has already been decrypted (a decryption flag has been set to True after the\r\ndecryption in the first stage discussed above) before jumping into the second copy. Therefore, this time the\r\ncode skips the decryption routine.   \r\nThe shellcode has an embedded DLL, which is termed core DLL herein. With VirtualAlloc the shellcode allocates\r\nmemory for the core DLL. VirtualProtect helps assign the correct memory access protection to each allocated\r\nmemory region. LoadLibraryExA and GetProcAddress help find the functions to be imported. \r\nCore DLL \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 9 of 21\n\nThe core DLL we dumped from memory has the following checksum (SHA1): \r\n 254b7ec984c3cdd479584c670822b9f65a31ce80 \r\nThe DLL might contain some trash bytes introduced by the memory dump process, which means the hash of the\r\nDLL shown above could be different from the one for the actual core DLL. \r\nThe DLL imports only Sleep and OutputDebugStringA. The addresses of other functions are obtained\r\ndynamically via two functions: \r\n1. Get module handle by hash; \r\n2. Get function address by hash. \r\nThese functions implement a standard function retrieval mechanism via the FS register, similar to the hash-based technique that was described previously. Whenever the DLL needs to call another function, it retrieves an\r\naddress dynamically and then makes a corresponding API call without storing pointers anywhere.  \r\nCalling API functions via the INT3-RET instruction pair.\r\nIn the example shown in the screenshot above, the code in the DLL performs a call to RegEnumKeyA (a Windows\r\nAPI function for enumerating the subkeys of an open registry key) via the INT3-RET instruction pair. More\r\nspecifically, the function call process can be summarized as follows: \r\n1. Retrieve the address of RegEnumKeyA and leave it in EAX; \r\n2. Push the function parameters to stack; \r\n3. Call INT 3 with RET instruction going afterwards; \r\n4. Execute RET with return address pointing to RegEnumKeyA; \r\n5. Transfer execution to RegEnumKeyA; return address points to instruction after RET (see the next\r\nscreenshot). \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 10 of 21\n\nReturn address points to instruction “test eax, eax” after RET instruction.\r\nThe trick here is that, prior to the function call, the DLL registers a VEH handler. The handler is called\r\nwhen the CPU raises an exception for INT 3. This is the prototype of a VEH handler:\r\nLONG PvectoredExceptionHandler(\r\n _EXCEPTION_POINTERS *ExceptionInfo\r\n)\r\n{...}\r\nThe prototype of a VEH handler.\r\nA handler is registered by calling AddVectoredExceptionHandler. The process performs the following steps\r\nif the exception handler gets called with STATUS_BREAKPOINT (0x80000003):\r\nExceptionInfo-\u003eContextRecord-\u003eEip++;\r\nExceptionInfo-\u003eContextRecord-\u003eEsp -= 4;\r\n*(DWORD*)ExceptionInfo-\u003eContextRecord-\u003eEsp = ExceptionInfo-\u003eContextRecord-\u003eEip + 1;\r\nExceptionInfo-\u003eContextRecord-\u003eEsp -= 4;\r\n*(DWORD*)ExceptionInfo-\u003eContextRecord-\u003eEsp = ExceptionInfo-\u003eContextRecord-\u003eEax;\r\nreturn 0xffffffff; // EXCEPTION_CONTINUE_EXECUTION\r\nThe multi-step process after the exception handler is called with STATUS_BREAKPOINT.\r\nIf one is not familiar with the technique, it can be confusing to see a lot of __debugbreak() across the code:\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 11 of 21\n\nint __usercall GetNtdllRtlHeapFuncs@\u003ceax\u003e(__m128i a1@\u003cxmm0\u003e)\r\n{\r\n int RtlAllocateHeap; // eax\r\n int (__cdecl *v2)(signed int, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD); // ebp\r\n if ( dword_6BB9B1E0 == 0xE99C89BF )\r\n {\r\n v2 = (int (__cdecl *)(signed int, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))GetProcAddressByHash(\r\n a1,\r\n 1485485034,\r\n -1061782048);\r\n g_RtlDestroyHeap = GetProcAddressByHash(a1, 1485485034, -2100136764);\r\n if ( dword_6BB9B1E0 == 0xE99C89BF )\r\n dword_6BB9B1E0 = v2(2, 0, 0, 0, 0, 0);\r\n }\r\n RtlAllocateHeap = GetProcAddressByHash(a1, 1485485034, 0x996E050F);\r\n if ( !RtlAllocateHeap )\r\n return 0;\r\n __debugbreak();\r\n return RtlAllocateHeap;\r\n}\r\n_debugbreak() is called in the code. _debugbreak() is an intrinsic command of the Microsoft compiler which\r\ndirectly translates to the INT 3 assembly instruction. Whenever an INT 3 instruction is called, it raises an\r\nexception.\r\nIn addition to the challenging static analysis described above, the debugger pops up every time INT 3 executes.\r\nSuppressing the STATUS_BREAKPOINT exception can be done in debugger settings, and it doesn’t affect the\r\ndebugging process: \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 12 of 21\n\nDebugger works well by ignoring the INT 3 exceptions.\r\nConnection to C\u0026C \r\nThe DLL has four IP:port pairs of C\u0026C servers, through which it iterates: \r\n194.225.58.214:443\r\n211.110.44.63:5353\r\n69.164.207.140:3388\r\n198.57.200.100:3786\r\nC\u0026C server and port pairs.\r\nThe DLL feeds IP address and port to InternetConnectW during a connection attempt. After\r\nthat, HttpOpenRequestW is called to initiate a POST request to the root folder of a web server. It\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 13 of 21\n\nprovides the following flags to HttpOpenRequestW: \r\nINTERNET_FLAG_SECURE – use PCT/SSL if applicable (HTTP); \r\nINTERNET_FLAG_IGNORE_CERT_CN_INVALID – bad common name in X509 certificate; \r\nINTERNET_FLAG_IGNORE_CERT_DATE_INVALID – expired X509 certificate; \r\nINTERNET_FLAG_NO_AUTO_REDIRECT – don’t handle redirections automatically; \r\nINTERNET_FLAG_RELOAD – retrieve the original item; \r\nINTERNET_FLAG_NO_UI – no cookie popup. \r\n Combining the flags of INTERNET_FLAG_SECURE and INTERNET_FLAG_IGNORE_CERT_XXX makes\r\nthe connection secure and forces wininet.dll to ignore problems with server-side SSL certificates. \r\nAs soon as the connection is established, the DLL calls HttpSendRequestW to transfer ~5 KB\r\nof encrypted data about the target environment:\r\n00009190 51 0C 69 4B 1D 79 D8 51 7C 6D A7 75 C9 4A 16 49 Q.iK.yØQ|m§uÉJ.I\r\n000091A0 38 58 CC DA F0 C9 C9 57 8C BA 0E C2 9D 61 77 F0 8XÌÚðÉÉWŒº.Âawð\r\n000091B0 E8 44 AF 89 DE 8D 41 F0 CD F2 F4 F6 C2 7C 95 D5 èD¯‰ÞAðÍòôöÂ|•Õ\r\n000091C0 48 29 F1 D5 A0 7A FF 55 9D E5 1A A7 19 19 72 C4 H)ñÕzÿUå.§..rÄ\r\n000091D0 E2 B0 E2 DF 43 60 22 0D 3B 9F 82 20 08 39 D0 F5 â°âßC`\".;Ÿ‚ .9Ðõ\r\n000091E0 74 84 C6 5D E7 19 78 23 08 52 D5 AF 8F 49 C0 E3 t„Æ]ç.x#.RÕ¯IÀã\r\n000091F0 19 7F B4 9F B9 D0 76 76 C3 3E F1 C8 BE 7C BE 01 .´Ÿ¹ÐvvÃ\u003eñÈ¾|¾.\r\n00009200 93 8D CB 29 1C 9E A4 32 86 BD B1 19 0E D7 B3 64 “Ë).ž¤2†½±..×³d\r\n00009210 BA 17 69 D6 A7 E3 09 08 79 97 7A 50 73 87 44 8E º.iÖ§ã..y—zPs‡DŽ\r\n00009220 4B F7 2C 79 18 26 62 AD ED 7A A2 F9 77 18 D9 70 K÷,y.\u0026bíz¢ùw.Ùp\r\n00009230 C3 A9 C6 2D C5 B0 17 78 9C 34 45 48 D0 9B 19 E4 Ã©Æ-Å°.xœ4EHÐ›.ä\r\n...\r\nData collected from the victim’s machine is encrypted prior to exfiltration.\r\nNSX detects the network traffic to the Dridex C\u0026C server: \r\nNSX detection: network traffic to a Dridex C\u0026C server. \r\nComparison with old Dridex samples \r\nTo find out how the TTPs used by the samples from the recent campaign differ from Dridex samples seen in the\r\npast, we performed a comparison study.  \r\nThe table below lists some typical samples collected from previous Dridex campaigns: \r\nOld samples  SHA1 \r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 14 of 21\n\nXLS (2020.4)  c2c873baf147aa74843382a1e2dae33659bd49d5 \r\nDLL (2020.4) \r\n1c3bd35dd430c10a4dd2e188ebad12cc85b6fa63 \r\n0554438b88e9463f6c8f040ba2370359ed42d80c (64-bit) \r\nDLL (2020.11)  1c6dfce105f9af04358901c46a50a8f419b621fb \r\nDLL (2020.12)  d240ad10acf8f15e8ac29fa8bee58796900bc55a \r\nDridex samples from past campaigns.  \r\nBased on our analysis, we make the following observations: \r\n1. Samples from 2020.4 and 2020.11 are very different from the samples from the new wave,\r\nexcept for the 64-bit DLL (0554438b88e9463f6c8f040ba2370359ed42d80c): the VEH implementation in\r\nthis older sample looks very similar to the approach described above. \r\n2. The code obfuscation method of the DLL from 2020.12 is very similar to swwwbudo.dll from the new\r\nwave. \r\nA detailed comparative analysis can be found in the Appendix. \r\nConclusion \r\nIn this report, we analyzed some samples from a recent wave of Dridex infections. As usual, the infection process\r\nstarts with a spam campaign using social engineering emails with malicious attachments (XLSM in this case). The\r\nattack comprises two main stages. The first stage is to leverage malicious VBA macros embedded in the XLSM\r\nfile to download the initial Dridex payload. In the second stage, the payload runs an embedded DLL from\r\nmemory, which then exfiltrates data collected from the infected system. Our analysis demonstrates that the\r\nmalware writer used various TTPs in the attack, including downloading a\r\nDLL payload via URLDownloadToFileA, using an API hashing algorithm to locate function\r\nnames, and registering a VEH handler to complicate analysis. \r\nIn addition, we also compared the new samples from the recent wave to some previous samples collected\r\nsince April 2020. Our comparison analysis shows that tricks such as using the VEH handler and code\r\nobfuscation used in the new samples were also seen in some past samples. However, to a large extent, the new\r\nsamples are very different from the old Dridex variants. \r\nVMware’s NSX Advanced Threat Prevention offering for the NSX Service-defined Firewall delivers the broadest\r\nset of threat detection capabilities that span network IDS/IPS and behavior-based network traffic analysis. This\r\nalso includes VMware NSX Advanced Threat Analyzer™, a sandbox offering based on a full-system emulation technology that has visibility into every malware  action. VMware NSX is purpose-built to\r\nprotect data center traffic with the industry’s highest fidelity insights into advanced threats.  \r\nBibliography\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 15 of 21\n\n[1]\r\nCheck Point, “March 2020’s Most Wanted Malware: Dridex Banking Trojan Ranks On Top Malware\r\nList For First Time,” March 2020. [Online]. Available: https://blog.checkpoint.com/2020/04/09/march-2020s-most-wanted-malware-dridex-banking-trojan-ranks-on-top-malware-list-for-first-time/.\r\nAppendix: Comparison with old Dridex samples\r\nXLS (2020.4) – sha1: c2c873baf147aa74843382a1e2dae33659bd49d5\r\nThis file also leverages social engineering techniques to display content related to a logistic invoice, but it looks\r\ncompletely different from the new XLSM sample.\r\nThe opening page of the XLS sample.\r\nThe embedded VBA macro code in the sample looks plain, and it doesn’t run regsvr32.dll:\r\nSub toggle()\r\nOn Error Resume Next\r\nWScript.Quit (CreateObject(\"WScript.Shell\").Run(undo(11000 + 956), 0, False))\r\nOn Error GoTo 0\r\nEnd Sub\r\nPrivate Sub google_Layout(ByVal Index As Long)\r\ntoggle\r\nEnd Sub\r\nFunction undo(home As Integer)\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 16 of 21\n\nDim tsi(): Dim Lo As Integer\r\nmodul = echo(ActiveSheet.[E90:E106], \"\")\r\nFor apo = 1 To Len(modul)\r\n ReDim Preserve tsi(apo)\r\n tsi(apo) = Mid(modul, apo, 1)\r\nNext\r\ntk = \"\"\r\nFor Lo = 0 To home Step 4\r\ntk = tk + tsi(Lo)\r\nNext\r\nundo = tk\r\nEnd Function\r\nEmbedded VBA macro code in the XLS sample.\r\nThis implies that this sample is different from the new XLSM sample.\r\nDLL (2020.4) – sha1: 1c3bd35dd430c10a4dd2e188ebad12cc85b6fa63\r\nThis DLL doesn’t have DllRegisterServer in the exports. DllEntry is not obfuscated, and it uses normal API calls\r\nsuch as GetWindowsDirectoryA, CreateSemaphoreA and GetCurrentDirectoryA.\r\nThe sample doesn’t look similar to the new swwwbudo.dll.\r\nDLL (2020.4) – sha1: 0554438b88e9463f6c8f040ba2370359ed42d80c\r\nThis is a 64-bit DLL, unlike the new one, which is 32-bit. The code inside the DLL is not obfuscated. The DLL\r\ndoesn’t have DllRegisterServer in exports. It imports 4 functions: AddVectoredExceptionHandler,\r\nGetComputerNameW, ExitProcess, GetExitCodeProcess. It is worth noting that the VEH handler used in the DLL\r\nis very similar to the one used by the new sample described above:\r\nsigned __int64 __fastcall VEH_handler(struct _EXCEPTION_POINTERS *ExceptionInfo)\r\n{\r\n struct _EXCEPTION_POINTERS *v1; // rbx\r\n DWORD v2; // edx\r\n void (__fastcall *v4)(_QWORD); // rax\r\n v1 = ExceptionInfo;\r\n v2 = ExceptionInfo-\u003eExceptionRecord-\u003eExceptionCode;\r\n if ( v2 != 0x80000003 )\r\n {\r\n if ( v2 != 0xC0000005 \u0026\u0026 v2 != 0xC00000FD \u0026\u0026 v2 != 0xC0000374 )\r\n return 0i64;\r\n v4 = (void (__fastcall *)(_QWORD))sub_180049720(7851018113971630002i64);\r\n if ( v4 )\r\n v4(0i64);\r\n }\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 17 of 21\n\n++v1-\u003eContextRecord-\u003eRip;\r\n v1-\u003eContextRecord-\u003eRsp -= 8i64;\r\n *(_QWORD *)v1-\u003eContextRecord-\u003eRsp = v1-\u003eContextRecord-\u003eRip + 1;\r\n v1-\u003eContextRecord-\u003eRsp -= 8i64;\r\n *(_QWORD *)v1-\u003eContextRecord-\u003eRsp = v1-\u003eContextRecord-\u003eRax;\r\n return 0xFFFFFFFFi64;\r\n}\r\nThe VEH handler used in the DLL.\r\nHowever, the DLL doesn’t implement the INT 3 technique described above. Though the sample doesn’t look\r\nsimilar to the new swwwbudo.dll, the code for VEH handler used to manipulate registers is identical to the code\r\nfound in the new swwwbudo.dll, which led us to believe that both samples were coming from the same author.\r\nDLL (2020.11) – sha1: 1c6dfce105f9af04358901c46a50a8f419b621fb\r\nThe DLL doesn’t have DllRegisterServer in exports. There are following imports:\r\nList of imports used by the DLL.\r\nThe main function looks completely different from the new swwwbudo.dll:\r\n.text:004042E1 push off_424DEC\r\n.text:004042E7 pop eax\r\n.text:004042E8 jmp eax\r\nThe main function in the DLL.\r\nThe inner code also looks very different:\r\nsigned int sub_4014E0()\r\n{\r\n signed int v1; // [esp+40h] [ebp-4Ch]\r\n __int16 v2; // [esp+46h] [ebp-46h]\r\n __int16 v3; // [esp+46h] [ebp-46h]\r\n int v4; // [esp+48h] [ebp-44h]\r\n signed int v5; // [esp+4Ch] [ebp-40h]\r\n char v6; // [esp+56h] [ebp-36h]\r\n __int16 v7; // [esp+64h] [ebp-28h]\r\n __int16 v8; // [esp+68h] [ebp-24h]\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 18 of 21\n\n__int16 v9; // [esp+76h] [ebp-16h]\r\n __int16 v10; // [esp+78h] [ebp-14h]\r\n __int16 v11; // [esp+7Ah] [ebp-12h]\r\n __int16 v12; // [esp+7Ch] [ebp-10h]\r\n __int16 *v13; // [esp+80h] [ebp-Ch]\r\n v1 = 1;\r\n if ( !GetModuleHandleA(\"gernel33.dll\") )\r\n {\r\n v13 = \u0026v8;\r\n v3 = v2 * v2;\r\n sub_4051A4(\u0026v8, L\" estapp \", 24);\r\n v8 = 116;\r\n v9 = 46;\r\n v10 = 101;\r\n v11 = 120;\r\n v12 = 101;\r\n v5 = 1;\r\n if ( !LoadLibraryW(\u0026v8) )\r\n {\r\n sub_4051A4(\u0026v6, L\"self.ex \", 18);\r\n v7 = 69;\r\n if ( GetModuleHandleW(\u0026v6) )\r\n {\r\n v5 = 0;\r\n }\r\n else\r\n {\r\n v4 = 0;\r\n sub_40126C(\"tttt32\");\r\n do\r\n {\r\n GetFocus();\r\n v3 ^= 0x8019u;\r\n ++v4;\r\n v5 = 0;\r\n RegSaveKeyExA(0, 0, 0, 0);\r\n }\r\n while ( v4 != 1023 );\r\n }\r\n }\r\n v1 = v5;\r\n }\r\n return v1;\r\n}\r\nThe inner code in the DLL.\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 19 of 21\n\nThe code difference shows that this sample is not similar to the new swwwbudo.dll.\r\nDLL (2020.12) – sha1: d240ad10acf8f15e8ac29fa8bee58796900bc55a\r\nThere are two DllRegisterServer and DllUnregisterServer functions in the export table, similar to the new\r\nswwwbudo.dll. The code obfuscation also looks similar:\r\nHRESULT __stdcall DllRegisterServer()\r\n{\r\n int v0; // ecx\r\n char v1; // al\r\n DWORD v2; // edx\r\n int v3; // eax\r\n unsigned __int8 v4; // bl\r\n int v5; // ebp\r\n int v6; // edx\r\n HRESULT result; // eax\r\n int v8; // [esp+14h] [ebp-4h]\r\n dword_3A8008 = dword_3A800C + 41;\r\n v0 = dword_3A800C + 41 - dword_3A8074;\r\n dword_3A8004 = dword_3A8074 - dword_3A800C - 4;\r\n v1 = -3 - dword_3A8074 + 10;\r\n dword_3A8074 = (unsigned __int8)(-3 - dword_3A8074) + dword_3A800C + 43;\r\n v8 = dword_3A8074 + dword_3A8004 - 93;\r\n dword_3A8000 = v0 + dword_3A800C + 41 + dword_3A8074 - 98;\r\n byte_3A8070 = -(char)v8 - 47 * dword_3A8074 + dword_3A8074 + 2 * v1;\r\n dword_3A800C = dword_3A8074 + dword_3A8000 + 2 * (dword_3A800C + 41 + 2 * (dword_3A800C - 37110)) -\r\n v2 = GetModuleFileNameA(0, Filename, 0x5AFu);\r\n v3 = dword_3A8074;\r\n word_3A8078 = dword_3A8074 - dword_3A8000 - 4;\r\n if ( dword_3A803C == 154 )\r\n v3 = v2 - dword_3A8028 + dword_3A8074 + 2;\r\n v4 = v8 - v3 - 4;\r\n dword_3A8008 = dword_3A800C - v8 + 42;\r\n v5 = dword_3A8000 - v3 - 4;\r\n v6 = dword_3A800C - v8 + 42 - v3;\r\n dword_3A8074 = v4 + dword_3A800C - v8 + 44;\r\n byte_3A8070 = v4 + dword_3A800C + 44 + 2 * v4 + 19;\r\n dword_3A800C = dword_3A800C + 42 + 2 * dword_3A800C - 74221;\r\n dword_3A8000 = dword_3A8074 + v6 + dword_3A8008 - 98;\r\n result = 40461 * dword_3A8074 - v5;\r\n dword_3A8004 = result;\r\n return result;\r\n}\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 20 of 21\n\nObfuscated code in the DLL, which is similar to the new swwwbudo.dll.\r\nThere is a third function in the export table with a random name. The way strings are passed to function calls in\r\nthis function is similar to the method implemented in the new swwwbudo.dll. This implies that the sample is very\r\nsimilar to the new swwwbudo.dll.\r\nSource: https://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nhttps://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/\r\nPage 21 of 21",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blogs.vmware.com/networkvirtualization/2021/03/analysis-of-a-new-dridex-campaign.html/"
	],
	"report_names": [
		"analysis-of-a-new-dridex-campaign.html"
	],
	"threat_actors": [],
	"ts_created_at": 1775439086,
	"ts_updated_at": 1775791221,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/c90eda83b017149ebf1216261a9cf0bc84cbdff0.pdf",
		"text": "https://archive.orkl.eu/c90eda83b017149ebf1216261a9cf0bc84cbdff0.txt",
		"img": "https://archive.orkl.eu/c90eda83b017149ebf1216261a9cf0bc84cbdff0.jpg"
	}
}