# 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("