环球微资讯!扒一扒针对东亚的新型恶意软件FLUHORSE
导语:FluHorse针对东亚市场的不同领域,并通过电子邮件进行传播。
(资料图片)
Check Point的研究人员最近发现了一种名为FluHorse的新型恶意软件。该恶意软件具有几个模仿合法应用程序的恶意安卓应用程序,其中大多数安装量超过100万次。这些恶意应用程序窃取受害者的凭据和双因素身份验证(2FA)代码。FluHorse针对东亚市场的不同领域,并通过电子邮件进行传播。在某些情况下,第一阶段攻击中使用的电子邮件属于知名对象。恶意软件可以在数月内不被发现,这使其成为一种持久、危险且难以发现的威胁。
其中一个恶意软件样本在3个月后仍未在VirusTotal(VT)上检测到
攻击者使用规避技术、模糊处理和执行前的长时间延迟等技巧来躲过虚拟环境的检测。通常,这些技巧都有自定义实现,需要开发者付出大量的努力。
令人惊讶的是,FluHorse内部没有使用自定义实现的技巧,因为恶意软件的开发者在开发过程中完全依赖开源框架。尽管一些应用程序部分是用Kotlin创建的,但恶意功能是用Flutter实现的。Flutter是一个开源的用户界面软件开发工具包,由谷歌创建。它用于为各种平台开发跨平台应用程序,包括用于移动设备的Android和iOS,使用单个代码库。Flutter之所以成为恶意软件开发人员的一个有吸引力的选择,是因为它使用自定义虚拟机(VM)来支持不同的平台,而且它易于创建GUI元素。此外,由于自定义的虚拟机,分析此类应用程序非常复杂,这使得该框架成为Android网络钓鱼攻击的完美解决方案。
模拟应用程序
攻击者会为每个国家的目标开发一个虚假应用程序:攻击者努力仔细模仿所有关键细节,以避免引起任何怀疑。
网络钓鱼
让我们看一下如何在应用程序的不同变体中实现网络钓鱼,有趣的是,恶意应用程序不包含任何东西,除了为受害者提供输入可能性的几个窗口副本。没有添加额外的函数或检查。这种刻意的简单性让我们得出结论,恶意软件的开发者并没有在他们创建的编程部分投入太多精力,又或者他们可能故意做出这个决定,以进一步减少被安全解决方案检测到的机会。
不管他们的意图是什么,这个计划都很有效。受害者输入敏感数据后,这些数据会被泄露到C&C服务器。与此同时,恶意软件要求受害者在“处理数据”时等待几分钟。在这一步中,短信拦截功能发挥作用,将所有传入的短信流量重定向到恶意服务器。如果攻击者输入被盗凭证或信用卡数据,然后被要求输入双因素身份验证(2FA)代码,这也会被拦截。网络钓鱼方案如下:
恶意软件如何进行网络钓鱼攻击
请注意,根据恶意应用程序的类型(针对电子收费、银行或约会用户),可能不需要凭据或信用卡号。
感染链和目标
在受害者的设备上安装恶意应用程序之前,必须先发送恶意应用程序。这就是电子邮件诱饵派上用场的地方。我们追踪了不同类型恶意应用程序的感染链,并在这些电子邮件的收件人中发现了多个知名对象,包括政府部门和大型工业公司的员工。
电子邮件诱饵很好地利用了社会工程,并与随后安装的恶意APK的所谓目的一致:支付通行费。
这是一个带有fetc.net.tw-notice@twfetc.com发件人地址:
攻击者发送给政府接收者的电子邮件示例
攻击者使用的恶意fetc-net[.]com域与fetc公司的官方网站fetc.net.tw非常相似。
在这个恶意网站上,攻击者添加了一个额外的保护层,以确保只有受害者才能下载APK:如果目标的用户代理与预期的用户代理匹配,就会下载APK。此检查是通过客户端JavaScript执行的:
恶意软件安装完成后,需要短信权限:
ETC APK请求SMS权限
在此步骤中获得的权限将在受害者输入敏感数据后生效。
恶意电子收费APK
此应用程序仅包含3个窗口:
恶意ETC APK按顺序显示的窗口
第一个窗口询问用户凭证,第二个窗口询问信用卡数据。所有这些敏感数据都被泄露到恶意的C&C服务器。接下来,第三个窗口要求用户等待10分钟,因为“系统繁忙”。希望用户关闭应用程序,或者至少在合理的时间内不被怀疑。当用户被“系统繁忙”消息误导而产生虚假的安全感时,攻击者会执行所有必要的操作,即拦截所有带有2FA代码的短信,并利用被盗数据。
这个诱饵应用程序的整个GUI看起来像是原始ETC应用程序的一个简单副本,用于收取通行费。以下是恶意和合法应用程序入口窗口的可视化比较:
原始输入窗口(左)和恶意APK输入窗口(右)
原始应用程序不显示任何用于登录或输入用户凭据的字段。相反,有一个单独的窗口用于此目的:
原始应用程序登录表格
恶意VPBank APK
此应用程序仅包含2个窗口:
恶意VPBank APK按顺序显示的窗口
其原理与其他恶意APK相同:要求用户输入凭据,然后等待15分钟(而恶意ETC APK则为10分钟)。在此期间,恶意软件拦截所有传入的SMS,从而为攻击者提供他们可能需要的所有2FA代码。请注意,此应用程序不要求提供信用卡详细信息。
恶意和合法应用程序登录窗口之间的比较:
原始登录窗口(左)和恶意APK输入窗口(右)
如上所示,即使缺少某些GUI元素,恶意副本看起来也很好。
恶意约会APK
约会应用程序不包含任何窗口。相反,它实际上充当了一个浏览器,引导用户进入钓鱼约会网站。但是,窃取和处理数据的原理是一样的。
我们没有与受害者交互的所有步骤的屏幕截图,因为在撰写本文时,负责处理从该APK窃取的数据的恶意服务器尚未激活。根据代码,只有信用卡数据被盗,不需要凭证。
APK中显示的钓鱼交友网站窗口
所示消息的翻译如下:
网络钓鱼网站上显示的消息翻译。
技术细节
与分析纯Android应用程序相比,分析基于flutter的应用程序需要一些中间步骤才能达到目的。
深度分析
如上所述,Flutter使用自定义的虚拟环境来支持具有单一代码库的多平台开发。开发过程中使用了一种名为Dart的特定编程语言。分析Flutter平台代码变得更容易了,因为它是一个开源项目,但仍然是一个繁琐的过程。
Flutter Github页面中的Dart演示
让我们来看看在处理Flutter运行时的特殊领域时遇到的一些复杂情况。我们用哈希2811f0426f23a7a3b6a8d8b7e1bcd79e495026f4dcdc1c2fd218097c98de684解剖了一个APK。
ARM的Flutter运行时使用自己的堆栈指针寄存器(R15)而不是内置的堆栈指针(SP)。哪个寄存器用作堆栈指针在代码执行或反向工程过程中没有区别。然而,这对反编译器来说有很大的不同。由于寄存器的使用不规范,会生成错误且难看的伪代码。
启动恶意软件分析的一个好方法是确定与C&C服务器的通信协议。这可以说明很多恶意功能。里面有一个字符串,对应于我们在钓鱼电子邮件中看到的网站:
恶意APK中字符串中C&C服务器的地址
然而,当我们试图找到对此字符串的一些引用时,分析失败:
IDA中没有对C&C服务器字符串的引用
我们的目标是创建对该字符串的引用,以定位执行C&C通信的代码。
Flutter -re-demo和reFlutter可以用来处理Flutter应用程序,其主要思想是使用运行时快照来创建Dart对象并查找对它们的引用。reFlutter的主要目的是收集函数的名称,而flutter re-demo允许我们处理在应用程序执行期间收集的内存转储。
然而,除了内存快照之外,还需要一些更多的运行时信息。Flutter运行时使用堆来创建对象,并将指向已创建对象的指针存储在一个称为对象池的特殊区域中。指向该池的指针被传递到寄存器X27中的方法。我们需要找到对象池的位置。
flutter-re-demo使用Frida收集内存转储并获取对象池地址。如果我们使用在flutter-re-demo存储库中可用的dump_flutter_memory.js脚本运行APK,我们会看到所需的地址:
带有所需地址的Frida脚本输出
现在我们已经拥有了开始一个高效的逆向工程所需的所有元素。
在用map_dart_vm_memory.py加载转储文件并运行create_dart_objects.py脚本后,我们现在至少可以看到一些对象:
脚本创建的对象
有一个名为create_dart_objects.py的脚本,用于创建dart对象。该脚本通过遍历对象池、解析记录和创建对象来工作。脚本没有关于这些对象的信息,脚本会为它们创建以下描述对象格式的结构:
这里的NNN被“class id”取代,如下所示:
由create_dart_objects.py创建的结构
在Flutter应用程序逆向工程时,研究人员注意到最后一个字段(unk)经常被用作指针。可以考虑将该字段从简单的QWORD转换为OFFSET QWORD。这可能会给带来一些误报,但也可能非常有助于创建参考。因此,我们决定更改由脚本创建的unkin结构的字段类型。以下是对原始脚本的更改:
对dart_obj_create.py脚本的更改
研究人员提到的存储库包含一个用于创建对Dart对象引用的脚本:add_xref_to_art_objects.py。当运行它时,该脚本会遍历代码并创建对create_Dart_objects.py脚本创建的Dart对象的引用。不过此时仍然只有一个对我们感兴趣的字符串的引用,即来自对象池的引用:
没有对C&C服务器URL的引用
我们的第一个想法是,也许根本没有交叉引用?不过这不可能,存在几个交叉引用,例如,这个对象就具有引用:
几个从函数到对象的引用
这是从函数中引用的对象:
引用在函数代码中的外观
通过浏览add_xref_to_dart_objects.py的代码,我们可以看到文件dart_obj_xref.py。该文件还遍历代码,尝试根据寄存器X27提取对数据的引用,计算这些引用的偏移量,最后创建IDA引用。对代码的分析表明,原始脚本支持访问该对象的两种ARM代码变体:
代码是否使用了一些其他指令来引用寄存器X27?让我们检查一下。为了方便起见,让我们修改脚本,并为用X27处理的每条指令添加一条注释:
dart_obj_xref.py修改
然后,我们可以检查用X27处理的结构的反汇编程序列表,这些构造没有附加对Dart对象的注释引用。我们可以通过IDA生成一个列表文件并使用grep实用程序进行grep,从而部分自动化这些操作,如下所示:
首先,grep查找具有X27的所有字符串。然后,所有这些字符串都给了第二个grep命令,只打印那些不包含对Dart对象引用的字符串。因此,我们只看到不受支持的X27引用。
当检测到不受支持的X27构造时,我们将在脚本中添加支持该构造的代码。经过几次迭代,我们终于获得了对C&C地址字符串的引用:
对C&C地址字符串的引用
让我们从sub_70FD611C0C开始检查这些函数。简要概述显示,当与C&C服务器通信时,此函数打算使用路径为“/addcontent3”的HTTP POST方法来执行:
sub_70FD611C0C函数的伪代码
另一个Dart对象也有对这个函数的引用:
对Dart对象的引用
当我们遍历这些引用时,我们最终得到了带有以下代码的函数:
负责监听所有传入短信的代码
此函数为所有传入的短信安装一个侦听器。
为了确保我们做了正确的静态分析,我们在运行时在一个真实的设备上检查了这个函数。实际上,我们捕获了一个发送到C&C服务器的POST请求。
这是设备收到带有“Fdsa”文本的短信后的C&C请求示例:
因此,使用sub_70FD611C0C函数将短信泄露到C&C服务器
除了被泄露的数据类型和服务器路径之外,函数sub_70FD61EBC4和sub_70FD61EECC看起来与已经分析的sub_70FD 611C0C非常相似。这些函数分别使用路径“/addcontent”和“/addcontent2”,用于泄露受害者的凭据和支付卡信息。
DEX代码中没有服务器通信的痕迹,因此我们可以假设所有通信都位于应用程序的Flutter部分。在分析了与命令控制服务器通信相关的所有功能之后,我们可以描述网络协议。
C&C通信
C&C协议旨在将数据从受攻击设备发送到服务器。没有命令可以在相反的方向上发送,即从服务器发送到受攻击设备。HTTPS用于传输数据,并且使用了几个终端。
以下是我们在分析样本中遇到的每个终端的介绍:
用于约会恶意应用程序的网络诱饵变体使用了非常相似的协议。这是一个泄露信用卡数据的示例:
唯一的区别是正文格式:Web版本使用JSON而不是“name=value”格式。
总结
这些恶意样本的技术实现由几个层组成,由于功能部分相对简单,我们可以得出结论,恶意软件开发人员没有在编程中投入太多精力,而是依赖Flutter作为开发平台。开发人员的主要关注点是GUI。这种方法使他们能够创建危险且不易被发现的恶意应用程序。使用Flutter的好处之一是其难以分析的特性使许多当代安全解决方案形同虚设。
翻译自:https://research.checkpoint.com/2023/eastern-asian-android-assault-fluhorse/