PowerPoint 簡報
Evolution after prosecution
: Psychedelic APT41
Aragorn Tseng Charles Li Peter Syu Tom Lai
Malware Analysis
Incident Response
Threat Intelligence
Malware Analysis
Incident Response
Tool Development
Incident Response
Malware Analysis
Penetration
Malware Analysis
Threat Hunting
Threat Intelligence
Who we are
2
AGENDA
01
02
03
04
05
Initial Access
Cobalt Strike Loader
APT41’s Backdoor
C2 Hiding Technique
Relation to other operations
06 Takeaway
The content of APT41 in this
talk is mainly from
2020/9 to 2021/8
Evolution after prosecution: Psychedelic APT41
Target Country Talk in last section
5
Target Industry
High-techHealthcare Airlines
Financial ResearchGovernment
Media
Gaming
Telecom
EnergyEducation
Manufacturing
6
New TTP
◆ Dll hollowing technique
◆ Certificate bypass
◆ InstallUtil
◆ Early bird code injection
◆ CDN service and Cloudfare worker
◆ Some new backdoor
7
Initial Access
◆ CVE-2021-34527(printnightmare)
◆ SQL vulnerabilities
◆ phpmyadmin vulnerabilities
◆ Web vulnerabilities
◆ Flash installer
◆ Fake Decoy Icon
8
Cobalt Strike loader
Evolution after prosecution: Psychedelic APT41
Timeline for disseminating the
Cobalt Strike
2020.7
2020.11
2021.1
2021.3
2021.4
Chacha20
shellcode or
loader(Chatloader)
appeared to
extract Cobalt
strike Beacon
Use CDN service in
Cobalt Strike,
especially DNS
beacon
Use Cloudfare
worker to hide real
C2 IP
Use certificate
bypass and dll
hollowing
technique in
Chatloader
Use multiple .NET
loaders and
misuse InstallUtil
to load
CobaltStrike 2021.6
Use funnyswitch to
load Cobalt Strike
and use early bird
code injection
technique
10
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
_length
config_enc_length ciphertext
0x100:0x120 0x20 config key
11
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
0x4 Payload crc32
0xC Payload Nonce
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
Header:CB2F29AD
Header:8BD6488B
12
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
Payload CRC32 = 0x40 0xf6 0x8f 0xa7
Payload Nonce (12 bytes) = 0x93 0x49 0x68 0x79 0x6a 0xda 0xb5 0xcf 0xf0 0xf1 0xb3 0x4f
13
Dll Hollowing
Signed file
Dll hijack
libEGL.dll
wlbsctrl.dll
Find target dll in
System32
Kernel32.dll
User32.dll
aaclient.dll
DLL Hollowing: Inject
malware payload in
aaclinet.dll’s .text section
Synchost.exe
Create
Process
Synchost.exe’s
Module
Read File
Load module
launcher
payload
Choose
aaclient.dll
dll hollowing
14
Dll Hollowing (cont.)
https://github.com/forrest-orr/phantom-dll-hollower-poc 15
https://github.com/forrest-orr/phantom-dll-hollower-poc
Certificate bypass
セワシ
Valid
certificate
Valid
certificate
セワシ
Shell
code
The address of the Certificate Table
signature length
16
.NET loader
InstallUtil.exe KBDHE475.
dll
kstvmutil.ax
payload
1.
System.Configur
ation.Install.Inst
aller
3.Inject
payload via
Process
Hollowing
2.Read File
and decrypt
with AES
sdiagnhost.exe
Payload:
cobalt strike or
other backdoor:
ex: Natwalk
Use InstallUtil to bypass application
allowlist restrictions.
.NET
loader(obfuscation by
ConfuserEx)
17
.NET loader structure
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 0-3 must be 1F A4 3A AC
offset 4-7 the length of the payload
offset 8 - end malware payload
Version 2.63
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 0C C0 73 95
offset 4-7 the length of the payload
offset 8 - end malware payload
Version 17.102
After decryption
18
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
19
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
*https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-
backdoors-old-and-new/
Cobaltstrike funnydll 20
https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/
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
*https://github.com/cribdragg3r/Alaris
21
https://github.com/cribdragg3r/Alaris
Backdoor
Evolution after prosecution: Psychedelic APT41
APT41’s Backdoor during 2020-2021
Natwalk
APT41 Errorroot
HIGHNOON
Funnydll
Shadowpad
Cobalt strike
RBRAT
PlugX
Spyder
Winnti
Linux RAT
23
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 -"
24
http://[IP]/
Command of errorroot
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
0x11 List Process
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)
25
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)
26
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
*https://github.com/TKCERT/winnti-nmap-
script/blob/master/winnti-detect.nse
27
https://github.com/TKCERT/winnti-nmap-script/blob/master/winnti-detect.nse
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\”
rbx = 7FEF1431534
28
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
29
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
30
Natwalk(cont.)
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
0x8E list directory
31
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
Unique string in the bottom of Natwalk
HIGHNOON(Botdll64)
wbemcomn.dll sdhasjk.dllWmiApSrv.exe
Dll hijack IAT modify
Decrypt
payload with
DPIAPI/AES
Botdll64.dll
Packed with
UPX in
memory
HIGHNOON
Windivert.dll
Windivert.sys
User mode
Kernel
mode
Reflective
injection
(1) packet
(2a)
Matching
packet
(2b) non-matching packet
(3) re-
injected
packet
32
HIGHNOON Loader
DPAPI version
AES version
choose the driver determined by the dwMinorVersion 33
“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
*https://hitcon.org/2018/pacific/downloads/1214-R2/1330-1400.pdf
34
https://hitcon.org/2018/pacific/downloads/1214-R2/1330-1400.pdf
Funnydll*
config
mcvsocfg.dll Stage_1.shellcode Funny.dll
Base64+AES
decrypt
Js module
35*https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-
backdoors-old-and-new/
https://www.ptsecurity.com/ww-en/analytics/pt-esc-threat-intelligence/higaisa-or-winnti-apt-41-backdoors-old-and-new/
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*
36
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
37
def decrypt_string(src):
key = struct.unpack("