PaaS, or how hackers evade antivirus software By Positive Technologies Published: 2024-08-19 · Archived: 2026-04-05 23:13:49 UTC Malware is one of the main tools of any hacking group. Depending on the level of qualification and the specifics of operation, hackers can use both publicly available tools (such as the Cobalt Strike framework) and their own developments. Creating a unique set of tools for each attack requires huge resources; therefore, hackers tend to reuse malware in different operations and also share it with other groups. The mass use of the same tool inevitably leads to its getting on the radar of antivirus companies, which, as a result, reduces its efficiency. To prevent it from happening, hackers use code packing, encryption, and mutation techniques. Such techniques can often be handled by separate tools called crypters or sometimes simply packers. In this article, we will use the example of the RTM banking trojan to discuss which packers attackers can use, how they complicate detection of the malware, and what other malware they can pack. Packer-as-a-service A hacker group responsible for RTM distribution regularly sent mass phishing emails with malicious attachments until the end of 2020. Apparently, the attacks were automated. Figure 1. RTM phishing email, December 2020 Each attachment contained files that significantly differed from each other, but the final payload remained almost the same. Figure 2. Example of RTM archive Such feature is a natural consequence of using crypters. Initially, the group behind RTM used its own unique crypter. In 2020, however, the group changed it twice. When analyzing samples packed in a new way, we detected numerous other malware protected by similar method. Taking into account the fact that packing process is automated, such overlapping with other malware allows us to assume that attackers use the packer-as-a-service model. In this model, packing of malicious files is delegated to a special service managed by a third party. https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 1 of 11 Figure 3. Website of a crypt service Access to such services can often be found on sale on hacker forums. Figure 4. Advertisement of file packing as a service Later in this article, we will discuss specific examples of crypters used by the RTM group. Rex3Packer The first use of this packer by the RTM group that we detected dates back to November 2019. The group started actively using the packer in April–May 2020. Rare uses of the packer for distributing old versions of the RTM trojan were also observed in late January 2021. Figure 5. Phishing email by RTM, January 2021 https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 2 of 11 We couldn't associate this packer with any of the publicly described ones, so we named it according to three specifics of its working: recursion, bit reverse, and reflective loading of PE files (reflection), hence the name Rex3Packer. Unpacking algorithm The overall algorithm for extracting the payload is as follows: 1. A predetermined amount of memory is allocated with read, write, and execute rights using VirtualAlloc. 2. The content of the current process image in the memory is copied to the allocated buffer (in particular, section .text). 3. Control passes to the function inside the buffer. 4. The difference is calculated between the location of data in the buffer and in the PE file image (difference between the addresses in the buffer and virtual addresses in the image). This difference is written to the ebx register. All references to virtual addresses in code are indexed by the content of this register. As a result, wherever necessary, a correction is added to the PE image addresses that allows obtaining the corresponding address in the buffer. Figure 6. Calls to functions and variables taking into account the correction in the ebx register 5. Another buffer is allocated for packed data. 6. By calling VirtualProtect, RWX rights are assigned to the entire memory region with the PE file image. 7. The packed data is copied to the buffer. 8. The packed data is decoded. 9. The memory region with the PE image is filled with null bytes. 10. The decoded data represents an executable file—the PE payload. This payload is reflectively loaded to where the initial PE image was, and control passes to its entry point. A specific algorithm for decoding packed data is of special interest to us. In this case, it would be incorrect to compare packing with compression, as the algorithm is such that the size of packed data is always bigger than that of the initial data. The packed data is preceded by a 16-byte header that contains four 4-byte fields: Size of the header Size of initial data (PE payload) Position in initial data (*) at which they are divided (more details below) Encoding mode (1, 2, or 4) The decoding looks as follows: 1. Inside each byte, bit order is reversed (for example, 10011000 becomes 00011001). 2. Depending on encoding mode (1, 2, 4), data is divided into blocks with N size of 9, 5, or 3 bytes, respectively. The result of the block decoding is N-1 byte (8, 4, or 2). 3. In the first N-1 bytes of the block, some bits are missing: their values always equal zero. To restore the original bytes, the missing bits are extracted from the last byte of the block by using 00000001, 00010001, or 01010101 masks. The mask is shifted for each subsequent byte. As a result, the last byte of the block is composed of the bits extracted from previous bytes and united by the logical operation OR. For example, in mode 4, the last byte is composed of even bits of the block's first byte and odd bits of the block's second byte. As a result of "returning" these bits to the first and second bytes, an original sequence of two bytes is composed. https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 3 of 11 Figure 7. Scheme of obtaining initial bytes in mode 4 4. When bits are restored in all blocks, the obtained data represents the initial PE file divided by two parts at position (*). These parts, in turn, were swapped. The second rearrangement (taking into account the (*) value) allows obtaining the original file. Obfuscation To complicate code analysis, various obfuscation techniques are used in the packer: In between the execution of significant code, various WinAPI functions are called. Their results are saved but not used, and the functions are selected so that not to affect the program operation. Figure 8. Calling WinAPI functions A typical feature of this packer is the presence of cycles (not performing useful operations) implemented via a recursive function. Figure 9. Recursive function (sample without junk code) For further obfuscation, several dozens of randomly generated functions are added to executable file. They may call each other, but none of them obtains control ever. https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 4 of 11 Figure 10. Example of generated function Usage In addition to RTM samples, we detected the use of Rex3Packer for packing various malware, mainly originating from the CIS countries. Below is the list with examples of such malware: Malware family SHA256 Phobos Ransomware 6e9c9b72d1bdb993184c7aa05d961e706a57b3becf151ca4f883a80a07fdd955 Zeppelin Ransomware 8d44fdbedd0ec9ae59fad78bdb12d15d6903470eb1046b45c227193b233adda6 Raccoon Stealer 3be91458baa365febafb6b33283b9e1d7e53291de9fec9d3050cd32d98b7a039 KPOT Stealer 9b6af2502547bbf9a64ccfb8889ee25566322da38e9e0ccb86b0e6131a67df1e Predator The Thief d1060835793f01d1e137ad92e4e38ef2596f20b26da3d12abcc8372158764a8f QakBot 18cc92453936d1267e790c489c419802403bb9544275b4a18f3472d2fe6f5dea We also detected the use of this packer for packing malware samples of the Nemty, Pony, and Amadey families. This is, of course, not an exhaustive list of all cases of using Rex3Packer. HellowinPacker In May 2020, RTM started using a new packer and went on using it until the beginning of 2021. We called it HellowinPacker because of the file name "hellowin.wav" we spotted in strings of some samples. The packer's key feature is two levels of code mutation. The first one significantly changes the unpacking code structure, making samples look different from each other. https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 5 of 11 Figure 11. Comparison of code in two samples of different structure The example above shows the comparison of samples 5b5f30f7cbd6343efd409f727e656a7039bff007be73a04827cce2277d873aa0 (on the left) and 1f9a8b3c060c2940a81442c9d9c9e36c31ad37aaa7cd61e1d7aec2d86fe1c585 (on the right). The second level only changes some details, and the code structure remains in general the same. The changes mainly affect assembler instructions and constants that do not impact the program operation. As a result, the code looks almost identical when decompiled. Figure 12. Comparison of code in two samples of the same structure Just like Rex3Packer, HellowinPacker is actively used by attackers to pack various malware. Note that malware from the same family has the same structure when packed. This lasts for at least some time, after which the structure can change. All these features coincide with the description of a packing service the access to which is sold on hacker forums: [Uniqueness] A customer is given a unique crypter that does not depend on other customers. If your files were spotted, your uploads are to blame. We're not looking for 10,000+ customers, we provide correct Premium support and have a very limited number of clients. We make only unique stubs for a customer. Apparently, each unique crypter has its own structure of generated code. The crypter itself can also mutate code but at a lower level, without changing the program structure. In any case, the significant executable code remains the same. Unpacking algorithm One of the first actions in all packed files is an attempt to open the registry key HKEY_CLASSES_ROOT\Interface\ {b196b287-bab4-101a-b69c-00aa00341d07} (character case may differ in each particular case) and request a default value. Correct program operation in some modifications of generated code depends on whether these operations are successful. Interface GUIDs may also differ. Here are some of the possible options: {3050f1dd-98b5-11cf-bb82-00aa00bdce0b} {aa5b6a80-b834-11d0-932f-00a0c90dcaa9} {683130a6-2e50-11d2-98a5-00c04f8ee1c4} {c7c3f5a1-88a3-11d0-abcb-00a0c90fffc0} {b8da6310-e19b-11d0-933c-00a0c90dcaa9} The subsequent code obtains the address at which a block of encrypted data is located. This block starts with a 4-byte number, which stores the size of initial data (those that will be obtained after decoding). By calling VirtualAlloc, a memory block of required size with RWX rights is allocated for decrypted data. Encrypted data is copied to the allocated memory by blocks of X bytes each. In the original file, "spaces" of Y byte length are located between these blocks. https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/paas-or-how-hackers-evade-antivirus-software/ Page 6 of 11 Figure 13. Scheme of data copying in HellowinPacker Data is then decrypted by 4-byte blocks: Each next block is interpreted as an integer (DWORD). Index of the first byte in the block is added to the integer. An xor operation is executed between the obtained value and the sum of the index and a fixed key (Z number). Example of algorithm implementation in Python: def decrypt(data, Z): index = 0 while index < len(data): dword = struct.unpack("