# Evolution after prosecution : Psychedelic APT41 ----- ### Who we are ###### Aragorn Tseng Charles Li Peter Syu Tom Lai ###### Malware Analysis Incident Response Threat Intelligence ###### Malware Analysis Threat Hunting Threat Intelligence ###### Malware Analysis Incident Response Tool Development ###### Incident Response Malware Analysis Penetration ----- ### AGENDA ###### 01 Initial Access 02 Cobalt Strike Loader 03 APT41’s Backdoor 04 C2 Hiding Technique 05 Relation to other operations ----- ## The content of APT41 in this talk is mainly from 2020/9 to 2021/8 ----- ### Target Country ###### Talk in last section ----- ### Target Industry ###### Healthcare High-tech Airlines ###### Telecom ###### Manufacturing ###### Media ###### Education Gaming Government Financial Energy Research ----- ### New TTP  Dll hollowing technique  Certificate bypass  InstallUtil  Early bird code injection  CDN service and Cloudfare worker  Some new backdoor ----- ### Initial Access  CVE-2021-34527(printnightmare)  SQL vulnerabilities  phpmyadmin vulnerabilities  Web vulnerabilities  Flash installer  Fake Decoy Icon ----- ## Cobalt Strike loader ----- #### g Cobalt Strike ###### Use certificate bypass and dll hollowing technique in Chatloader ###### 2021.4 ###### Use funnyswitch to load Cobalt Strike and use early bird code injection technique ###### 2020.7 ###### Use CDN service in Cobalt Strike, especially DNS beacon ###### 2021.1 ###### Chacha20 shellcode or loader(Chatloader) appeared to extract Cobalt strike Beacon ###### 2020.11 ###### 2021.3 ###### Use multiple .NET loaders and misuse InstallUtil to load CobaltStrike 2021.6 ----- ### Chatloader  Uses chacha20 algorithm to decrypt the payload  Most of the payload is Cobalt Strike, but we have also seen another backdoor  ETW bypass  Dll hollowing  Certificate bypass(MS13-098) ###### offset length data 0x0:0xC 0xC config nonce 0xc:0x10 0x4 config crc32 0x10:0x14 0x4c config_enc_length 0x14:0x14+config_enc config_enc_length ciphertext _length 0 100 0 120 0 20 fi k |te bypass(MS13-098)|Col2|Col3| |---|---|---| |offset|length|data| |0x0:0xC|0xC|config nonce| |0xc:0x10|0x4|config crc32| |0x10:0x14|0x4c|config_enc_length| |0x14:0x14+config_enc _length|config_enc_length|ciphertext| ----- ###### Header:CB2F29AD |length|data| |---|---| |0x4|Header| |0x4|Check User is SYSTEM| |0x4|Mutex trigger| |0x4|Delete Loader trigger| |0x4|Patch EtwEventWrite trigger| |0x4|Process Hollowing trigger| |0x4|Injected Process Name Length(x2)| |InjectedProcess Name Length(x2)|InjectedProcess Name| |0x4|Payload in Loader| |0x4|Payload Name Length(x2)| |Payload Name Length(x2)|Payload Name| |0x4|Payload Size| |0x4|Payload FilePointor| |length|data| |---|---| |0x4|Header| |0x4|Check User is SYSTEM| |0x4|Mutex trigger| |0x4|Delete Loader trigger| |0x4|Patch EtwEventWrite trigger| |0x4|Payload in Loader| |0x4|Payload Name Length(x2)| |Payload Name Length(x2)|Payload Name| |0x4|Payload Size| |0x4|Payload FilePointor| |0x4|Payload crc32| |0xC|Payload Nonce| ###### 0x4 Payload crc32 ----- ### Chatloader config example ====== Decrypt Config ====== Config Nonce (12 bytes) = 0xb5 0x5e 0x14 0x8d 0x46 0xe1 0x2e 0x97 0x5d 0x3d 0x75 0xf1 Config Nonce (base64) = tV4UjUbhLpddPXXx Config CRC32 = 0xe 0xdc 0xac 0xad Config CRC32 (base64) = DtysrQ== Ciphertext length = 48 Config Key = 0xa2 0x42 0x99 0x5 0x5f 0x1f 0xc 0x14 0xcb 0xdd 0xb 0x1 0xdf 0xa6 0x4c 0x34 0xf5 0xfd 0x3 0x3c 0xa7 0xf1 0xaf 0x30 0xa0 0xc7 0x5c 0x57 0x35 0x9d 0x41 0xe0 Config Key (base64) = okKZBV8fDBTL3QsB36ZMNPX9Azyn8a8woMdcVzWdQeA= ====== Config ====== Head = 0xad 0x29 0x2f 0xcb Check User is SYSTEM = 0 Mutex trigger = 0 Delete Loader trigger = 0 Patch EtwEventWrite trigger = 1 Payload in Loader = 0 Payload Name Length = 14 Payload Name = Despxs.dll Payload Size = 3f800 Payload FilePointor = 0 ----- ### Dll Hollowing ###### wlbsctrl.dll Dll hijack ###### Synchost.exe’s Module ###### libEGL.dll Signed file Read File ###### Signed file ###### dll hollowing launcher Load module Create Process Find target dll in System32 ###### Synchost.exe ###### Choose aaclient.dll ###### DLL Hollowing: Inject l l d i ----- ### Dll Hollowing (cont.) ----- ### Certificate bypass ###### The address of the Certificate Table ###### セワシ Valid certificate ###### セワシ Shell code ###### Valid certificate ###### signature length ----- ### .NET loader ###### 1. System.Configur ation.Install.Inst aller ###### kstvmutil.ax 2.Read File payload and decrypt with AES .NET loader(obfuscation by ConfuserEx) ###### InstallUtil.exe KBDHE475. dll Payload: 3.Inject cobalt strike or Use InstallUtil to bypass application payload via other backdoor: Process allowlist restrictions. ex: Natwalk Hollowing sdiagnhost.exe ###### payload ----- ### .NET loader structure ###### Version 2.63 offset data offset 38(h) – md5 hash of offset 48 until end 47 offset 48-53 Sha256 as AES key offset 54-67 MD5 as AES IV offset 68 - end Encrypted payload with AES(ECB) After decryption Version 17.102 offset Data offset 84(h) -93 md5 hash of offset 48 until end offset 94-9f Sha256 as AES key offset a0-ab MD5 as AES IV offset ac - end Encrypted payload with AES(ECB) |offset|data| |---|---| |offset 0-3|must be 1F A4 3A AC| |offset 4-7|the length of the payload| |offset 8 - end|malware payload| |offset|data| |---|---| |offset 38(h) – 47|md5 hash of offset 48 until end| |offset 48-53|Sha256 as AES key| |offset 54-67|MD5 as AES IV| |offset 68 - end|Encrypted payload with AES(ECB)| |offset|Data| |---|---| |offset 84(h) -93|md5 hash of offset 48 until end| |offset 94-9f|Sha256 as AES key| |offset a0-ab|MD5 as AES IV| |offset|data| |---|---| |offset 0-3|must be 0C C0 73 95| |offset 4-7|the length of the payload| |offset 8 - end|malware payload| ----- ### Fishmaster loader  PDB : C:\Users\test\Desktop\fishmaster\x64\Release\fishmaster.pdb  Some have “Bidenhappyhappyhappy” in strings  Two ways to decrypt payload  Xor with hardcode key, ex:” Bsiq_gsus” or “miat_mg”  Use UUIDShellcode and callback function ----- ### Funnyswitch loader  Name from ptsecurity*, which will inject .NET backdoor funny.dll in memory  We found new version loader(mcvsocfg.dll) which may target McAfee user  E:\VS2019_Project\while_dll_ms\whilte\x64\Release\macoffe.pdb  Another : ##### E:\\VS2019_Project\\prewhiltedll\\x64\\Release\\prewhiltedll.pdb  We found the new loader inject Cobalt Strike and funny.dll ----- ### Early code injection Loader  Using open source Alaris loader* to use ##### syscalls to run cobalt strike  Load PNG resource as payload and decrypt ##### with RC4  Using Detour to hook the Freelibrary API of ##### the launcher  Using early bird code injection technique  NtTestAlert  KiUserApcDispatcher ----- ## Backdoor ----- #### APT41’s Backdoor during 2020-2021 ###### RBRAT ###### Spyder ----- ### errorroot  A listening-port backdoor, was first found in 2019  New version in 2021  c:\js\js.pdb  add “http://+:80/default” to the URL Group of the server to enable the server ##### to open port 80  If the format of packet which connecting to the errorroot is wrong, the server ##### will send a unique error message:" " and redirect you to http://[IP]/  It can just use curl to send the instruction to errorroot ###### "curl -v http://[ip]/default -d echo -e ‘\x00\x00\x00\x00\x65\x71\xae\xdc\x12\x34\x56\x78\x01\xbc’ --output -" ----- ### Command of errorroot |command|description| |---|---| |0x12|Kill Process| |0x13|Mimikatz_kuhl_m_ts_session| |0x18|Start process| |0x19|Call function by address(offset+0x50,0x58,0x60)| |0x1A|Call function by address (offset+0x70,0x80)| |0x1B|Call function by address (offset+0x68)| |0x1C|Call function by address (offset+0x78)| |command|description| |---|---| |0x0|send victim info(computer name, User name, Process name, Os versiion, IP)| |0x1|Open shell| |0x2|close process/thread/handle| |0x3|write data to pipe(must use 0x1 to open a pipe)| |0x4|send pipe info| |0x7|send logic drive info| |0x9|List File| |0xB|Upload File| |0xD|Download File| |0xF|Delete File| ----- ### RBRAT  Name from its function prefix  Ex: “RB”Shell  May have some relations to Rbdoor  Mutex  googleupdater1.0.1  Listen port backdoor  Import table with windivert  Add firewall rule |command|description| |---|---| |0|beacon| |1|Open a shell(RBShell)| |2|Upload file(RBUpload)| |3|download file(RBDownload)| |4|collect system info| |5|collect network info| |6|list process| |7|collect service info| |8|take screenshot| |250|File Exploer(RBFileExploer)| ----- ### RBRAT(cont.)  Having magic number of packets just like ##### Rbdoor /Stone  Magic number (static key)  0xA1B5D2F,0x4A3C7FD5  One of Rbdoor’s magic number : ##### 0xABC18CBA*  Shell command of RBRAT  May modified from Cryptcat ----- ### Natwalk  Dropped by chatloader  First seen in the wild in 2021/3, and first seen on VT in 2021/7  Shellcode based backdoor  It uses register + offset to call the Windows api (also used by crosswalk)  The name is from the unique file path it will look up : ##### “%AllUserProfile%\UTXP\nat\” ----- ### Natwalk(cont.)  Transport protocol  Raw TCP socket  HTTPS:Post requests to C2 server  gtsid : generated by CryptGenRamdom  gtuvid : generated by CryptGenRamdom and md5 operation  Uses chacha20 md5 to encrypt/decrypt the message to/from C2 server ###### the post request of Natwalk ###### raw TCP ----- ### Natwalk(cont.)  Crosswalk also uses register + offset to call the Windows api in shellcode  First cammand code are both 0x64  But commands are different ----- ### Natwalk(cont.) ###### Software\Microsoft\Windows\CurrentVersion\Intern et Settings ProxyServer texplorer.exe %AllUsersProfile%\UTXP\nat\ %02X POST Mozilla/5.0 Chrome/72.0.3626.109 Safari/537.36 gtsid: gtuvid: https://msdn.microsoft.com https://www.google.com https://www.twitter.com https://www.facebook.com |command|description| |---|---| |0x64|close connection| |0x5C|create session key| |0x66|open a shell| |0x68|download file| |0x70|Upload file| |0x74|Delete File| |0x78|kill process| |0x7c|run shellcode| |0x7e|Unknown| |0x80|Unknown| |0x82|list process| |0x84|Unknown| |0x8C|list service| ###### Unique string in the bottom of Natwalk ###### 0x8E list directory ----- ### HIGHNOON(Botdll64) ###### WmiApSrv.exe wbemcomn.dll sdhasjk.dll Dll hijack IAT modify ###### Decrypt payload with DPIAPI/AES ###### Botdll64.dll HIGHNOON Packed with UPX in memory Windivert.dll (3) re (2a) injected Matching packet packet (2b) non-matching packet ###### (1) packet ----- ### HIGHNOON Loader ###### DPAPI version AES version “F:\2019\RedEye\Door\Bin\Middle64.pdb” ----- ### HIGHNOON command  Command is same as the HIGHNOON mentioned by Macnica* in 2018 |command|description| |---|---| |0|Bind Network Socket| |1|Check IP address change and Receive Packet, Console Output| |3|Console Output| |4|Read //DEV//NULL and Console Output| |5|Check IP address change and Receive Packet, Console Output| ----- ### Funnydll* ``` ``` ###### Base64+AES decrypt mcvsocfg.dll Stage_1.shellcode Funny.dll ###### config ###### Js module ----- ### Funnydll  In 2020, the config of funnydll is plaintext, in 2021, the config will decrypt by ##### funny.core.run which using AES and base64  Command, protocol, and js module are same as 2020* ----- ### Shadowpad  APT41 used the new builder of shadowpad in 2021, which was mentioned in ##### Ptsecurity’s report* which used new obfuscation method and decryption method for configuration  We think this builder was a shared Tool, because we have also seen Naikon ##### Team use this builder  Md5 of the loader:3520e591065d3174999cc254e6f3dbf5 ###### def decrypt_string(src): key = struct.unpack("