{
	"id": "b87ea7b4-f958-4079-968d-bf66b3e6cc4b",
	"created_at": "2026-04-06T01:29:50.000875Z",
	"updated_at": "2026-04-10T13:11:30.758228Z",
	"deleted_at": null,
	"sha1_hash": "10e93921eff8330eb0caf3af1936b489c9f4bea1",
	"title": "IcedID – Technical Malware Analysis [Second Stage] - 0x0d4y Malware Research",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 6381334,
	"plain_text": "IcedID – Technical Malware Analysis [Second Stage] - 0x0d4y Malware\r\nResearch\r\nBy 0x0d4y\r\nPublished: 2024-01-09 · Archived: 2026-04-06 00:10:30 UTC\r\nIn this report I will technical analyze the new IcedID malware, go deep through reverse engineering, debugging and\r\ndetection engineering.\r\nIntroduction\r\nThe IcedID is a banking malware design to steal financial information from your victims. The IcedID malware is also know\r\nby MITRE ATT\u0026CK as S0483, and has been around since 2017. The IcedID has been used by GOLD CABIN (also knows\r\nas TA551 by MITRE ATT\u0026CK), in a lot of campaign since 2017, but recently in a Covid-19 pandemic, they execute a\r\ncampaign of Phishing emails with malicious attachments (1st stage that download the loader) to download and execute the\r\nIcedID.\r\nSome public threat reports points to a modular capability of IcedID trojan, this makes this malware family a greater\r\nevolution compare to Zeus malware. This modular capability of IcedID is due to the fact that the malware downloads,\r\nthrough network communication with command and control servers, new modules if necessary during the campaign.\r\nIn 2017, when IcedID emerge in the cyber scenario, has been observed the IcedID malware was delivery through Emotet\r\ninfections. Emotet has been a distribution of the elite malware baking trojans, like Qbot and Dridex, and since 2017 the\r\nIcedID was added in their list of malware distribution.\r\nCapabilities\r\nIn the samples that I will use as an objects of research for this article, I identified the following MITRE ATT\u0026CK Tactics and\r\nTechniques.\r\nATT\u0026CK Tatic ATT\u0026CK Technique\r\nDEFENSE EVASION Obfuscated Files or Information [T1027]\r\nDEFENSE EVASION Process Injection [T1055]\r\nDEFENSE EVASION Virtualization/Sandbox Evasion: System Checks [T1497.001]\r\nDEFENSE EVASION\r\nVirtualization/Sandbox Evasion: Time Based Evasion\r\n[T1497.003]\r\nDISCOVERY Account Discovery [T1087]\r\nDISCOVERY File and Directory Discovery [T1083]\r\nDISCOVERY System Owner/User Discovery [T1033]\r\nCOMMAND AND\r\nCONTROL\r\nApplication Layer Protocol: Web Protocols [T1071.001]\r\nFurthermore, it was identified that this samples, and members of its family, contain the following capabilities according to\r\nMalware Behavior Catalog.\r\nANTI-BEHAVIORAL\r\nANALYSIS\r\nDebugger Detection::Anti-debugging Instructions [B0001.034]\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 1 of 28\n\nCOMMUNICATION\r\nHTTP Communication::Create Request [C0002.012]\r\nHTTP Communication::Get Response [C0002.017]\r\nHTTP Communication::Read Header [C0002.014]\r\nHTTP Communication::WinHTTP [C0002.008]\r\nCRYPTOGRAPHY\r\nEncrypt Data::RC4 [C0027.009]\r\nEncryption Key::RC4 KSA [C0028.002]\r\nGenerate Pseudo-random Sequence::RC4 PRGA [C0021.004]\r\nDATA Encode Data::XOR [C0026.002]\r\nDEFENSE EVASION\r\nObfuscated Files or Information::Encoding-Standard Algorithm\r\n[E1027.m02]\r\nDISCOVERY\r\nAnalysis Tool Discovery::Process detection [B0013.001]\r\nFile and Directory Discovery [E1083]\r\nFILE SYSTEM\r\nCreate Directory [C0046]\r\nRead File [C0051]\r\nWrites File [C0052]\r\nPurpose of this Technical Article\r\nThis is a technical article, which aims to analyze the IcedID second loader. This article will not focus on network traffic\r\nanalysis, mainly due to the fact that there are already excellent articles written by techevo. You can access these articles by\r\nclicking here.\r\nThis analysis will understood as the study of WHAT and HOW IcedID executes its Tactics, Techniques and Procedures.\r\nThis type of analysis is performed through static analysis through Reverse Engineering, and through dynamic analysis\r\nperformed through a Debugger.\r\nAfter performing such an analysis, this report will focus on two topics:\r\nWhat are the similarities between samples from different years?\r\nDevelopment of Yara detection rules, with the aim of detecting IcedID infections.\r\nIn this article I will focus the analysis on an IcedID sample that was seen in 2020. However, at the end of the technical\r\nanalysis, we will analyze in more depth the similarities between two more samples, from different years. Below you can see\r\nthe SHA-256 hash from it, and the link for download the sample.\r\n76cd290b236b11bd18d81e75e41682208e4c0a5701ce7834a9e289ea9e06eb7e new_iced.exe\r\nLink to download this sample, here.\r\nThis same sample has been executed into AnyRun Sandbox, but, the AnyRun don’t identify this IcedID sample as a threat.\r\nThe same sample has been executed into Triage Sandbox, and it’s not identify at malicious too. This indicates the sample has\r\na sandbox evasion technique, to not be detected by sandbox or other detection methods.\r\nStatic Analysis\r\nNow let’s start our analysis of this sample, and first, let’s identify some screening information to understand the sample we\r\nhave in hand.\r\nStatically analyzing DLL imports, we can observe the import of two DLLs:\r\nole32.dll\r\nkernel32.dll\r\nWhat catches our eye is the amount of kernel32.dll imports, but 67 functions is explicit imported. This can confuses the\r\nanalyst, when we are looking for binary packed pattern. But, into the 67 imported functions, we can identify the\r\nVirtualProtectEx import.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 2 of 28\n\nThe VirtualProtectEx API is often used by malware to modify memory protection in a process (often to allow write or\r\nexecution).\r\nWith the standard output, Capa cannot identify that sample is packed.\r\nresearcher@malwarelab:~$ capa new_iced.exe\r\n ┍━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━\r\n │ md5 │ 17091a1e444f306b928d69f2b905bc8b\r\n │ sha1 │ 1078744833050626e9681c7c233c3a0963a0b559\r\n │ sha256 │ 76cd290b236b11bd18d81e75e41682208e4c0a5701ce7834a9e289ea9e06eb7e\r\n │ os │ windows\r\n │ format │ pe\r\n │ arch │ i386\r\n │ path │ /home/researcher/malware/new_iced.exe │\r\n ┕━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━\r\n ┍━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━\r\n │ ATT\u0026CK Tactic │ ATT\u0026CK Technique\r\n ┝━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━\r\n │ DISCOVERY │ File and Directory Discovery T1083\r\n ├────────────────────────┼─────────────────────\r\n │ EXECUTION │ Shared Modules T1129\r\n ┕━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━\r\n ┍━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━\r\n │ MBC Objective │ MBC Behavior\r\n ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━\r\n │ DISCOVERY │ File and Directory Discovery [E1083]\r\n ┕━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━\r\n ┍━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n │ Capability │ Namespace\r\n ┝━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\n │ contains PDB path │ executable/pe/pdb\r\n │ get common file path │ host-interaction/file-system\r\n │ print debug messages │ host-interaction/log/debug/write-ev\r\n │ get thread local storage value │ host-interaction/process\r\n │ link many functions at runtime │ linking/runtime-linking\r\n ┕━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\r\nThis is probably due to the low entropy of the sample (despite the .text section being tagged as packed, by DiE). High\r\nentropy is generally an easy indicator of using encryption in samples. In this case, as we can see in the image below, the\r\nentropy is below 7.0.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 3 of 28\n\nFrom here, we need to make sure this is not a sample that is not packed. To do this, we will dynamically analyze the sample,\r\nwith the aim of discovering the existence of its unpacking routine.\r\nUnpacking with x32dbg – new_iced.exe\r\nWe saw in previous sections of this article, that any sandbox or tool, can be capable to identify that this sample is packed, or\r\neven malicious. But, in our static analysis, we find the VirtualProtect API call, and this API is widely used for unpacking\r\nprocess.\r\nSo, let’s diving in, and figure out that this sample is really packed or not, with the x32dbg.\r\nOn the x32dbg, we need to set some breakpoints on APIs, that is commonly used to run the unpacking process. Are they:\r\nVirtualAlloc – is often used by malware to allocate memory as part of process injection.\r\nVirtualProtect – is often used by malware to modify memory protection (often to allow write or execution).\r\nCreateProcessInternalW – is an undocumented API for process creation. According to Windows Internals,\r\nCreateProcess and CreateProcessAsUser actually lead to this API, which is responsible for starting the process\r\ncreation in user land. Eventually it calls NtCreateUserProcess for the kernel land operations. This API is commonly\r\nused for spawning a suspended process to be hollowed/injected.\r\nA lot of others APIs can be used, but, this three is commonly used by packers.\r\nAs a precaution, we will set a breakpoint at IsDebuggerPresent in case the example implements some Anti-Debugging\r\ntechniques.\r\nBelow, we can see the breakpoints setup.\r\nThe first breakpoint match in the VirtualAlloc API has been triggered, so we need to press execute till returns, and run again\r\nthe sample, so we can observe memory allocation and filling. This allocation and completion will be stored in the EAX\r\nregister.\r\nWe need to follow in dump on EAX memory space, to visualize the allocation and filling with data (possible shellcode on\r\nfirst round, and soon will be the unpack IcedID).\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 4 of 28\n\nThis process, need to be done three times in this sample (maybe is less or more in other samples), until we can get the\r\nunpacked IcedID. After repeat this process three times, we get our strange MZ header.\r\nThe M8Z header is what we see on EAX register’s memory space, after unpacking process is done. This header is a\r\nreference to APlib, that is widely used to compress malware. Generally, when we find a PE artifact, with the APlib magic\r\nnumber, we can be sure that the binary is already unpacked in some memory space close to the artifact packed with APlib.\r\nSo let’s find the decompress IcedID.\r\nFinding the Decompressed Unpacked IcedID\r\nWhen the last VirtualAlloc breakpoint is reached, the next breakpoint is the VirtualProtect (is the API that set protections\r\nconfiguration on that memory region). We can press execute till return, to reached the end of the function, and then, exit the\r\ncode related to the VirtualProtect API and return to the sample code.\r\nAfter that, we will be redirected to the some instructions that manipulate some address to registers. To try to find the\r\ndecompressed unpacked IcedID, we need to look the dump of each address of the next instructions on the x32dbg.\r\nAfter some try and failure, we encounter the decompressed unpacked IcedID, on the follow instruction in 00C407F7 offset.\r\nmov esi,dword ptr ds:[ebx+7014C2]\r\nBelow we can identify the truly unpacked IcedID on the 00C60CD3 address.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 5 of 28\n\nTo validate this information, we can go to the Memory Map tab on the 32xdbg, and look at 00C60CD3 address protections.\r\nAs we can see below, this region of memory has Execute (E), Read (R) and Write (W) protections. This indicates that\r\nunmapped region, has the same rights of one executable.\r\nNow that we found our unpacked IcedID, we need to save him into a file. To do this, we need to select all data on the dump\r\ntab that we identify the unpacked malware, and save to a file.\r\nNow, we have our real IcedID, so let’s reverse engineering it.\r\nReverse Engineering – unpacked_iced.exe\r\nBefore we diving in on reverse engineering, let’s take a look at some triage information of the unpacked sample.\r\nBelow we can see the import of four DLLs (unlike the packed version). Being them:\r\nkernel32.dll\r\nwinhttp.dll\r\nuser32.dll\r\nadvapi32.dll\r\nshell32.dll\r\nHowever, we will only highlight the most important ones.\r\nThe first API that catches our eye, due to its capabilities, is WINHTTP.dll. This DLL gives the sample the capabilities of\r\nnetwork connection. And, in the import functions, we can identify network connections related functions as we can see\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 6 of 28\n\nbelow.\r\nThe second DLL of note is KERNEL32.dll. As we can see in the image below, this DLL gives the sample the ability to\r\nperform file and directory manipulations, in addition to enabling memory space manipulation, allowing the execution of\r\ntechniques such as code injection into memory.\r\nThis indicates, that the unpacked IcedID have the capability of do some, write file to execute the next stage, code injection\r\nto evade detection, and network communications to connect to the command and control server. As we can see on public\r\nthreat intell, the IcedID is a modular banking trojan. Network-related API imports are a hint of these modular features of\r\nIcedID, as seen in the public threat reports described in the introduction sections.\r\nNow, that we understand possible functionalities, let’s dive in on reverse engineering.\r\nNOTE: The name of internal functions, variables and data chunks are renamed by me, and it’s not the default way\r\nthat disassembler/decompiler produce.\r\nThe first function is start. This section contains only the IcedID main function, and then the call to the ExitProcess API.\r\nNow let’s analyze the iced_2020_main function. Below, we can see the logical structure of the code.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 7 of 28\n\nBelow, we can see the main function, which can be done through IDA pseudo-code. The image below allows us to identify\r\nthe main features of this IcedID sample:\r\nCreation of the c:\\\\Users\\\\Public\\\\ directory, where the photo.png file will probably be stored.\r\nExecution of a decryption routine, using the RC4 algorithm (function rc4_routine). It is interesting to note that the\r\nIDA Decompiler interpreted a series of setup instructions for calling the routine, as an array\r\n(key_and_data_decryption_array). And in this array, we are presented with information such as the size and\r\nposition of the decryption key, the data to be decrypted and the address of all this data (in the .data section, as we can\r\nsee the data reference below).\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 8 of 28\n\nA series of conditionals to execute the creation of the photo (file_creation_photo_png function).png file, collection\r\nof hardware information and network communication with the c2 servers (hardware_info_net_connection\r\nfunction).\r\nAnd the last function to be executed is a function that carries out a series of instructions, which resemble the memory\r\ncode injection technique (code_injection function), using the data encrypted in .data.\r\nThe first block of instructions in the sample, which involve the use of the CreateDirectoryA and GetUserNameA API,\r\nwith the purpose of building the path to create a directory (if not existing), with the purpose of dropping the photo.png into\r\nit, is very straight to the point. Therefore, we will focus on the function that performs the data decryption process\r\n(rc4_routine), using the RC4 algorithm.\r\nBelow, we can observe the pseudo-code of the rc4_routine function, which shows us the Heap allocation in memory with\r\nthe data present in the .data section (apparently the key + data), the call of the rc4_ksa_prga function, which we will see the\r\ncore of its operation below , and the execution of the XOR stage of the RC4 encryption algorithm. It is at this stage that the\r\n248 bytes after the key are decrypted.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 9 of 28\n\nInside of the rc4_routine function, we can analyze the core of another function called rc4_ksa_prga. As we can see below,\r\nthis function have a rc4 KSA/PRGA routine pattern. This pattern is the two first stages of the rc4 algorithm.\r\nAs we can see in the image below, after executing the decryption routines, the CPU will do a test between the EAX register,\r\nand jump to the file_creation_photo_png function if the result is not zero.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 10 of 28\n\nLet’s dive in the instructions of file_creation_photo_png.\r\nBefore we continue the analysis, we need to remember the pseudo-code of the IcedID main function. As we can see below,\r\nthe file_creation_photo_png function takes three arguments.\r\npszPath\r\nlpBuffer\r\nNumberOfBytesToWrite\r\npszPath in particular underwent a series of transformations throughout the execution of the Main function. And when it is\r\nused as an argument in the file_creation_photo_png function, it is the absolute path of the photo.png file.\r\nWith this in mind, let’s look at the pseudo-code of the file_creation_photo_png function, and next, we’ll analyze its\r\nfunctionality.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 11 of 28\n\nAs we can see in the pseudo-code above, the function is very straight to the point, where the process of creating a handle for\r\nthe photo.png file is basically executed, and the allocation of this handle in memory. During the end of the execution of the\r\nfile_creation_photo_png function, it is possible to observe the cleaning being carried out.\r\nAfter executing the photo.png file handle creation function, the CPU will perform a test in the EAX register and skip the\r\ncontrol flow to the hardware_info_net_connection function, if the condition is met. If the condition is not met, the flow will\r\njump to executing the heap_allocation function.\r\nIt is important to note (as we can see in the image below) that this function is called twice in the main function. One if the\r\nconditions are not met after creating the photo.png file handle, and another if the conditions are not met after executing the\r\nhardware information collection function and HTTP network communication routine.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 12 of 28\n\nBy analyzing what the heap_allocation function does, we can understand why it is executed if a certain function is not\r\ncompleted as expected. In the pseudo-code below, you can see that this function performs a series of calculations to\r\ndetermine the size of the buffer to be allocated on the heap, with the purpose of allocating the data present in .data (rc4 key\r\nand encrypted data). After this allocation, the rc4_routine function is executed to decrypt the data in memory.\r\nReturning to the normal sample flow, when executing the handle creation function for the photo.png file, if conditionals are\r\nmet, the flow will jump to the hardware_info_net_connection function.\r\nAs we can see on pseudo-code below, inside of the hardware_info_net_connection function, has two main functions, the\r\nhardware_info_collection and the http_connection.\r\nThe hardware information, was implemented in the code is based on timestamp of the device, and the CPU model.\r\nAnalyzing the call of _cpuid, with just a little research on Google, we can find that matches with VMware hypervisor\r\nCPUID. That value, is the same that we can see on IcedID.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 13 of 28\n\nHowever, during the dynamic analysis, we will discover that the hardware information collected by IcedID will be used to\r\nbuild the HTTP request to be sent to C2.\r\nIf everything was of expected, the code will continue and execute a network related function, and after that, will check if the\r\nresult of the communication results in a 200 HTTP status code.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 14 of 28\n\nBelow, we can see the decompiler version of the code above.\r\nLet’s dive in the function http_connection_func.\r\nAnalysis of http_connection Function\r\nAll plaintext config is encrypted, but we can prepare ourselfs to debugging process after reverse engineering the sample.\r\nBelow we can see the first part of the network communication setup.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 15 of 28\n\nThe IcedID use all capability of wininet’s APIs. In this first part we can see the usage of the follow APIs:\r\nWinHttpOpen -\u003e this API initializes, for an application, the use of WinHTTP functions and returns a WinHTTP-session handle;\r\nWinHttpConnect -\u003e this API specifies the initial target server of an HTTP request and returns an HINTERNET\r\nconnection handle to an HTTP session for that initial target;\r\nWinHttpOpenRequest -\u003e this API creates an HTTP request handle;\r\nIn this first part of this network communication setup, the IcedID initialize the HTTP connection with the APIs listed above.\r\nBelow, is the rest of the http_connection.\r\nThe rest of the http_connection function, uses the follow APIs:\r\nWinHttpSetOption -\u003e this API sets an Internet option;\r\nWinHttpSendRequest -\u003e this API sends the specified request to the HTTP server;\r\nWinHttpQueryHeaders -\u003e this API retrieves header information associated with an HTTP request;\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 16 of 28\n\nWinHttpQueryDataAvailable -\u003e this api returns the amount of data, in bytes, available to be read with\r\nWinHttpReadData;\r\nWinHttpReadData -\u003e this api reads data from a handle opened by the WinHttpOpenRequest function;\r\nWinHttpQueryDataAvailable -\u003e returns the amount of data, in bytes, available to be read with WinHttpReadData.\r\nIn this part, the function handle with the data downloaded from the command and control servers. Beyond of network\r\ncommunication capabilities, we can observe the usage of heap manipulation APIs, like HeapAlloc and HeapReAlloc, as a\r\nconditional statement for the code proceed.\r\nAfter that, this functions realize the clean up in the stack, closing the handles.\r\nA curious fact that we can see above, is that data_encrypted pointer is present on this function, and, can be usage if some\r\nstatements are reached, after a sleep of 5000 seconds (1 hour and 38 minutes). By the way, this sleep technique is a\r\nsandbox evasion technique.\r\nWrite the photo.png and Code Injection\r\nAfter the network communication routine, do a test on EAX register with him self, and if the results not was the operand\r\nexpected it will jump to the same heap allocation and rc4 routine that we saw before. The processor will do the same test\r\nwith EAX, and with the results are the same as earlier, it will take a jump to the write_photo.png.\r\nWe will not delve deeper into this function, because the name is self explanatory. The only information that we need, is what\r\nAPI will use to carry out this activity, the answer is simple, the code will just use the WriteFile (writes data to the specified\r\nfile) API.\r\nAfter that, the code will call the last function of this sample, the function that execute a code Injection.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 17 of 28\n\nAnalyzing this function, in the image below, we can see that it is very straight to the point. The function uses VirtualAlloc\r\nto allocate memory.\r\nAfter some calculations, using the variables that contained the return value of the VirtualAlloc function and the pointer to\r\nthe previously set buffer size, the function uses GetModuleFileNameA to collect the complete path of a file, performing a\r\nseries of calculations with the variables.\r\nIn the last part of the code injection function, the code implements some for loops, probably with the aim of iterating each\r\nbyte of the encrypted data, within a single memory space, which will be used later. Finally, the code will use\r\nVirtualProtect.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 18 of 28\n\nIn general, this function gives the ability to inject code into memory (possibly a PE artifact), which must be contained within\r\nthe previously dropped photo.png artifact.\r\nWith that, we now can understand what APIs are used to construct a network communication, decrypt data, injection and\r\ndropped routines, now we know what APIs we need to set breakpoints when we will doing dynamically analysis of\r\nunpacked IcedID.\r\nNow that we understand the main functionality of the IcedID, let’s dive into the debugging stage of our analysis, with\r\nx32dbg.\r\nDynamically Analysis of IcedID Unpacked\r\nIn this dynamic analysis, we will focus on understanding the decryption routines and network communication with the C2\r\nserver.\r\nBelow, we can now see the exact prologue instructions that we identified through the disassembler. When following the data\r\nfrom address 7E3000 in the dump (the same data as .data, identified in Disassembler by 0x403000), we are able to observe\r\nthat our assumption becomes possible.\r\nThat is, in the image below, we can see that after the first 8 bytes, only 248 bytes remain. Exactly the value we observe in\r\nDisassembler. Therefore, we can validate our assumption that the first 8 bytes of the .data data are the RC4 decryption key,\r\nand the remaining 248 bytes are the data to be decrypted.\r\nTo test this assumption, let’s set a breakpoint exactly after calling the decryption function, and execute the function.\r\nExactly after executing the decryption function, we can observe the network communication configuration of IcedID (an\r\nindex.php, and some c2 server domains) in plain text.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 19 of 28\n\nLet’s restart the sample in the debugger, and analyze the decryption process in more detail.\r\nAs we can see in the image below, the CPU moves the data address from .data to the ECX register, and immediately after\r\nthat, the function executes the first two stages of rc4 (KSA and PRGA). Then, the CPU performs the third phase of the RC4\r\nalgorithm, which is the XOR operation between the keystream and the data.\r\nI set a breakpoint at the exact restart point of the XOR loop, and ran it several times, until enough data was decrypted and\r\nbecame clear text. If we observe, the first 8 bytes have not been modified, which in fact means that these first 8 bytes are the\r\ndecryption key.\r\nTo validate once and for all, I went to CyberChef and put the first 8 bytes as the key, and the next 248 bytes as data. And\r\nindeed, the data was successfully decrypted!!\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 20 of 28\n\nNow shifting the focus to the hardware information that the sample collects, we can now observe the true usefulness of this\r\ninformation for adversaries. Below, we can see that after executing the functions that we identified in the reverse\r\nengineering process, such as hardware_info_collection function, the collected values are concatenated in a way that\r\nresembles a URI.\r\nIf we analyze the HTTP request construction function, we have confirmation that in fact the hardware information that was\r\ncollected is sent to one of the c2 domains present in the previously decrypted configuration.\r\nWe now know that this IcedID sample uses the RC4 encryption algorithm to encrypt communication settings with c2\r\nservers. But, we know even more, we know where the sample stores the key and data that will be decrypted, and how it will\r\nbe decrypted.\r\nWith this knowledge, we can produce a script that automates the process of decrypting the network communication\r\nconfiguration with the c2 servers. In the next section, we will cover developing a configuration extractor for IcedID. If\r\nsuccessful, we will be able to reuse this script to extract the configuration of network communication with c2 servers from\r\nother samples, without having to carry out the entire debugging process after the sample is unpacked.\r\nWell, we have all the information needed to automate the IcedID configuration extraction process. We need a script that:\r\nReceive a PE artifact\r\nRead the .data section of the PE file, through the pefile library\r\nSelect the first 8 bytes for the RC4 decryption key\r\nSelect the remaining 248 bytes of data encrypted with RC4\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 21 of 28\n\nTreat the raw data in hexadecimal, using a library like binascii\r\nPerform the RC4 decryption process, using the arc4 library\r\nPrint the key, encrypted data, and decrypted data in a formatted format after executing the above processes.\r\nYou can find the complete configuration extraction script on my Github, or just by clicking aqui.\r\nWith the configuration extractor developed, we can test on other unpacked samples, from the IcedID family, in the hope that\r\nour script will perform the configuration extraction process automatically.\r\nIn order to test our script on different samples from IcedID, I added two samples, in addition to the one that was already the\r\nsubject of our analysis. All three samples you can find at the links below:\r\n1648556.exe – sample seen in 2019\r\niced-new.exe – sample seen in 2020\r\nwinme_sc_carved.bin – sample seen in 2023\r\nWith that, below is the PoC video of the execution of the configuration extractor I developed, tested on three different\r\nsamples from the IcedID family. And as you can see below, the script managed to extract the settings successfully!\r\nCode Patterns between Samples from Different Years\r\n0:00 / 0:55\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 22 of 28\n\nIn this section, we will analyze two more unpacked samples from 2019 and 2023, with the aim of identifying IcedID code\r\nreuse over the years. Allowing us to understand the familiarity between samples, and identify opportunities for creating\r\nsignatures, to detect samples that follow the same pattern. To perform this analysis, we will use the BinDiff plugin in IDA.\r\nWe will perform this analysis, using the same samples that we tested with the config extractor, in the previous section.\r\nWhen we run BinDiff between the sample we analyzed in this article (unpacked_icedid.exe) that was reported in 2020,\r\nwith the unpacked_1648556 sample from 2019, we can already notice the great similarities between the internal functions\r\nof the samples.\r\nIn the table in the image above, we should focus our attention on the Similarity and Confidence columns. Basically, how\r\nclose it is to the value 1.0 is how similar each function is. And as we can see in the image above, the internal functions of the\r\nunpacked_1648556 sample (from 2019) are identical to the functions of the unpacked_icedid.exe sample (from 2020).\r\nNow if we compare the unpacked_icedid.exe (from 2020) and winme_sc_carved.bin (from 2023) samples, we will\r\nobserve several similarities, but some differences between certain functions. Below, we can see this in BinDiff.\r\nAnalyzing the image above, we can see a slight difference between the main functions, a slightly larger difference in the\r\nhttp_connection function, and a considerable difference in the heap_allocation function.\r\nNow that we know that the unpacked_1648556 sample is identical to the sample we analyzed in this article, let’s note the\r\nimportant similarity between unpacked_icedid.exe (from 2020) and winme_sc_carved.bin (from 2023) in the\r\nhardware_info_net_connection function. Below, we can see the similarity in the code structure between the two versions.\r\nThe functions that have an important functionality, and which are also identical between all versions analyzed in this article,\r\nare the decryption routine functions through RC4.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 23 of 28\n\nBelow, we can observe the similarity between the unpacked_iced.exe and unpacked_1648556.exe samples, referring to the\r\nroutine function of the RC4 KSA and PRGA stages being executed. It is also possible to observe the pattern of these RC4\r\nphases, through the presence of the value 0x100 in loops, followed by XOR operations.\r\nIn the following image, we can see the same pattern being observed between the unpacked_iced.exe and\r\nwinme_sc_carved.bin samples.\r\nBelow, we can observe the similarity between the unpacked_iced.exe and unpacked_1648556.exe samples, referring to the\r\nroutine function of the RC4 routine after executing the first two stages (KSA and PRGA), and finally executing the XOR\r\noperation that will decrypt the data that we observed in previous sections.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 24 of 28\n\nIn the following image, we can see the same pattern being observed between the unpacked_iced.exe and\r\nwinme_sc_carved.bin samples.\r\nThis information is extremely useful, both for identifying code reuse between samples, and consequently the identification\r\nof new strains of malware families (or use of malware by different malicious actors), and for the development of Yara\r\nsignatures, to detect samples of more effective way.\r\nThat’s what we’ll do in the next section.\r\nDevelopment of Yara Detection Rules\r\nIn this section we will use the intelligence we collected through our analysis, and use it to create a detection rule, which can\r\ndetect samples from the IcedID family.\r\nIn addition to creating our Yara detection rules, we will use the Unpac.me platform to carry out a Yara Hunt, with the\r\npurpose of validating the quality of our detection rule, by detecting other samples in the Unpac.me database.\r\nAs we can see in the previous section, we identified code reuse in some of the main functions. This will be decisive for the\r\nproduction of our detection rule, because, if the IcedID family reuses the code of primary functions, we can use these\r\npatterns in our detection rules.\r\nThe primary functions for the operation of both samples analyzed in the previous section are:\r\nrc4_ksa_prga\r\nrc4_routine\r\nhardware_info_collection\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 25 of 28\n\nIn our analysis, these functions had their codes reused in both samples, therefore, they will be part of our detection rule. The\r\ncode reuse pattern is collected using the Disassembler, where we will identify the same sequences of bytes (in hexadecimal)\r\nbeing used in the functions mentioned above. Below, we can see the sequence of bytes referring to the rc4_ksa_prga\r\nfunction. This sequence is the same in all samples analyzed in this article.\r\nFurthermore, we also selected some strings that also appear constantly in the three samples analyzed.\r\nHaving this information, we created our detection rule, which I called iced_family_was_detected, and validated its syntax in\r\nUnpac.me, as we can see in the image below. The Yara detection rule has all the information collected and analyzed in this\r\narticle.\r\nAfter performing the validation, I started Yara Hunt on Unpac.me. This run returned 5 different samples from the Unpac.me\r\ndatabase, just labeled as part of the IcedID family, and without false positives.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 26 of 28\n\nI also carried out the validation using the Yara Scan Service platform, and below, we can see the result.\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 27 of 28\n\nObviously, the validation was also performed with the samples that we analyzed, I didn’t pay much attention to them, as it is\r\nobvious that it would work, since I made the Yara detection rule based on them. But, just to show the functionality, below\r\nare the matches in my laboratory.\r\nConclusion\r\nI hope that in this article I have exposed my sample analysis and reverse engineering methodology, as well as the entire\r\nprocess of identifying patterns between samples and detection engineering. And I hope that you who are reading this article\r\nmay have learned something new, or may have gained some insight. Until next time, feedback is always welcome.\r\nYou can access the Yara rule and the config extractor at the following links.\r\nYara Rule: iced_family_was_detected\r\nConfig Extractor: iced_conf_extractor\r\nSee you later!!\r\nSource: https://0x0d4y.blog/icedid-technical-analysis/\r\nhttps://0x0d4y.blog/icedid-technical-analysis/\r\nPage 28 of 28",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://0x0d4y.blog/icedid-technical-analysis/"
	],
	"report_names": [
		"icedid-technical-analysis"
	],
	"threat_actors": [
		{
			"id": "26a04131-2b8c-4e5d-8f38-5c58b86f5e7f",
			"created_at": "2022-10-25T15:50:23.579601Z",
			"updated_at": "2026-04-10T02:00:05.360509Z",
			"deleted_at": null,
			"main_name": "TA551",
			"aliases": [
				"TA551",
				"GOLD CABIN",
				"Shathak"
			],
			"source_name": "MITRE:TA551",
			"tools": [
				"QakBot",
				"IcedID",
				"Valak",
				"Ursnif"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "40b623c7-b621-48db-b55b-dd4f6746fbc6",
			"created_at": "2024-06-19T02:03:08.017681Z",
			"updated_at": "2026-04-10T02:00:03.665818Z",
			"deleted_at": null,
			"main_name": "GOLD CABIN",
			"aliases": [
				"Shathak",
				"TA551 "
			],
			"source_name": "Secureworks:GOLD CABIN",
			"tools": [],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "90f216f2-4897-46fc-bb76-3acae9d112ca",
			"created_at": "2023-01-06T13:46:39.248936Z",
			"updated_at": "2026-04-10T02:00:03.260122Z",
			"deleted_at": null,
			"main_name": "GOLD CABIN",
			"aliases": [
				"Shakthak",
				"TA551",
				"ATK236",
				"G0127",
				"Monster Libra"
			],
			"source_name": "MISPGALAXY:GOLD CABIN",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "04e34cab-3ee4-4f06-a6f6-5cdd7eccfd68",
			"created_at": "2022-10-25T16:07:24.578896Z",
			"updated_at": "2026-04-10T02:00:05.039955Z",
			"deleted_at": null,
			"main_name": "TA551",
			"aliases": [
				"G0127",
				"Gold Cabin",
				"Monster Libra",
				"Shathak",
				"TA551"
			],
			"source_name": "ETDA:TA551",
			"tools": [
				"BokBot",
				"CRM",
				"Gozi",
				"Gozi CRM",
				"IceID",
				"IcedID",
				"Papras",
				"Snifula",
				"Ursnif",
				"Valak",
				"Valek"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775438990,
	"ts_updated_at": 1775826690,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/10e93921eff8330eb0caf3af1936b489c9f4bea1.pdf",
		"text": "https://archive.orkl.eu/10e93921eff8330eb0caf3af1936b489c9f4bea1.txt",
		"img": "https://archive.orkl.eu/10e93921eff8330eb0caf3af1936b489c9f4bea1.jpg"
	}
}