0x00 前言
大概在一星期之前,我收到了某个用户发出的一封邮件:
上周三,攻击者通过尚未公开的一个Firefox 0day攻击了我,不知道用什么方法将一个程序释放到我的mac主机上(10.14.5)然后执行。
我觉得你可能对这个文件比较感兴趣,这可能是绕过gatekeeper的一种有趣方法,值得研究一下。
我当然很感兴趣,但当时我正在写另一篇文章(大家可以点击此处阅读该文章),有点腾不出手来。
现在尘埃落定,我想借此机会深入研究这次攻击行为,分析其中涉及到的持久化恶意软件。
0x01 Firefox 0day
用户联系我时,我还没有太多掌握此次攻击中使用的Firefox 0day,然而现在我已经拿到了足够多信息。
一开始用户提供的邮件内容如下(翻译版):
XXX:
您好,我叫Neil Morris,是亚当斯奖(Adams Prize)组委会的一名成员。
每年我们都会更新独立专家团队成员,这些专家需要评审参选项目(http://people.ds.cam.ac.uk/nm603/awards/Adams_Prize)的质量。
我的同事推荐您加入这一领域的专家团队中。
我们需要您参评竞争亚当斯奖的几个项目。
期待您的回复。
祝好,
Neil Morris
这里提一下,即便攻击者拥有浏览器0day利用技术,他们仍需要找到方法将攻击payload投递给目标用户。
选定目标后,攻击者通常会选择电子邮件作为投递方式,邮件中包含指向恶意网站的链接(当用户访问该网站时可以投递漏洞利用payload)。
不幸的是,当时该链接(people.ds.cam.ac.uk/nm603/awards/Adams_Prize
)已失效,返回404 Not Found
错误:
$ curl http://people.ds.cam.ac.uk/nm603/awards/Adams_Prize
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /nm603/awards/Adams_Prize was not found on this server.</p>
<hr>
<address>Apache/2.4.7 (Ubuntu) Server at people.ds.cam.ac.uk Port 80</address>
</body></html>
当然有可能该站点只为该攻击活动提供服务,只有当用户通过存在漏洞的Firefox浏览器、或者通过特定IP地址等来访问时,才会触发攻击过程。也有可能攻击过程已经结束,攻击者关闭了该站点。
虽然我无法获得利用代码,但用户依然向我提供了攻击过程中安装在他系统中的恶意软件(名为Finder.app
)。
本文将对这款恶意软件进行详细分析(哈希:23017a55b3d25a2597b7148214fd8fb2372591a5
)。
$ shasum -a 1 ~/Attack/Finder.app/Contents/MacOS/Finder
23017a55b3d25a2597b7148214fd8fb2372591a5 Finder
有趣的是,来自Coinbase的一名安全研究者(Philip Martin)在今天发表了一则比较有趣的推文:
Phil提供的哈希值(23017a55b3d25a2597b7148214fd8fb2372591a5
)刚好与用户发给我的恶意文件相匹配。此外用户还提到一个信息,最近他“参与了加密货币交易事宜”。综合这些信息,很有可能我和Phil讨论的都是同一个Firefox 0day。
这个0day现在对应的编号为CVE-2019-11707,已经被修复,其他文章中也提到了这个漏洞:
- “Mozilla patches Firefox zero-day abused in the wild”
- “Mozilla Patches Firefox Critical Flaw Under Active Attack“
然而,关于攻击中使用的后门恶意软件资料较少(或者没有),因此我们可以深入分析一下。
0x02 Mac后门分析(OSX.NetWire.A)
前面提到过,受害者向我提供了攻击者(通过Firefox 0day)安装在系统上的恶意后门(Finder.app
)。
在VirusTotal上搜索对应的哈希后(23017A55B3D25A2597B7148214FD8FB2372591A5
),我找到了一个匹配结果,显示这个文件已于2019-06-06提交,但目前只有一个反病毒引擎能够检测到:
备注:完整的应用程序包
Finder.app
今天才被提交到VirusTotal上,同样只有一个AV引擎能够检测。
有趣的是,这个反病毒引擎将其标记为OSX.Netwire
。
OSX.Netwire
(或者OSX.Wirenet
)最早于2012年被Dr Web发现。在这篇研究文章中,Dr Web表示这是“历史上第一款能够窃取Linux及MacOS X密码的后门”。
恶意软件通过键盘记录器以及/或者直接通过磁盘上的文件(比如已保存的浏览器登录信息)来窃取密码:
$ strings malware/2012/OSX.Netwire
%s/Library/Opera/wand.dat
%s/.Library/Opera/wand.dat
SeaMonkey
Thunderbird
%s/Library/Application Support/Firefox
%s/signons.sqlite
NSS_Init
PK11_GetInternalKeySlot
PK11_Authenticate
NSSBase64_DecodeBuffer
select * from moz_logins
但这是2012年时的OSX.Netwire
,现在这款恶意软件是否还是OSX.Netwire
?我个人从2012年后再也没听到过关于OSX.Netwire
的任何信息,因此决定研究一下。
首先,我们可以通过简单的字符串匹配方法,确认2012年的样本与2019年的样本有所关联。
比如,2012年样本中包含\x03\x04\x15\x1A\r\nexit\r\n\r\nexit\n\n
字符串:
esi = "/bin/sh";
if(access(esi) != 0x0) {
esi = "/bin/bash";
}
...
eax = write$UNIX2003(*0x140d0, "x03x04x15x1Arnexitrnrnexitnn", 0x15);
同样,2019年样本中也包含该特征:
if(stat("/bin/sh", edi) != 0x0) {
ebp = "/bin/bash";
}
...
write$UNIX2003(ebx, "x03x04x15x1Arnexitrnrnexitnn", 0x15)
此外还有一些特殊的字符串也能在两个样本中找到。
在与小伙伴(安全研究员)交流时,他注意到XProtect已经能够检测到这个新样本。
XProtect是Apple在macOS中内置的反恶意软件系统,大家可以参考此处了解更多信息。
我对此有所怀疑(因为我记得XProtect最近并没有关于OSX.Netwire
的任何更新),然而事实证明小伙伴是正确的。
2016年,Apple添加了一个Yara特征,用来检测OSX.Netwire.A
。这个特征(参考/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.yara
)如下所示:
rule NetwireA
{
meta:
description = "OSX.Netwire.A"
strings:
$a = "exitexit"
$b = "User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like GeckoAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
condition:
all of them
}
我们可以使用Digita的UXProtect工具以图形界面显示该特征:
还可以利用UXProtect确认(2016年推出的)这个特征依然可以检测此次Firefox 0day攻击中使用的恶意软件:
Apple之前提供的特征竟然还能检测这个“新的”威胁!
有趣的是Apple的特征并不能检测2012年的样本(因为该样本不包含User-Agent: Mozilla...
)字符串,这表明虽然这两个样本有所关联,但也存在不同之处。
目前我还找不到有关于这个新样本的(公开)资料。
有趣的是,Intego在2016年曾发表过关于Apple XProtect的一篇小文章:Apple Updates XProtect Malware Definitions for NetWeirdRC。
然而,他们(以及其他人)引用的都是2012年的样本,而该样本并不能被Apple的
OSX.Netwire.A
YARA特征检测到。通常情况下,这表明Apple已经知道一些信息,但不愿与大家分享,或者也有可能不愿意与我分享:
虽然2012年和2019年的样本明显有关联,但也有很多不同点。我们会在Part 2中透露更多细节,深入分析(新版)恶意软件样本的功能。简而言之,2012年及2019年样本的目标完全不同。我猜测这两款恶意软件都由同一个开发者(或者团队)编写,但服务于不同的目的(比如2012年的样本只关心密码窃取)。
在总结Part 1之前,我们来看一下新版OSX.NetWire.A
如何实现本地驻留。
快速查看恶意软件的反汇编代码后,我们可以找到其中内置的一个启动代理plist:
memcpy(esi, "<?xml version="1.0" encoding="UTF-8"?>n<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//ENnt"http://www.apple.com/DTDs/PropertyList-1.0.dtd">n<plist version="1.0">n<dict>n <key>Label</key>n <string>%s</string>n <key>ProgramArguments</key>n<array>n <string>%s</string>n </array>n <key>RunAtLoad</key>n <true/>n <key>KeepAlive</key>n <%s/>n</dict>n</plist>");
...
eax = getenv("HOME");
eax = __snprintf_chk(&var_6014, 0x400, 0x0, 0x400, "%s/Library/LaunchAgents/", eax);
...
eax = __snprintf_chk(edi, 0x400, 0x0, 0x400, "%s%s.plist", &var_6014, 0xe5d6);
因此有理由推测该恶意软件会以启动代理方式实现驻留。
然而,恶意软件中还包含以登录项实现驻留的代码逻辑(注意其中调用了LSSharedFileListInsertItemURL
API):
eax = __snprintf_chk(&var_6014, 0x400, 0x0, 0x400, "%s%s.app", &var_748C, &var_788C);
eax = CFURLCreateFromFileSystemRepresentation(0x0, &var_6014, eax, 0x1);
...
eax = LSSharedFileListCreate(0x0, **_kLSSharedFileListSessionLoginItems, 0x0);
...
eax = LSSharedFileListInsertItemURL(eax, **_kLSSharedFileListItemLast, 0x0, 0x0, edi, 0x0, 0x0);
在虚拟机中运行恶意软件后,我们发现恶意软件同时采用了这两种方法。首先是作为启动代理(com.mac.host.plist
),然后是作为登录项:
$ cat ~/Library/LaunchAgents/com.mac.host.plist
{
KeepAlive = 0;
Label = "com.mac.host";
ProgramArguments = (
"/Users/user/.defaults/Finder.app/Contents/MacOS/Finder"
);
RunAtLoad = 1;
}
由于这个启动代理(com.mac.host.plist
)设置了RunAtLoad
键(值为1
),因此每次用户登录时,系统会自动运行指定的程序(.defaults/Finder.app/Contents/MacOS/Finder
)。
登录项也可以确保恶意软件能被运行。然而登录项会显示在UI界面中,这显然不利于恶意软件实现隐蔽驻留:
采用两种驻留机制是不是比一种机制更好?不一定,如果大家使用了Objective-See提供的BlockBlock工具,就能轻松检测到这两种驻留机制:
关于以登录项(以及
backgroundTaskManagementAgent
角色)实现驻留,大家可以参考我最近的一篇文章了解更多细节。
我们也可以使用KnockKnock,通过探测恶意软件的驻留方式来检测系统是否已被感染。
可能恶意软件开发者需要确保自己能万无一失实现驻留,才采用这种攻击方式。
0x03 总结
在本文中,我们讨论了针对加密货币交易的一种较为复杂的持久化payload。攻击者利用Firefox 0day将恶意软件部署到目标macOS中。
有趣的是,这个恶意软件为OSX.NetWire.A
,与2012年同名的样本有一定联系,并且Apple于2016年部署的检测特征能成功发现这款恶意软件,但其实事情没那么简单。
在受害者的原始邮件中,曾提到这款恶意软件可以绕过Gatekeeper。这一点其实很正常,因为恶意软件采用的是远程0day漏洞进行投递。Gatekeeper只会扫描带有隔离属性集的应用程序,而只有当应用程序通过常见方式进行下载时(比如通过用户点击),浏览器等应用或者操作系统才会在下载的程序中添加这些属性集。通过漏洞利用代码下载的payload(比如恶意应用)并不会设置隔离属性(或者可以移除这些属性),因此就不会触发Gatekeeper。
我曾经在2016年的一次演讲中提到过这一点。
同样,XProtect只会对设置了隔离属性的文件进行操作。然而,macOS 10.15(Catalina)可能会修改这种机制。
由于攻击者采用的特殊感染方式(通过Firefox 0day),Gatekeeper以及XProtect都无法保护用户。因此,单纯依赖系统提供的安全保护机制永远都不是明智之举。