6月中旬,哈萨克斯坦与冠状病毒的斗争如火如荼。警惕案件数量的增加(甚至前总统努尔苏丹·纳扎尔巴耶夫(Nursultan Nazarbayev)被感染),地方当局决定再次关闭所有购物和娱乐中心,连锁店,市场和集市。那时,网络犯罪分子通过向俄罗斯和国际公司发送恶意邮件来利用这种情况。
威胁检测系统(TDS)组IB拦截了伪装为哈萨克斯坦共和国卫生部长的呼吁的危险信件。附件中包含的文档在启动时安装了Loki PWS(密码窃取者)家族的恶意程序,该程序旨在从受感染的计算机中窃取登录名和密码。将来,攻击者可以使用它们来访问电子邮件帐户,以进行财务欺诈,间谍活动或在黑客论坛上出售。
在本文中,CERT-GIB的分析师Nikita Karpov研究了当今最流行的Data Stealers之一的实例Loki。
今天,我们将考虑机器人的流行版本之一-1.8。它是活跃销售的,管理面板甚至可以在公共领域找到:此处。
管理面板示例:
Loki用C ++编写,是最流行的恶意软件之一,用于从受感染的计算机窃取用户信息。就像我们时代的祸害-勒索软件病毒-Data Stealer在被害者的计算机上击中后,以很高的速度执行任务-它不需要立足点并增加其在系统中的特权,因此几乎没有时间来防御攻击。因此,在恶意软件窃取用户数据的事件中,主要事件是调查事件。
打开包装并获得可行的恶意软件转储
在大多数情况下,分发是通过邮件列表中的附件进行的。伪装成合法文件的用户下载并打开附件,启动了恶意软件。
注射标记表明存在装载程序。
在DIE的帮助下,我们可以获得有关源文件是用VB6编写的信息。
熵图表示大量的加密数据。
启动后,第一个进程将创建一个子进程,将其注入并退出。第二个过程负责恶意软件的工作。短时间后,我们停止该过程并保存内存转储。要确认Loki是否在转储文件中,请查看命令中心网址,该网址多数情况下以fre.php结尾。
我们转储包含Loki的内存片段,并更正PE标头。
我们将使用TDS Huntbox系统检查转储的性能。
机器人功能
在检查反编译的恶意软件代码的过程中,我们发现包含四个功能的部分,这些功能在初始化操作所需的库后立即生效。在将它们分解后,我们确定了恶意软件的目的和功能。
为了方便起见,已将函数名称重命名为更具描述性的名称。
机器人功能由两个主要功能决定:
- Data Stealer是负责从101个应用程序中窃取数据并将其发送到服务器的第一个功能。
- 下载器-来自CnC(命令和控制)命令的执行请求。
为方便起见,下表列出了正在检查的Loki实例试图窃取数据的所有应用程序。
功能编号 | 应用 | 功能编号 | 应用 | 功能编号 | 应用 |
---|---|---|---|---|---|
1个 | 火狐浏览器 | 35 | FTP信息 | 69 | 经典FTP |
2 | 科莫多冰龙 | 36 | LinasFTP | 70 | 腻子/ KiTTY |
3 | 苹果Safari | 37 | FileZilla | 71 | 雷鸟 |
4 | K-Meleon | 38 | 员工FTP | 72 | 福克斯邮件 |
五 | 海猴子 | 39 | BlazeFtp | 73 | Pocomail |
6 | 群 | 40 | NET文件 | 74 | 增量邮件 |
7 | NETGATE黑鹰 | 41 | 的FTP | 75 | Gmail通知程序专业版 |
8 | 月神 | 42 | 远程FTP | 76 | 检查邮件 |
九 | 谷歌浏览器 | 43 | 豪华FTP | 77 | WinFtp |
十 | 歌剧 | 44 | 总指挥官 | 78 | 马丁·普里克里(Martin Prikryl) |
十一 | QTWeb浏览器 | 45 | FTPGetter | 79 | 32位 |
12 | QupZilla | 46 | WS_FTP | 80 | FTP浏览器 |
十三 | IE浏览器 | 47 | 邮件客户端配置文件 | 81 | 邮件
(softwarenetz) |
十四 | 歌剧2 | 48 | 全倾斜扑克 | 82 | 歌剧邮件 |
十五 | 赛博狐 | 49 | 扑克之星 | 83 | 邮箱 |
十六 | 苍白的月亮 | 50 | ExpanDrive | 84 | 福萨邮件 |
17 | 水狐 | 51 | 骏马 | 85 | 贝基! |
十八 | 皮金 | 52 | FlashFXP | 86 | POP3 |
19 | 超级腻子 | 53 | NovaFTP | 87 | 外表 |
20 | FTPShell | 54 | 网盘 | 88 | Ymail2 |
21 | NppFTP | 55 | 总指挥官2 | 89 | 特罗吉塔 |
22 | 我的FTP | 56 | SmartFTP | 90 | TrulyMail |
23 | FTP箱 | 57 | FAR经理 | 91 | .spn文件 |
24 | 谢罗德FTP | 58 | 比特维斯 | 92 | 待办事项清单 |
25 | 立即FTP | 59 | RealVNC
紧VNC |
93 | 胶粘物 |
26 | NexusFile | 60 | mSecure钱包 | 94 | 注意飞 |
27 | XFTP | 61 | 发现 | 95 | 注意齐拉 |
28 | 易FTP | 62 | FreshFTP | 96 | 便利贴 |
29 | SftpNetDrive | 63 | 比特币 | 97 | KeePass |
三十 | AbleFTP | 64 | 超FXP | 98 | 绕过 |
31 | JaSFtp | 65 | 立即FTP 2 | 99 | 我的机器人表格 |
32 | 自动化 | 66 | Vandyk SecureFX | 100 | 1密码 |
33 | 数码鸭 | 67 | Odin安全FTP专家 | 101 | Mikrotik WinBox |
34 | 全同步 | 68 | 一扔 |
联网
记录网络交互需要解决两个问题:
- 命令中心仅在发生攻击时可用。
- Wireshark不会在回送中记录漫游器通信,因此您需要使用其他方式。
最简单的解决方案是将Loki将与之通信的CnC地址转发到本地主机。对于机器人,服务器现在可以随时使用,尽管它没有响应,但是没有必要记录机器人的通信。为了解决第二个问题,我们将使用RawCap实用程序,该实用程序允许我们编写需要pcap的通信。接下来,我们将在Wireshark中解析记录的pcap。
在每次通信之前,漫游器会检查CnC的可用性,并在可用时打开套接字。所有网络通信均在传输级别使用TCP协议进行,而在应用程序级别使用HTTP。
下表显示了Loki作为标准使用的数据包头。
领域 | 值 | 描述 |
---|---|---|
用户代理 | Mozilla / 4.08(Charon; Inferno) | Loki的典型用户代理 |
接受 | * / * | |
内容类型 | 应用/八位字节流 | |
内容编码 | 二元 | |
内容密钥 | 7DE968CC | 先前标头的散列结果(散列是通过多项式0xE8677835的自定义CRC算法完成的) |
连接 | 关 |
- 记录数据的结构取决于漫游器的版本,在较早的版本中,没有字段负责加密和压缩选项。
- 服务器根据请求的类型确定如何处理接收到的数据。服务器可以读取7种数据:
- 0x26被盗的钱包数据
- 0x27被盗的申请数据
- 来自服务器的0x28命令请求
- 0x29卸载被盗文件
- 0x2A POS
- 0x2B键盘记录器数据
- 0x2C截图
- 在检查的实例中,仅存在0x27、0x28和0x2B。
- 每个请求都包含有关漫游器和受感染系统的常规信息,服务器会根据这些信息识别一台计算机的所有报告,然后根据请求的类型提供一些信息。
- 在该僵尸程序的最新版本中,仅实现了数据压缩,并且为将来准备了加密字段,并且服务器不对其进行处理。
- 开源的APLib库用于压缩数据。
当使用被盗数据形成请求时,漫游器会分配一个大小为0x1388(5000字节)的缓冲区。下表显示了0x27请求的结构:
偏压 | 规模 | 值 | 描述 |
---|---|---|---|
0x0 | 0x2 | 0x0012 | Bot版本 |
0x2 | 0x2 | 0x0027 | 请求类型(发送被盗数据) |
0x4 | 0xD | ckav.ru | 二进制ID(也会出现XXXXX11111) |
0x11 | 0x10 | -- | 用户名 |
0x21 | 0x12 | -- | 电脑名称 |
0x33 | 0x12 | -- | 电脑域名 |
0x45 | 0x4 | -- | 屏幕分辨率(宽度和高度)
|
0x49 | 0x4 | -- | |
0x4D | 0x2 | 0x0001 | 用户权限标志(如果为管理员则为1) |
0x4F | 0x2 | 0x0001 | SID标志(如果设置则为1) |
0x51 | 0x2 | 0x0001 | 系统位数标志(如果为x64,则为1) |
0x53 | 0x2 | 0x0006 | Windows版本(主要版本号) |
0x55 | 0x2 | 0x0001 | Windows版本(次要版本号) |
0x57 | 0x2 | 0x0001 | 附加系统信息(1 = VER_NT_WORKSTATION) |
0x59 | 0x2 | -- | |
0x5B | 0x2 | 0x0000 | 被盗的数据是否已发送 |
0x5D | 0x2 | 0x0001 | 是否使用了数据压缩 |
0x5F | 0x2 | 0x0000 | 压缩类型 |
0x61 | 0x2 | 0x0000 | 是否使用了数据加密 |
0x63 | 0x2 | 0x0000 | 加密方式 |
0x65 | 0x36 | -- | 来自MachineGuid的MD5寄存器值 |
0x9B | -- | -- | 压缩的被盗数据 |
缓冲区大小:0x2BC(700字节)
偏压 | 规模 | 值 | 描述 |
---|---|---|---|
0x0 | 0x2 | 0x0012 | Bot版本 |
0x2 | 0x2 | 0x0028 | 请求类型(来自命令中心的命令请求) |
0x4 | 0xD | ckav.ru | 二进制ID(也会出现XXXXX11111) |
0x11 | 0x10 | -- | 用户名 |
0x21 | 0x12 | -- | 电脑名称 |
0x33 | 0x12 | -- | 电脑域名 |
0x45 | 0x4 | -- | 屏幕分辨率(宽度和高度) |
0x49 | 0x4 | -- | |
0x4D | 0x2 | 0x0001 | 用户权限标志(如果为管理员则为1) |
0x4F | 0x2 | 0x0001 | SID标志(如果设置则为1) |
0x51 | 0x2 | 0x0001 | 系统位数标志(如果为x64,则为1) |
0x53 | 0x2 | 0x0006 | Windows版本(主要版本号) |
0x55 | 0x2 | 0x0001 | Windows版本(次要版本号) |
0x57 | 0x2 | 0x0001 | 附加系统信息(1 = VER_NT_WORKSTATION) |
0x59 | 0x2 | 0xFED0 | |
0x5B | 0x36 | -- | 来自MachineGuid的MD5寄存器值 |
数据包中每个命令的缓冲区大小:0x10(16个字节)+ 0x10(16个字节)。
HTTP标头(数据开始) | \ r \ n \ r \ n | [0D 0A 0D 0A] | 4字节 | ||
- | - | 4 | |||
2 | [00 00 00 02] | 4 | |||
4 |
4 |
4 |
4 |
() |
|
---|---|---|---|---|---|
#0
EXE- |
[00 00 00 00] | [00 00 00 00] | [00 00 00 00] | [00 00 00 23] | www.notsogood.site/malicious.exe |
#1
DLL |
[00 00 00 00] | [00 00 00 01] | [00 00 00 00] | [00 00 00 23] | www.notsogood.site/malicious.dll |
#2
EXE- |
[00 00 00 00] | [00 00 00 02] | [00 00 00 00] | [00 00 00 23] | www.notsogood.site/malicious.exe |
#8
(HDB file) |
[00 00 00 00] | [00 00 00 08] | [00 00 00 00] | [00 00 00 00] | - |
#9
|
[00 00 00 00] | [00 00 00 09] | [00 00 00 00] | [00 00 00 00] | - |
#10
|
[00 00 00 00] | [00 00 00 0A] | [00 00 00 00] | [00 00 00 00] | - |
#14
Loki |
[00 00 00 00] | [00 00 00 0E] | [00 00 00 00] | [00 00 00 00] | - |
#15
Loki |
[00 00 00 00] | [00 00 00 0F] | [00 00 00 00] | [00 00 00 23] | www.notsogood.site/malicious.exe |
#16
更改检查服务器响应的频率 |
[00 00 00 00] | [00 00 00 10] | [00 00 00 00] | [00 00 00 01] | 五 |
#17
删除Loki并退出 |
[00 00 00 00] | [00 00 00 11] | [00 00 00 00] | [00 00 00 00] | -- |
网络流量解析器
通过此分析,我们获得了解析Loki网络交互所需的所有信息。
该解析器是用Python实现的,接收一个pcap文件作为输入,并在其中找到所有属于Loki的通信。
首先,让我们使用dkpt库查找所有TCP数据包。要仅接收http数据包,请在使用的端口上放置一个过滤器。在收到的http数据包中,我们选择那些包含众所周知的Loki头的数据包,并获取需要解析的通信,以便以可读形式从中提取信息。
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not isinstance(eth.data, dpkt.ip.IP):
ip = dpkt.ip.IP(buf)
else:
ip = eth.data
if isinstance(ip.data, dpkt.tcp.TCP):
tcp = ip.data
try:
if tcp.dport == 80 and len(tcp.data) > 0: # HTTP REQUEST
if str(tcp.data).find('POST') != -1:
http += 1
httpheader = tcp.data
continue
else:
if httpheader != "":
print('Request information:')
pkt = httpheader + tcp.data
httpheader = ""
if debug:
print(pkt)
req += 1
request = dpkt.http.Request(pkt)
uri = request.headers['host'] + request.uri
parsed_payload['Network']['Source IP'] = socket.inet_ntoa(ip.src)
parsed_payload['Network']['Destination IP'] = socket.inet_ntoa(ip.dst)
parsed_payload_same['Network']['CnC'] = uri
parsed_payload['Network']['HTTP Method'] = request.method
if uri.find("fre.php"):
print("Loki detected!")
pt = parseLokicontent(tcp.data, debug)
parsed_payload_same['Malware Artifacts/IOCs']['User-Agent String'] = request.headers['user-agent']
print(json.dumps(parsed_payload, ensure_ascii=False, sort_keys=False, indent=4))
parsed_payload['Network'].clear()
parsed_payload['Compromised Host/User Data'].clear()
parsed_payload['Malware Artifacts/IOCs'].clear()
print("----------------------")
if tcp.sport == 80 and len(tcp.data) > 0: # HTTP RESPONCE
resp += 1
if pt == 40:
print('Responce information:')
parseC2commands(tcp.data, debug)
print("----------------------")
pt = 0
except(dpkt.dpkt.NeedData, dpkt.dpkt.UnpackError):
continue
在所有Loki请求中,前4个字节负责bot版本和请求类型。使用这两个参数,我们确定如何处理数据。
def parseLokicontent(data, debug):
index = 0
botV = int.from_bytes(data[0:2], byteorder=sys.byteorder)
parsed_payload_same['Malware Artifacts/IOCs']['Loki-Bot Version'] = botV
payloadtype = int.from_bytes(data[2:4], byteorder=sys.byteorder)
index = 4
print("Payload type: : %s" % payloadtype)
if payloadtype == 39:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Application/Credential Data"
parse_type27(data, debug)
elif payloadtype == 40:
parsed_payload['Network']['Traffic Purpose'] = "Get C2 Commands"
parse_type28(data, debug)
elif payloadtype == 43:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Keylogger Data"
parse_type2b(lb_payload)
elif payloadtype == 38:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Cryptocurrency Wallet"
elif payloadtype == 41:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Files"
elif payloadtype == 42:
parsed_payload['Network'].['Traffic Purpose'] = "Exfiltrate POS Data"
elif payloadtype == 44:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Screenshots"
return payloadtype
接下来的一行将是解析服务器的响应。要仅读取有用的信息,请查找\ r \ n \ r \ n序列,该序列定义了数据包头的结尾和来自服务器的命令的开头。
def parseC2commands(data, debug):
word = 2
dword = 4
end = data.find(b'\r\n\r\n')
if end != -1:
index = end + 4
if (str(data).find('<html>')) == -1:
if debug:
print(data)
fullsize = getDWord(data, index)
print("Body size: : %s" % fullsize)
index += dword
count = getDWord(data, index)
print("Commands: : %s" % count)
if count == 0:
print('No commands received')
else:
index += dword
for i in range(count):
print("Command: %s" % (i + 1))
id = getDWord(data, index)
print("Command ID: %s" % id)
index += dword
type = getDWord(data, index)
print("Command type: %s" % type)
index += dword
timelimit = getDWord(data, index)
print("Command timelimit: %s" % timelimit)
index += dword
datalen = getDWord(data, index)
index += dword
command_data = getString(data, index, datalen)
print("Command data: %s" % command_data)
index += datalen
else:
print('No commands received')
return None
到此结束了对解析器算法主要部分的分析,然后继续我们在输出中获得的结果。所有信息均以json格式显示。
下面是解析器工作结果的图像,这些图像是从具有不同CnC并记录在不同环境中的各种漫游器的通信中获得的。
Request information:
Loki detected!
Payload type: 39
Decompressed data:
{'Module': {'Mozilla Firefox'}, 'Version': {0}, 'Data': {'domain': {'https://accounts.google.com'}, 'username': {'none@gmail.com'}, 'password': {'test'}}}
{'Module': {'NppFTP'}, 'Version': {0}, 'Data': {b'<?xml version="1.0" encoding="UTF-8" ?>\r\n<NppFTP defaultCache="%CONFIGDIR%\\Cache\\%USERNAME%@%HOSTNAME%" outputShown="0" windowRatio="0.5" clearCache="0" clearCachePermanent="0">\r\n <Profiles />\r\n</NppFTP>\r\n'}}
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Application/Credential Data",
"First Transmission": true
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
上面是对服务器0x27的请求(上传应用程序数据)的示例。为了进行测试,在三个应用程序中创建了帐户:Mozilla Firefox,NppFTP和FileZilla。Loki具有三个用于记录应用程序数据的选项:
- 以SQL数据库的形式(解析器将保存数据库并显示其中的所有可用行)。
- 以开放形式显示,例如Firefox中的示例。
- 作为NppFTP和FileZilla之类的xml文件。
Request information:
Loki detected!
Payload type: 39
No data stolen
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Application/Credential Data",
"First Transmission": false
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
第二个请求的类型为0x28,并从服务器请求命令。
Responce information:
Body size: 26
Commands: 1
Command: 1
Command ID: 0
Command type: 9
Command timelimit: 0
Command data: 35
来自CnC的响应示例,该响应发送了一个命令作为响应来启动键盘记录程序。并随后卸载键盘记录器数据。
Request information:
Loki detected!
Payload type: : 43
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Keylogger Data"
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
在工作结束时,解析器显示来自bot的每个请求中所包含的信息(有关bot和系统的信息)以及pcap文件中与Loki相关的请求和响应的数量。
General information:
{
"Network": {
"CnC": "nganyin-my.com/chief6/five/fre.php"
},
"Compromised Host/User Description": {
"User Name": "-",
"Hostname": "-",
"Domain Hostname": "-",
"Screen Resolution": "1024x768",
"Local Admin": true,
"Built-In Admin": true,
"64bit OS": false,
"Operating System": "Windows 7 Workstation"
},
"Malware Artifacts/IOCs": {
"Loki-Bot Version": 18,
"Binary ID": "ckav.ru",
"MD5 from GUID": "-",
"User-Agent String": "Mozilla/4.08 (Charon; Inferno)"
}
}
Requests: 3
Responces: 3
完整的解析器代码位于:github.com/Group-IB/LokiParser
结论
在本文中,我们仔细研究了Loki恶意软件,分解了其功能并实现了网络流量解析器,该解析器将大大简化事件分析过程,并帮助我们了解到底是从受感染的计算机中窃取了什么。尽管Loki的开发仍在进行中,但仅合并了1.8(或更早版本)版本,这是安全专业人员每天都会遇到的版本。
在下一篇文章中,我们将分析另一个流行的Data Stealer Pony,并比较这些恶意软件。
危害指标(IOC):
网址:
- nganyin-my.com/chief6/five/fre.php
- wardia.com.pe/wp-includes/texts/five/fre.php
- broken2.cf/Work2/fre.php
- 185.141.27.187/danielsden/ver.php
- MD5哈希值:B0C33B1EF30110C424BABD66126017E5
- User-Agent String: «Mozilla/4.08 (Charon; Inferno)»
- Binary ID: «ckav.ru»