概述

  Kimsuky 是位于朝鲜的APT组织,又名(Mystery Baby, Baby Coin, Smoke Screen,BabyShark, Cobra Venom)等,最早由Kaspersky在2013年披露。
  该组织长期针对于韩国的智囊团、政府外交、新闻组织、教育学术组织等进行攻击,在过去几年里,他们将攻击目标扩大到包括美国、俄罗斯和欧洲各国在内的国家。主要目的为窃取情报、间谍活动等。
  Kimsuky使用各种鱼叉式网络钓鱼和社会工程方法来获取对受害者网络的初始访问权限。

2. 样本详情

文件名 ESTCommon.dll
Md5 6844589e2962b3914824cc8b90a552a6
文件类型 Dll x64

4. 详细分析

1.字符串解密

  恶意程序将所有可见的字符串和重要的API使用自定义的加密算法进行加密,加密后的数据以十六进制的ANSII格式存放,当需要使用时调用解密函数进行解密。如下图:

首先将加密数据转换成十六进制,然后取前16个字节为异或key,剩余的数据为已加密的字符串。 解密算法如下,当i为0时,string[i-1]为0。

1
key[i] ^ string[i-1] ^ string[i]

以上图中的加密数据为例,解密过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
异或Key为: 5a a6 54 15 c2 fc 1b e5 25 29 0b 29 23 75 89 4b
加密字符为: 31 f2 d4 af 08 98 b0 67 6c 21 46 03
依次异或解密:
0x5a ^ 0x00 ^ 0x31 = ‘k’
0xa6 ^ 0x31 ^ 0xf2 = ‘e’
0x54 ^ 0xf2 ^ 0xd4 = ‘r’
0x15 ^ 0xd4 ^ 0xaf = ‘n’
0xc2 ^ 0xaf ^ 0x08 = ‘e’
0xfc ^ 0x08 ^ 0x98 = ‘l’
0x1b ^ 0x98 ^ 0xb0 = ‘3’
0xe5 ^ 0xb0 ^ 0x67 = ‘2’
0x25 ^ 0x67 ^ 0x6c = ‘.’
0x29 ^ 0x6c ^ 0x21 = ‘d’
0x0b ^ 0x21 ^ 0x46 = ‘l’
0x29 ^ 0x46 ^ 0x03 = ‘l’
最后解密出字符串”kernel32.dll”

用python脚本编写的解密代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def decrypt(s):
s_bytes = bytes.fromhex(s)
key = s_bytes[0:16]
str = s_bytes[16:]

decrypt_str = ""
for i in range(0,len(str)):
if i == 0 :
ch = 0
else:
ch = str[i-1]
ch = key[i%16] ^ ch ^ str[i]
decrypt_str = "%s%c"%(decrypt_str,ch)
print(decrypt_str)

2.判断互斥量

恶意程序在API解析完成后会判断互斥量”SpyRegsvr32-20210604170153”是否存在,如果存在则退出程序避免重复允许。

3.权限提升

恶意程序通过检测ConsentPromptBehaviorAdminPromptOnSecureDesktop的值来判断UAC是否被启用,如果这两个注册表项值都为0, 则表示UAC已被禁用无需做提权操作。

1
2
3
4
- HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 
ㄴConsentPromptBehaviorAdmin
- HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
ㄴ PromptOnSecureDesktop

UAC检测代码如下:

判断当前进程是否有TokenElevation。

如果UAC被禁用并且当前进程没有TokenElevation,则通过powershell来间接使用regsvr32启动恶意进程,此时恶意程序具有与regsvr32相同的权限。

4. 线程执行主要功能

恶意程序使用多个线程来实现主要功能, 创建的线程如下:

1. 屏幕截图线程

该线程的主要功能为每隔5分钟屏幕截图依次并通过SMTP协议发送到邮件服务。截图后文件保存到目录”c:\\programData\\{random}.tmp”,当整个文件的数据被加密时,文件名改成” {random }.tmp.tmp”。

2. 键盘按键记录线程

该线程的主要功能为监听带有窗口名称的按键记录,它每记录256次按键就将其写入到文件,然后休眠1秒,最后每隔10分钟发送按键记录文件到邮件服务。

3. 文件监控线程

该线程的主要功能是每隔一分钟从指定的目录搜索指定后缀的文件。这些目录分别是:

1
2
3
4
%Desktop%
%Downloads%
%Documents%
AppData\Local\Microsoft\Windows\INetCache\IE

如果发现指定后缀的文件,将文件名写入到文件list.fdb中。

4. USB文件监控线程

恶意程序通过函数get_usbs找到所有存在的USB驱动器,然后通过dir命令获取该驱动器的文件列表,压缩加密后发送的邮件服务。

5. 泄露文件列表线程

该文件由于恶意程序从受害者机器上收集的各种数据,该文件被保存到路径:

1
C:\ProgramData\Software\ESTsoft\Common\list.fdb

文件格式如下:

1
2
3
4
5
Struct format
{
Uint16_t magic;//值为0xFEFF
Char* file_or_dir_name[];//多个完整文件名或目录名
}

该线程的主要功能是将list.fdb中的文件或目录列表信息压缩加密后发送到邮件服务。一旦发送成功,恶意程序就会将list.fdb中包含文件或目录列表的数据清除,只留下magic部分。

5.C&C解密

读取电子邮件

  攻击者将邮件服务作为发送C&C指令和接收泄露数据信息的中转站,C&C指令由C&C服务器发起,并以电子邮件的形式存放在特定邮件账户的特定目录中,邮件正文无任何内容但是包含由加密的附件,该附件提供后门要执行的命令。恶意程序每隔30秒。邮件读取过程如下:

1
2
发送IMAP命令”UID SEARCH ALL”获取所有邮件的UID。收到的响应内容为”\* SEARCH 1 2 3 4”,后面的数字就是邮件的uid号
根据获取到的uid发送请求到邮件服务获取邮件数据,请求链接为 imaps://imap.daum.net:993/cmd/;Uid={uid}

1.在邮件搜索关键字” Subject:”找到邮件主题数据
2.附件内容在邮件主题中以base64编码, 以”filename=”开头,结尾一般是”–”,因此搜索这两个字符串就能找到对应的附件数据。
3.附件保存为临时文件,发送post请求让邮件服务删除该邮件。

1
2
请求连接: imaps://imap.daum.net:993/cmd/;Uid={uid}
传输参数:STORE 1 +Flags \Deleted

电子邮件附件解密

  恶意程序通过SMTP协议从账号为k2x0604@daum.net的邮箱的cmd文件夹中获取要执行的C&C命令,
C&C指令以加密的形式存放在邮件附件中。
  恶意程序获取到邮件后首先将邮件附件下载并第一次解密后保存到临时目录,文件名为**{temp_name}.enc。邮件附件使用如下结构保存加密的C&C指令数据。

1
2
3
4
5
6
7
8
9
10
11
12
Struct encrypt_Command
{
//伪装成pdf文件,值为%PDF-1.7..4 0 obj
Char fake_pdf_head[0x10];
//xor_key 和 encrypt_command的CRC32值的取反值
//用于验证数据是否被修改
Uint32_t vertifity_crc;
//用于解密C&C指令
Char xor_key[0x10];
//加密的C&C指令
Char encrypt_command[];
}

  首先查找PDF标识,如果不是则取消解密操作,否则进行解密C&C指令操作。恶意程序通过将邮件附件伪装成PDF文件的手段绕过邮件安全系统的检测。

  恶意程序采用自定义算法生成一个key,该key与xor_key、encrypt_command通过自定义算法计算出crc32值,将该值取反后与vertifity_crc比较来验证邮件附件是否被修改过。

  解密加密的C&C指令时,使用xor_key来进行解密;解密后写入临时文件。

C&C指令解密

  恶意程序在第一次解密邮件附件后,C&C指令部分仍处于加密状态,对应的格式如下:

1
2
3
4
5
6
Struct encrypt_cmd
{
Uint32_t cmd_len; //解密后C&C指令数据的大小
Char key[0x80]; //使用RAS算法加密的RC4密钥
Char crypt_cmd[]; //已加密的C&C指令
}

  为防止被人解密出C&C指令数据,攻击者将用于解密C&C指令的RC4密钥用RSA算法加密,即发送邮件时使用公钥对RC4密钥加密,接收到邮件时使用RSA私钥解密RC4密钥。
  RSA公钥与密钥以硬编码和加密的形式存放在程序内,解密方法与解密字符串一样。解密后的数据为十六进制字符串,转换成十六进制为对应的MicrosoftBlob Format格式,使用程序openssl可以将其转换成文本形式。

解密后的RSA 公钥如下:

解密后的RSA私钥如下:

  恶意程序将要发送的数据加密后上传到电子邮件附件然后发送到邮件服务。对数据加密的过程如下:

1.生成大小为117的随机数并计算其md5值作为RC4算法的密钥
2.使用RSA公钥加密RC4密钥
3.将原始数据长度写入文件,长度为4字节
4.将加密后的RC4密钥写入文件,长度为0x80字节
5.加密要加密的数据,并写入文件

代码实现如下图

恶意程序接从邮件服务获取邮件时解密邮件附件得到加密的C&C指令,解密过程如下:

1.从邮件附件中读取被加密的RC4密钥
2.使用RSA私钥解密RC4密钥
3.使用RC4密钥解密加密的C&C指令

代码实现如下图:

从对邮件附件的加密解密来看,RC4算法使用的密钥为随机生成并且被RSA算法加密,只要RSA密钥不被泄露,想要解密数据目前是很困难的。

指令读取

恶意程序要执行的指令包含在由攻击者通过邮件服务发送的电子邮件附件中,C&C指令部分解密后使用的结构如下:

1
2
3
4
5
6
7
Struct C2C_command
{
uint32_t commandID;//指令ID
uint32_t param_cnt;//参数个数
uint32_t* params_size;//保存每个参数的大小
void* params;//保存所有的参数,参数大小由字段params_size
}

C&C指令读取代码如下:

6.C&C指令

C&C指令由恶意程序从邮件附件中解密而来,主要由以下几种:

C&C指令 描述
0x64 写入数据到list.fdb
0x66 创建文件
0x65 启用或禁用恶意程序的主要功能
0x00 子指令1:执行文件并返回输出结果
0x00 子指令1或3: 通过regsvr32.exe执行命令
0x02 DLL注入

1. 写入文件或目录列表到list.fdb

攻击者在该文件中写入想要从受害者机器上获取的文件和目录,等到下一次执行泄露文件列表线程时将这些文件泄露出去。该命令使用的结构如下:

1
2
3
4
5
6
Struct format{
Uint32_t commid;//0x64
Uint32_t param_cnt;//参数个数为1
Uint32_t param_size;//参数大小
Uint8 param[];//包含文件列表或者目录列表,使用”\r\n”分隔
}

2. 文件创建

该指令主要用于攻击在在受害者机器上创建文件,使用的指令格式为:

1
2
3
4
5
6
7
8
Struct format{
Uint32_t command_id;//0x66
Uint32_t param_cnt;//个数为2,文件名和文件数据
Uint32_t file_size;//文件数据大小
Uint8_t file[file_size]; //文件数据
Uint32_t file_name_len;//文件名长度
Uint8_t file_name[file_name_len];//文件名
}

3. 关闭或启用主要功能

该指令的主要功能用于开启或者关闭主要功能,比如键盘按键记录、文件监控、屏幕截图等等。该指令使用的格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
Struct format{
Uint32_t command_id;//0x65
Uint32_t param_cnt;//参数个数为4
Uint32_t param1_len;//参数1长度,值为1
Bool enable_keyboard_mon;//1为启用,0为关闭
Uint32_t param2_len;//值为1
Bool enable_screen_mon;//1为启用,0为关闭
Uint32_t param3_len;//值为1
Bool enable_folder_mon;//1为启用,0为关闭
Uint32_t param4_len;//值为1
Bool enable_usb_mon;//1为启用,0为关闭。
}

4. 执行命令并返回执行结果

该指令的主要功能为在受害者机器上执行命令,并将执行后的结果发送到邮件服务。
该指令使用的结构如下:

1
2
3
4
5
6
Struct format{
Uint32_t command_id;//值为0
Uint32_t param_cnt;//值为1,使用一个参数
Uint32_t cmd_str_len;//命令字符串的长度
Wchar_t cmd_str[cmd_str_len];//命令字符串
}

5. 使用regsvr32.exe调用dll程序

该指令主要是使用regsvc32.exe来调用dll文件,前提是该dll文件导出了函数**DllRegisterServer。**dll文件下载后保存到临时目录,使用regsvr32.exe注册成功后将该dll文件删除。该指令使用的格式如下:

1
2
3
4
5
6
Struct format{
Uint32_t command_id;//值为0
Uint32_t param_cnt;//参数个数
Uint32_t file_size;//文件长度
Uint32_t dll_file_data;//文件数据
}

6. dll注入

该命令的功能主要为将dll注入到进程中,使用的结构如下:

1
2
3
4
5
6
7
8
Struct format{
Uint32_t command_id;//值为2
Uint32_t param_cnt;//使用两个参数
Uint32_t name_len;//函数名长度
Uint8_t function_name[name_len];//函数名
Uint32_t file_size;//dll文件长度
Uint8_t file_buf[file_size];//dll文件数据
}

将接收到的dll注入到指定的进程中,并执行指令中给定的导出函数function_name。

7. ATT&CK矩阵

Tactic ID Name Description
exfiltration T1041 Exfiltration Over C2 Channel 通过邮件泄露数据
Command and Control T1071.003 Application Layer Protocol:Mail Protocols 使用邮件服务接收泄露数据或发送C&C指令
T1001 Data Obfuscation 使用RC4加密或解密数据,使用RSA算法加密RC4密钥
Collection T1113 Screen Capture 屏幕截图
T1056 Input Capture 按键记录
T1560 Archive Collected Data 使用ZIP算法压缩收集的数据
T1005 Data from Local System 搜索本地文件
T1025 Data from Removable Media 从USB驱动器收集数据
Discovery T1083 File and Directory Discovery 遍历文件或目录
T1082 System Information Discovery 获取操作系统版本号用于机器标识符
Persistence T1547 Boot or Logon Autostart Execution 注册自启动项
execution T1059 Command and Scripting Interpreter 使用cmd执行命令

2022-07-15

⬆︎TOP