Incinerator——Android 恶意软件逆向分析终极利器
导语:想要轻松掌握 Android 恶意软件的逆转技术吗?Incinerator 将是你在这场网络攻防战中的得力伙伴
想要轻松掌握 Android 恶意软件的逆转技术吗?Incinerator 将是你在这场网络攻防战中的得力伙伴,无论是资深专家还是初出茅庐的新手,都能在这款工具中找到自己的舞台。
大家好!在这篇文章里,我们将探索 Incinerator 的强大功能、丰富特性以及它所带来的种种优势。这款 Android 逆向工程工具集的灵感来自于广受好评的 Shambles 项目。
我们的目标非常明确:打造一款能够轻松应对 Android 应用,尤其是恶意软件的高级逆向工具。我们需要的是一个集反编译、解密、动态调试和漏洞检测于一体的全能工具。而且,这款工具还得能够快速、准确地揪出那些常见和隐蔽的威胁迹象(IOCs)。
正是基于这些目标,我们推出了 Incinerator!简单来说,它是一个功能全面、操作简便的逆向工程生态系统。不论你是经验丰富的逆向工程专家,还是刚踏入恶意软件分析领域的新手,Incinerator 都能满足你的需求。
Incinerator 应用内置了多种强大功能,让你可以轻松反编译 Android 应用,自动解密内容,取消反射 API 调用,获取清晰的反混淆代码,并在真实设备上进行实时调试分析。这对于那些想要深入了解、分析和逆转 Android 恶意软件的人来说,是一个完美的选择,即使你没有太多经验也没关系。
Incinerator 在后台进行的分析工作包括组件分析、安全漏洞检测、静态和动态代码分析、漏洞挖掘以及恶意代码分析。通过全面的检查,Incinerator 能够有效地帮助用户识别和解决安全风险和漏洞。
在更高层次上,Incinerator 将解密任务放在云端处理,其内部的漏洞分析引擎沙箱会实时更新漏洞库,能够精确到代码的具体行来定位恶意代码或漏洞。
多年前,Incinerator 与 JEB 或 GDA 进行了性能对比测试,并展现出了卓越的性能。如果你想看完整的对比报告,可以点击这里查看。
此外,我们还对比了多个威胁情报中心和在线沙箱的恶意代码检测与分析能力,以此来衡量 Incinerator 的性能。结果同样令人满意,相关报告也可供大家参考。
现在,让我们来认识一下 Incinerator 背后的团队。这款工具由 Lian Security 的一支约 12 人的工程师团队开发,历时约两年。他们也是 SHAMBLES、INCINERATOR 和 FLEGIAS 等产品的开发者,这些产品覆盖了从软件、基础设施、硬件到基本操作和维护、产品 UI 设计等多个领域。
Incinerator 可以在 Windows
、MacOS
和 Linux
系统上运行。它支持分析 APK 和 DEX 文件。APK 文件包含了编译后的代码文件(.dex 文件)、资源文件、证书和清单文件。DEX 文件是 Android 系统的可执行文件,包含了应用程序的所有操作指令和运行时数据。
分析文件的途径有两种,一种是通过 Incinerator 的桌面应用程序界面,如下图所示。
另一种是通过云端的网络门户进行。
选择哪一种方式,全凭个人喜好。我个人习惯于通过桌面应用程序上传和打开 APK。上传后,你可以登录到云端门户,在 https://incinerator.cloud/#/main/task/list 查看上传的样本。
从网络门户,你可以查看和处理生成的基于网络的报告。这些报告可以分享给其他人进行 APK 分析。这种访问权限需要在你的 UCENTER 账户中进行配置,默认情况下是不公开的。
如果你想要深入了解报告,或者跟随我们的分析步骤,请点击这里,你将看到如下的报告内容。
Incinerator 使用的 ML 模型具有非常高的准确性。Incinerator 的一些功能实际上是开源的,可以在 Lian Security 的 Github 上找到。特别是用于处理和生成报告数据的两个模型已经公开。
android-malware-detection
apk-obfucation-detection
在 Base Info
和 Behavior Info
面板以及 Static Analysis
、Dynamic Analysis
和 APK Risk
侧边面板中,包含了大量的信息。我们的目标是提供一个材料清单(BOM),它从包管理器、二进制文件、源代码和容器图片中派生。
让我们看看我个人特别喜欢的一些功能。你可以下载 APK 的网络流量,并将其导入到 Wireshark 中进行分析。
例如,应用程序权限(Application Permissions
)等许多面板,都是基于 androidmanifest.xml
文件的分析结果得出的,还有更多信息等待你去发掘。
快速浏览一下报告中的软件组成分析(SCA)部分,你会发现这些信息大部分都是非常有价值的。
我邀请你自己去探索这份报告。我不会再次回到这个网络门户,因为在网络上看到的所有内容都已经融入到了主应用程序中。
一旦样本被云端引擎完全分析,我们就可以开始在 Incinerator 应用程序中对其进行分析。当你第一次加载样本时,APK 报告会加载出来,它和网络门户报告中的内容非常相似。
如前所述,Incinerator 是一个沙箱工具,用于记录应用程序的整个执行过程,以调用栈的形式展示。当用户在本地打开相应的样本时,我们可以提供类似动态调试的体验。这使得用户能够理解样本在动态执行后是如何被触发的。
工具界面主要分为两个部分:Base Info
和 Behavior info
。每个部分提供的信息和主要差异如下,这些是你在使用时通常会看到的内容,但请注意,这里列出的并不是全部信息。
在右侧,我们有四个面板:Android Monitor
、Set Debug Device
、Static Analysis
和 Dynamic Analysis
,我们将在后面的内容中详细探讨这些面板。
这是 Incinerator 用户界面的基本布局。
让我们开始逆转一些恶意软件吧!以 FakeCalls 为例。逆转恶意软件的主要目标之一是识别攻击者用来窃取和外泄数据的 C2 和 C&C 通信渠道。Incinerator 在识别这些通信渠道方面表现得非常出色。
正如上图所示,我们知道这款恶意软件使用了死信箱解析器(T1102.001)。这是一种将恶意内容存储在合法网络服务上,然后通过调用将其安装到受害者设备上的技术。这些服务常常用来代理和掩盖与真实 C&C 服务器之间的通信,通过额外的域名和 IP 地址实现。
让我们通过 checkpoint 报告中检索到的 curl 信息,手动在 Incinerator 中逆转这种行为。Incinerator 引擎识别出了执行请求到 C2 服务器 daebak222.com/huhu/admin.txt 的代码,如下图所示。
如果我们对端点执行 curl 命令,将会得到以下输出。
$ curl https://www.daebak222.com/huhu/admin.txt
{
"a01": "eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fA==",
"b05": "Y2ViYWIrPj4gICI_IyAjPykpPyAlKSspIiMjPn14Z3Q=",
"a07": "eWVlYWIrPj4gKSM_ICc_JSM_ICkrJCEkJD55ZHlkPnB1fHh_P2VpZQ=="
}
我们的目标是理解恶意软件为何要获取这些信息,以及它的用途。结果发现,这些信息被用来更新它的 C2 通信渠道。这次检测的整个调用栈指向了 ServerInfoService.java
,它调用了 Service
和 Binder Android
类,这些类通常在你需要通过 HTTP 请求获取服务器信息的服务中使用。它还提供了其他组件访问这些信息的方法。
ServerInfo
类包含了有关服务器的信息。
a01 (eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fA==),
b05 (Y2ViYWIrPj4gICI_IyAjPykpPyAlKSspIiMjPn14Z3Q=),
a07 (eWVlYWIrPj4gKSM_ICc_JSM_ICkrJCEkJD55ZHlkPnB1fHh_P2VpZQ==)
它代表了我们期望从服务器获取的各种属性。
其中,serverInfo.a01
代表新服务器,serverInfo.b05
代表备用服务器,serverInfo.a07
代表从哪个服务器获取信息。fetch()
和 fetchFromAlternative()
方法用来启动 HTTP 请求,以获取服务器信息。
如果我们在 Incinerator 控制台中按下 tab
键进入 fetch()
方法,我们可以看到 Android 应用程序字节码的中间语言,也就是所谓的 "smali" 代码。在这里我们可以清楚地看到 eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fD55ZHlkPnB1fHh_P2VpZQ==
实际上是 daebak222.com/huhu/admin.txt
。就在下面,我们有 onData
方法,如果成功获取服务器信息,则记录成功消息。然后,它会检查 ServerInfo
对象的字段(a01
、b05
、a07
)是否有空。如果任何一个字段为空,它会记录一个警告消息,指示服务器信息无效。否则,它将调用 ServerInfoService
类的 updateServerInfo
方法,传递接收到的 ServerInfo
对象,以更新服务器信息。
太棒了!有了 Incinerator,这一切都变得非常简单。接下来,让我们看看 Incinerator 的检测能力。Incinerator 识别出恶意软件能够捕获设备接收的 SMS 消息,发送短信,并根据 C2 服务器的指令拨打电话。
让我们验证一下这款恶意软件是否真的具备在受感染设备上捕获电话通话、短信等信息的能力。首先,我们需要确认恶意软件是否已经获取或为自己分配了获取这些信息的权限。从下面的图中可以看出,它确实拥有大量权限。
那么,恶意软件是如何获得这些权限的呢?我们可以双击调用栈中的任何参数,打开相应的代码进行查看。特别值得注意的是 Add New Device Administrator
的事件。
恶意软件会检查设备管理员是否活跃,如果不是,它会通过发送一个 Intent 来请求设备管理员权限,这个 Intent 的动作是 android.app.action.ADD_DEVICE_ADMIN
。只要用户不答应,它就会不断地通过循环窗口请求权限。
一旦用户授予了权限,根据我的经验,唯一手动停用它的方法是在 Settings -> Security -> Device Management
中操作,但到那时可能已经太晚了。
下面列出的是应用程序请求或已经获取的权限,但这个列表并不全面:
permissionNames.add("READ CONTACTS");
permissionNames.add("WRITE CONTACTS");
permissionNames.add("READ SMS");
permissionNames.add("RECEIVE SMS");
permissionNames.add("SEND SMS");
permissionNames.add("RECORD AUDIO");
permissionNames.add("READ PHONE STATE");
permissionNames.add("WRITE EXTERNAL STORAGE");
permissionNames.add("READ EXTERNAL STORAGE");
permissionNames.add("CHANGE WIFI STATE");
permissionNames.add("INTERNET");
permissionNames.add("ACCESS WIFI STATE");
permissionNames.add("GET ACCOUNTS");
permissionNames.add("READ LOGS");
permissionNames.add("PROCESS OUTGOING CALLS");
permissionNames.add("CALL PHONE");
permissionNames.add("RECEIVE BOOT COMPLETED");
permissionNames.add("DISABLE KEYGUARD");
permissionNames.add("INSTALL SHORTCUT");
permissionNames.add("UNINSTALL SHORTCUT");
permissionNames.add("WAKE LOCK");
permissionNames.add("CHANGE WIFI STATE");
permissionNames.add("INTERNET");
permissionNames.add("ACCESS WIFI STATE");
permissionNames.add("GET ACCOUNTS");
permissionNames.add("READ LOGS");
permissionNames.add("PROCESS OUTGOING CALLS");
permissionNames.add("CALL PHONE");
permissionNames.add("RECEIVE BOOT COMPLETED");
permissionNames.add("DISABLE KEYGUARD");
permissionNames.add("INSTALL SHORTCUT");
permissionNames.add("UNINSTALL SHORTCUT");
permissionNames.add("WAKE LOCK");
我们知道恶意软件已经具备了执行恶意行为所需的所有权限。回到检测调用栈,我们可以发现多处代码检测到设备麦克风作为音频源,并将录音存储在磁盘上的预定位置。因此,这款恶意软件确实能够记录电话通话。
恶意软件还会通过查询 content://sms/
来获取设备上的短信信息,包括 Sender ID and Address
、 Body/Content
、 Read status
Data received
和 Type
,并将这些信息压缩后发送回 C2 服务器。
它还能拦截设备上的传入短信,发送新的短信,以及根据 C2 服务器的指令拨打电话。
通常情况下,它会获取设备信息,压缩后发送出去。
这款恶意软件还会尝试获取 Facebook 凭据,奇怪的是,它是唯一试图获取的凭据类型。
还有一个复杂的包管理器类,它会检索受害者手机上所有安装的应用程序信息,如 VersionCode
、 VersionName
、 PackageName
和 AppName
。这些信息很可能用于覆盖攻击,即恶意软件在合法应用程序上方打开一个透明窗口,以此窃取用户的凭证数据,如支付信息或登录凭据。
如下图所示,这种攻击极有可能已经发生。恶意窗口与合法应用程序看起来一模一样。在这种攻击中,恶意软件可以轻易窃取用户的敏感数据。
恶意软件还会在启动时获取设备的地理位置信息,使用如 api.ipify.org
等服务。这样它就能获取公共的 IPv4 和 IPv6 地址、MAC 地址和 Wi-Fi SSID。
它还会执行操作系统命令,主要用于从 /proc/cpuinfo
获取额外的系统信息。
老实说,还有更多功能等待发掘,但我已经尽力概述了 Incinerator 的基础功能。这篇文章的目的并不是要逆转恶意软件,而是要展示 Incinerator 的强大功能,并提供一个概览和实例演示。接下来,让我们看看调试器的功能。
我们可以使用调试器的两种方式,一种是通过将实体 Android 手机连接到电脑,另一种是使用虚拟机。选择哪种方式完全取决于个人喜好。但我猜,可能没有多少人愿意将已经 root 的手机专门用于安装可疑的恶意软件。
在开发者选项中,你只需要设置两个配置:USB Debugging = True
和 Default USB configurations = Transferring Files
。如果你在使用虚拟机,你可以简单地使用 scrcpy 来访问 Android 设备并启用它。
我还没试过这种方法,但我不认为有什么理由不行。你也可以通过以下 ADB 命令来配置这一切(我可能漏掉了一两个命令)。
adb shell settings put global development_settings_enabled 1
adb shell setprop persist.security.adbinput 1
adb shell settings put global adb_enabled 1
adb shell settings put global adb_usb_debugging 1
adb shell settings put global adb_usb_tethering 1
不管怎样,我不在乎你是怎么做的,但我相信你最终会找到解决办法。一旦你的手机连接到电脑或者通过 ADB 连接到虚拟机,你就可以在 Incinerator 的 Android Monitor
标签中看到以下挂载点。
我们所要做的就是双击它,APK 将被上传到手机,并附加到 Incinerator 调试器上。
你可以设置断点,逐步执行代码,修补数据...任何顶级调试器能做的事情,Incinerator 都能做。
再次强调,你可以使用像 Caindo 或 BurpSuite 这样的代理工具来运行所有这些操作。对于基于 Android 的 CTF 竞赛来说,这绝对是一个强大的工具。
这种情况很少见,但如果调试器失败了(尤其是当你尝试加载一些奇怪的 CTF 挑战时),你可能会看到下面的截图。
如果你尝试启动调试器几次,但它一直失败,这很可能是因为你现有的 ADB 环境或手机存在问题。下面是调试器失败时的截图。
接下来是手动调试的步骤。
步骤 1
启动你想要调试的应用程序组件。例如,我们想要调试 com.lian.logindemo
,因此我们将启用调试日志来启动它。
adb -s 10.40.43.88:5555 shell am start -D com.lian.logindemo/com.lian.logindemo.ui.login.LoginActivity
如果你在这里遇到错误,我很抱歉,但问题可能出在你的设备上。
步骤 2
我们想要获取设备上当前正在运行的进程列表。
adb -s 10.40.43.88:5555 shell "ps |grep com.lian.logindemo"
如果你没有任何输出,那意味着 APK 启动失败了。请注意,有些系统可能需要使用 ps
命令的 -A
选项来列出所有进程。
步骤 3
我们想要在特定的 APK 上启用远程调试。为此,我们将设置端口转发,以便让我们的主机机器上的 JDWP 调试器与设备上运行的 APK 之间进行通信。
adb -s 10.40.43.88:5555 forward tcp:12345 jdwp:
如果在运行这个命令时出现错误,那可能是因为进程没有运行,或者端口已经被占用了。
步骤 4
现在我们想要让 JDB 连接到运行在本地机器(127.0.0.1)上的 JVM,以便进行调试。
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=12345
如果你遇到任何错误...请按照以下子步骤操作:
步骤 4-1: 找出所有占用端口
5037
(adb-server)的进程,并将它们结束。例如,android studio 可能会使用 adb-server。要查看这些进程,可以运行netstat -ano | findstr 5037
。步骤 4-2: 使用
adb forward --list
检查端口转发状态。步骤 4-3: 检查 debugable PID 是否存在,运行
adb jdwp
命令。
步骤 5
在 JDB 终端中运行 classes
命令,如果它能列出所有类,那么你就已经准备好了,可以重新启动调试器!
如果你对 Incinerator 的使用感兴趣,Lian Security 团队还发布了他们对 BOOMSLANG 恶意软件的分析,你可以在这里阅读,还有 NEXUS 木马的分析,你也可以在这里查看。
如果你对 Lian Security 团队发布的 Android 研究感兴趣,我推荐你可以阅读以下文章:
AndroidManifest.xml 绕过静态分析的逃避技术:通过 Zip 格式操作
基于机器学习的 Android 恶意应用识别
AndroidManifest.xml 中多层次混淆技术的技术分析,旨在绕过静态分析
文本分类实现混淆检测
原文链接:Lian Security
发表评论