Introduction APT41, known by numerous aliases such as Amoeba, BARIUM, BRONZE ATLAS, BRONZE EXPORT, Blackfly, Brass Typhoon, Earth Baku, G0044, G0096, Grayfly, HOODOO, LEAD, Red Kelpie, TA415, WICKED PANDA, and WICKED SPIDER, is a Chinese-origin cyber threat group recognized for its extensive cyber espionage and cybercrime campaigns. APT41's operations stand out due to their complexity and versatility, reflecting a high level of expertise and resources, possibly indicating support or connections with state entities. The group targets a wide array of sectors including government, manufacturing, technology, media, education, and gaming, with the intent of stealing intellectual property, sensitive data, and compromising systems for strategic or economic gain. The group's tactics, techniques, and procedures (TTPs) include the deployment of malware, phishing, exploitation of zero-day software vulnerabilities, and supply chain attacks. Their activities pose a global threat, necessitating constant vigilance from cybersecurity professionals to mitigate associated risks. Notably, during a prolonged and in-depth investigation, Tinexta Cyber’s own Yoroi malware ZLab team isolated the infamous modular backdoor malware, KEYPLUG. Written in C++ and active since at least June 2021, KEYPLUG has variants for both Windows and Linux platforms. It supports multiple network protocols for command and control (C2) traffic, including HTTP, TCP, KCP over UDP, and WSS, making it a potent tool in APT41's cyber-attack arsenal. This specific implant has been identified both in its Linux and Windows variant, with its own custom configuration and C2 communication protocol, WSS, which will be deepened in the following sections. Technical Analysis Windows implant The first analyzed malware sample is the malware implant retrieved on a Windows machine. It is written in the .NET Framework, designed for decrypting the file "C:\ProgramData\pfm.ico". The decryption process employs the AES algorithm, with the keys hard-coded within the sample itself, as demonstrated in the following code snippet: Figure 1: Seeking for pfm.ico file and decryption After the decryption of the file content, the malware allocates memory to store a shellcode directly in memory the decrypted result using the VirtualAlloc API call. The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. It can be used to allocate memory for the decrypted payload. Once the memory is allocated, the malware immediately modifies the memory protections to make it executable using the VirtualProtect API call. VirtualProtect changes the protection on a region of committed pages in the virtual address space of the calling process. In this context, it ensures that the decrypted payload can be executed by the system Figure 2: Decrypted and loaded shellcode in memory The shellcode performs dynamically API loading with a custom hashing algorithm which will be explained further. Among these APIs, another time a VirtualAlloc is loaded to allocate another piece of memory where decrypt and load the Final keyplug implant. Figure 3: Evidence of other piece of memory allocated to store the Keyplug Payload When the decoding operations end, the malware passes the control to the Keyplug implant. The Sample starts by retrieving the hostname and hashing the string three times with another custom algorithm, the result is used as Mutex. It is used as an unique identifier for the infected machine and this information is shared with the command and control. Figure 4: Generation of a new mutex The malware proceeds to enable the SeDebugPrivilege token. The SeDebugPrivilege is a powerful privilege that allows a process to debug and interact with other processes, including those that it did not create. This privilege can be used to access and manipulate system-level processes and is typically reserved for administrators. In this case the malware uses it to manipulate pieces of its own code, in order to extract its configuration. Figure 5: Manipulating SeDebugPrivilege The new payload, with SHA256 hash 399bf858d435e26b1487fe5554ff10d85191d81c7ac004d4d9e268c9e042f7bf, appears to be a version of Keyplug compiled for Windows. Attribution was made by comparing the behavior and structure of the malware under examination with Mandiant's report "Does This Look Infected? A Summary of APT41 Targeting U.S. State Governments." Additionally, the configuration described in the file appendix matches that described by Mandiant. Configuration decryption is performed using the XOR key 0x59. Part of the configuration decoding is shown in Figure 6. Figure 6: Decrypting the malware configuration After decrypting the configuration, the malware starts to perform different reconnaissance-relevant information, such as the operating system version and installed anti-malware products, through WMIC (Windows Management Instrumentation Command-line) call. Figure 7: Choosing the communication protocol basing on the information retrieved by the configuration Then the Keyplug implant communicates with the C2 (Command and Control) through the abuse of CloudFlare's Content Delivery Network (CDN) and via the WSS (WebSocket Secure) protocol. The XOR-encoded configuration contains the information to communicate with the C2. Indeed, after decoding, KEYPLUG randomly selects a CIDR block from the list and then selects an IP address within the block based on the infected computer's tick count. Once one of the randomly chosen IPs belonging to Cloudflare's CDN, and present in the subnets listed within the communication, is selected, the KEYPLUG malware establishes communication with the C2 through a socket API call. However, KeyPlug is also capable of using TCP,UDP,WSS,HTTP,QUIC and overall, it is an interesting backdoor by looking at the logging strings (Appendix A) Linux Variant Compared to the Windows variant, it is slightly more complex, and it seems to use VMProtect. In fact, when static analysis was performed, many strings regarding to UPX packer, but the automated unpacking routine didn’t work. However, other advanced analysis strategies revealed a series of interesting information about the similarities between the Windows and Linux variants. Figure 8: Comparing the code between Windows and Linux Variant In this case the C2 is mirrors.directtimber.]buzz, and even in this case the communication is performed by abusing the WSS Protocol. Figure 9: Connection to the C2 through the WSS protocol Pivoting the analysis and the connection with ISOON leak The threat hunting investigation revealed other interesting information regarding the complex infrastructure built by APT41 and the development of this malware campaign. On February 16, a significant amount of sensitive data was exposed regarding the Chinese Ministry of Public Security. This information was subsequently shared on platforms such as on GitHub and Twitter. Causing considerable discussion and interest within the cybersecurity community. The event attracted immediate attention from a range of private organizations and researchers, who were keen to explore the implications of the leak and its potential impact on cybersecurity practices and policies. It seems that the massive data leak that appeared on Github comes from a data breach of a private industry contractor of the Chinese Ministry of Public Security (MPS) known as i-Soon (also called Anxun). The published data contains a plethora of chats, user manual, official government plans, projects, phone numbers, employee PII. The actor responsible for the compiled leak has organized the data into distinct sections. The entire folder contains over five hundred files, most of them are images containing private messages or conversation. It’s also possible to identify several documents regarding the different technology and software offered by I-S00N. When analyzing this report, a particular RAT lets think about we dub as KeyPlug, Hector. “Hector”, which targets both Linux and Windows machines and it is known to use the WSS protocol to communicate with the C2. Figure 10: Leaked image of Hector Backdoor Even Recorded Future hypothesized that a link between KEYPLUG malware and Hector leak could exist; but in this case the confidence of this information is medium-low due to the lack of direct evidences of the link. If this connection could be verified, the resulting infrastructure for this campaign is: Figure 11: Tracking the KEYPLUG malware campaign with the connection to ISOON Custom API Hashing As mentioned earlier, KeyPlug uses a custom algorithm for hashing the names of the APIs to dynamically load in the first part of the shellcode. By searching for 0x3b7225fc (LoadLibraryA) we found only a report by NetScout from 2016 about Nuclear Bot (TinyNuke) Figure 12: API Hashing algorithm (Source Netscout) Conclusion In conclusion, the analysis underscores the sophisticated nature of APT41's operations, adding the fact that this malware just described implant was capable to be resilient for several months inside the infected network. Not only, it was able to remain undetected even in environments where different NIDS and EDR solution were installed. Moreover, it is plausible to hypothesize a connection between APT41 and the ISOON Leak incident. The sophisticated techniques and target sectors align with the modus operandi of APT41, suggesting a potential link to this cyber espionage campaign. Further investigation into the ISOON Leak, particularly regarding the tools and methods utilized, may provide insights into the involvement of APT41 or related entities. Indicators of Compromise Yara Rules Suricata Rules Appendix A: Logging Strings This blogpost has been authored by Luigi Martire and Carmelo RagusaSHA256 87756cb5e33f7fb7c2229eb094f1208dbd510c9716b4428bfaf2dc84745b1542 Threat .NET Loader Threat Description Simple .NET Loader which decrypts and executes shellcode leading to the final KeyPlug payload SSDEEP 192:+3c5NTgL6xvKDgtRy5TZYxALUsLh4LSOK7kJ9POxLVLSE7pZ6A5U1A:+3cfvCMjcTZEAL9LOLSngJ5sLVL9NQUl SHA256 a6aabc68245dde1eda2093c6ef4b75b75f99d0572c59d430de9cef527dc037cb Threat KeyPlug Threat Description KeyPlug Linux Variant SSDEEP 98304:iH/3LJD43UewSERenGaEB9bhUQQxBdKGTYu9DUoi:ydDoUe7GeUB9buJBdJTYzp
rule keyplug_shellcode { meta: author = "Yoroi Malware ZLab" description = "Rule for KeyPlug Shellcode" last_updated = "2024-03-19" tlp = "CLEAR" category = "informational" strings: /* 4496fb2e42bb8734d4d5c6c40fa6e5f7afa00233ffa1c9e4b00e1ef4fd7849ad 48 89 5C 24 10 mov [rsp-8+arg_8], rbx 48 89 74 24 18 mov [rsp-8+arg_10], rsi 55 push rbp 57 push rdi 41 56 push r14 48 8D 6C 24 80 lea rbp, [rsp-80h] 48 81 EC 80 01 00 00 sub rsp, 180h E8 A1 08 00 00 call sub_8C0 BA FC 25 72 3B mov edx, 3B7225FCh 48 8B C8 mov rcx, rax 48 8B F8 mov rdi, rax E8 C5 07 00 00 call sub_7F4 BA 8A F8 C4 02 mov edx, 2C4F88Ah 48 89 44 24 38 mov qword ptr [rsp+190h+var_160+8], rax 48 8B CF mov rcx, rdi E8 B3 07 00 00 call sub_7F4 BA 59 3D 78 5E mov edx, 5E783D59h 48 89 44 24 20 mov qword ptr [rsp+190h+var_170], rax 48 8B CF mov rcx, rdi E8 A1 07 00 00 call sub_7F4 BA 8D 11 34 26 mov edx, 2634118Dh 48 89 44 24 28 mov qword ptr [rsp+190h+var_170+8], rax 48 8B CF mov rcx, rdi E8 8F 07 00 00 call sub_7F4 BA 5B 7B C3 0A mov edx, 0AC37B5Bh 48 89 44 24 40 mov qword ptr [rsp+190h+var_150], rax 48 8B CF mov rcx, rdi E8 7D 07 00 00 call sub_7F4 BA 95 6D B9 EE mov edx, 0EEB96D95h 48 89 44 24 30 mov qword ptr [rsp+190h+var_160], rax 48 8B CF mov rcx, rdi 48 8B D8 mov rbx, rax E8 68 07 00 00 call sub_7F4 48 89 44 24 48 mov qword ptr [rsp+190h+var_150+8], rax */ $1 = { 4? 89 5c ?4 10 4? 89 74 ?4 18 55 57 4? 56 4? 8d 6c ?4 80 4? 81 ec 80 01 00 00 e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 8b c8 4? 8b f8 e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 89 44 ?4 38 4? 8b cf e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 89 44 ?4 20 4? 8b cf e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 89 44 ?4 28 4? 8b cf e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 89 44 ?4 40 4? 8b cf e8 ?? ?? ?? ?? ba ?? ?? ?? ?? 4? 89 44 ?4 30 4? 8b cf 4? 8b d8 e8 ?? ?? ?? ?? 4? 89 44 ?4 48 } condition: $1 } rule keyplug_windows { meta: author = "Yoroi Malware ZLab" description = "Rule for KeyPlug Windows" last_updated = "2024-03-20" tlp = "CLEAR" category = "informational" strings: /* 23c6b417ddaf5fbd00d204543b5b981e7f5967c5123d511ef5654c4d409aee0f 00a366e51c88a41a204e4b2267991460c822b5d2d78a4da11596c14e0daf5d3c 70e28c530380ae4bc04d22de009196e4b131426534dd7af43c03a28a97779cc8 399bf858d435e26b1487fe5554ff10d85191d81c7ac004d4d9e268c9e042f7bf a72b689b816b1a2b41b0ecfd4730a7d9b400a8587c07006f297b1cdbc39c3a1a 48 83 EC 28 sub rsp, 28h 48 8B C1 mov rax, rcx 41 8B 09 mov ecx, [r9] ; s 44 8B 88 F8 02 00 00 mov r9d, [rax+2F8h] ; flags FF 15 A9 9A 04 00 call cs:send 85 C0 test eax, eax 79 56 jns short loc_1800A8EE1 FF 15 FF 99 04 00 call cs:WSAGetLastError 8B C8 mov ecx, eax 3D 33 27 00 00 cmp eax, 2733h 74 42 jz short loc_1800A8EDC 3D 4C 27 00 00 cmp eax, 274Ch 74 3B jz short loc_1800A8EDC 3D 46 27 00 00 cmp eax, 2746h 75 0A jnz short loc_1800A8EB2 B8 FD FF FF FF mov eax, 0FFFFFFFDh 48 83 C4 28 add rsp, 28h C3 retn ; --------------------------------------------------------------------------- loc_1800A8EB2: ; CODE XREF: sub_1800A8E70+36↑j 81 F9 14 27 00 00 cmp ecx, 2714h 75 0A jnz short loc_1800A8EC4 B8 FC FF FF FF mov eax, 0FFFFFFFCh 48 83 C4 28 add rsp, 28h C3 retn ; --------------------------------------------------------------------------- loc_1800A8EC4: ; CODE XREF: sub_1800A8E70+48↑j 81 F9 C7 CF FF FF cmp ecx, 0FFFFCFC7h B8 FF FF FF FF mov eax, 0FFFFFFFFh BA FB FF FF FF mov edx, 0FFFFFFFBh 0F 44 C2 cmovz eax, edx 48 83 C4 28 add rsp, 28h C3 retn /* $1 = {4? 83 ec 28 4? 8b c1 4? 8b 09 4? 8b 88 f8 02 00 00 ff 15 ?? ?? ?? ?? 85 c0 79 ?? ff 15 ?? ?? ?? ?? 4? 8b d8 3d 33 27 00 00 74 ?? 3d 4c 27 00 00 74 ?? 3d 46 27 00 00 75 ?? b8 fd ff ff ff 4? 83 c4 28 c3 3d 14 27 00 00 75 ?? b8 fc ff ff ff 4? 83 c4 28 c3} $2 = {4? 83 ec 28 4? 8b c1 4? 8b 09 4? 8b 88 f8 02 00 00 ff 15 ?? ?? ?? ?? 85 c0 79 ?? ff 15 ?? ?? ?? ?? 8b c8 3d 33 27 00 00 74 ?? 3d 4c 27 00 00 74 ?? 3d 46 27 00 00 75 ?? b8 fd ff ff ff 4? 83 c4 28 c3 81 f9 14 27 00 00 75 ?? b8 fc ff ff ff 4? 83 c4 28 c3} $3 = { 4? 63 4f 1c 4? 63 c3 4? 8b c6 4? 8d ?? 04 50 4? 2b c3 4? 33 c9 ff 15 ?? ?? ?? ?? 85 c0 79 ?? ff 15 ?? ?? ?? ?? 3d 33 27 00 00 75 ?? b9 01 00 00 00 ff 15 ?? ?? ?? ?? eb ?? 85 c0 75 ?? b8 01 00 00 00 66 89 47} condition: any of them and uint16(0) == 0x5A4D }
Questo sito, come la maggior parte dei siti web, utilizza cookie, anche di terze parti, per migliorare la tua esperienza di navigazione e raccogliere informazioni sull'utilizzo del sito stesso. Cliccando su "Accetta tutti" ti dichiari d'accordo all'utilizzo di cookie analitici (che ci aiutano a capire in che modo gli utenti usano il sito e come migliorarlo, insieme ai nostri servizi) e di tracciamento (inclusi quelli di nostri partner di fiducia) che ci aiutano a decidere quali prodotti mostrarti, a misurare il volume di visite sul nostro sito e a darti la possibilità di mettere "mi piace" e di condividere contenuti direttamente sui social media. Clicca qui per vedere a cosa hai dato il tuo consenso e trovare più informazioni sui cookie che utilizziamo.