Android逆向工程为初学者 - Dexcalibur

2021-03-20 16:16:13

在这篇文章中,我向你介绍了一个很好的工具,使动态分析能够对初学者进行动态分析。这篇文章是特殊的,因为它被Dexcalibur&#39所写的证明阅读。谢谢@Frenchyeti甚至需要读这次虽然我知道你有一百万其他事情要做,包括一个新的和改进的工具版本;)

本文是我使用KBG Messenger Android CTF的第三个系列,以展示Android逆向工程的基础知识。 KGB Messenger CTF包含3个应按顺序解决的3个挑战:

在本系列中,我使用第一个挑战警报向您介绍多个Android逆向工程工具。在第一篇文章中我演示了如何通过用Jadx,APKLAB和APKOOL修补APK和修补SMALI代码来解决挑战。邮政,我们使用Frida使用动态分析解决了挑战。

Dexcalibur是在Windows,MacOS和GNU / Linux上工作的NodeJS工具,它使用Frida允许您将代码片段注入Android应用程序。

Dexcalibur让您轻松创建挂钩,但更多的是帮助您使用拆除代码:

它检测到动态加载的代码,并将其添加到工作区中供您检查。

Dexcalibur建于NodeJS。要确保您拥有正确的版本,您应该安装NVM,一个节点版本管理器。

如果您使用像我这样的ZSH,您可以将NVM安装为ZSH插件。基本上你用git clone https://github.com/lukechilds/zsh-nvm〜/ .oh-my-zsh / custom / plusins / zsh-nvm克隆回购,并在你的.zshrc.you中添加插件zsh-nvm.you然后可以源您的.zshrc,它将执行安装。您还可以添加用于自动完成的插件NVM。

官方德里克西尔博尔和#39; S文档表示NodeJS 12是用于工作程序所必需的。

如果您安装了多个节点版本,则可以使用NVM列表列出它们,然后选择版本12作为使用NVM使用V12的默认版本。

Frida是Dexcalibur的工具正在使用它来创建钩子。通常,渗透测试仪直接使用Frida进行逆向工程,这一过程可能是乏味的。 Dexcalibur为我们提供了一种简单的方法,可以在没有设置Frida脚本的情况下倒换Android应用程序!查看我以前的文章以开始Frida。

如果您在安装结束时找不到Python等错误,则可能需要安装一个工具,使Python指向Python3:sudo apt安装python-is-python3。

启动配置过程。 Dexcalibur附带Sane默认值,但您可能希望更改工作空间保存的位置。

我们所有的工具都已安装,是时候设置我们的手机和测试应用程序的实验室。

您应该参考上一篇文章学习如何在测试电话上安装和使用adb.my Setup由Ubuntu 18.04机器和三星Galaxy S7(SM-G930F)组成,带有植根线果索4.1-20180712-noverly-herolte。如果您可以使用' T有一个Android手机来执行测试,您也可以使用模拟器。

确保在手机上安装了KGB Messenger应用程序。您可以使用:

您还需要在手机上运行Frida-Server.You必须确保FIDA-Server的主要版本与Dexcalibur使用的Frida-node的主要版本匹配。如果您有一个bash shell,您可以获得使用的版本Dexcalibur使用此命令:

在这里,Dexcalibur使用FIDA-Node的版本14.2.13,因此在Frida发行页面上,我下载了最新的Frida-Server,其中一个版本从14开始,它也发生在这种情况下为14.2.13。

有一个正确版本的Frida-Server,解压缩存档并将服务器重命名为" Frida-Server"

接下来,您必须启动服务器。最后一步必须按root完成:

最后运行adb devices -l以确保adb守护程序正在运行。您现在有一个带有adb的手机,目标应用程序和frida-server .we'准​​备好换乘折磨!

本文的目的是开始使用该工具,所以我使用了一个非常简单的应用程序来做演示。您可以在上一篇文章中找到详细的静态分析,但随着我们打开应用程序时,可以快速提醒。 ,我们被打招呼了一条错误消息,说明:

公共空白oncreate(捆绑){超级。 oncreate(捆绑); setContentView((int).layout .act.actity_main);属性=。 getProperty(" user.home"); str =。 GetEnv("用户"); if(property == null ||属性。isempty()||!属性。等于("俄罗斯")){a("完整性错误","这个应用程序可以只在俄罗斯设备上运行。"); }否则如果(str == null || str。isempty()||!str。等于(getresources()。getstring(.string .user))){a("完整性错误",&# 34;必须在用户白名单上。"); }别的{a。在他的 ) ;开始活动(新(班级)); }}

首先通过在dexcalibur.visit http:// localhost:8000中注册我们的设备并进入Device Manager选项卡。如果不尝试断开并重新连接手机,请单击“刷新”并重新连接手机,然后单击“刷新”,然后进入“设备管理器”选项卡。

接下来,切换到“选择”应用程序“选项卡,然后在”下拉菜单中“选择手机。

Dexcalibur将开始分析您的包裹。完成此过程后,您应该在概述页面上降落。此页面只会为您提供应用程序在应用程序中使用的基本概述。

让'继续前进到钩子>仪表板View.on此视图您拥有应用程序已创建的每个钩子的列表。

例如,Dexcalibur已经创建了java.security.keystore.getInstance()的钩子。每次调用此方法时,我们都会有一个日志向我们展示此功能的参数和返回值。

让' s尝试使用这些默认挂钩运行应用程序,以查看会发生什么。在仪表板中,单击“➤”运行(SPAWN)“。

应用程序应在手机上启动,Dexcalibur自动将视图更改为挂钩>日志。您将看到在执行期间调用的所有挂钩方法:

以下是日志的摘录,在那里我们可以看到使用参数调用构造函数文件():

由于我们已经完成了对应用程序的静态分析,我们知道其中一个检查将使用System.getProperty查找属性User.Home以验证结果是"俄罗斯" .let' s挂钩此功能以绕过第一个检查。

我们首先进入静态分析>搜索引擎View.dexcalibur提供带有滤波器的搜索实用程序。您赢了'目前查找有关如何使用Dexcalibur搜索的文档,但该界面提供了实用程序以帮助您以行为搜索向导的小药丸的形式搜索方法和课程。

在这里我们想钩钩一个名为getProperty的方法,所以点击软橙色药丸按名称找到:

这将打开一个弹出窗口,您可以在其中填写您正在寻找的函数的名称。您可以在此输入的正则表达式,如GetProp。*例如,如果现在让'填写GetProperty。

因为我已经运行了Dexcalibur分析,这给了我31个结果.Notice如何在搜索框中自动填充您可以在搜索框中手动使用的过滤器语法。

我' LL向您稍后向您展示一些诀窍来加快搜索。现在让' s做一个很好的旧CTRL + F并搜索系统:

现在是魔术,如果我们想钩这些功能,我们所要做的就是点击蓝色按钮探测器。我们已经完成了,按钮与文本探测器切换到绿色。

如果我们返回View Hook>日志和使用🗘重新生成按钮,应用程序将重新启动,我们将看到通过我们新钩子传递的数据。

在这种情况下,函数java.lang.system.getProperty()被称为Argument User.Home(按预期)并返回一个空字符串。

我们设法挂钩system.getProperty以显示其参数及其返回值。如果我们想要修改返回值,那么它总是返回"俄罗斯"

要这样做,让'返回View Hook≫仪表板。您将看到我们的新钩子在底部列为自定义。在第一列中,您可以找到一个绿色+按钮,您可以单击。这将打开一个编辑,我们可以自定义我们的钩子。

Dexcalibur建于FIDA的顶部,这是一个允许我们将QuickJS代码注入进程的工具。您可以使用完全访问内存,挂钩功能甚至调用此过程中的本机函数来执行。还有一个双向通信通道,用于在您的应用程序和目标过程中运行的应用程序之间进行通信。

您看到的编辑器允许您修改此JS代码。如果您' d想了解更多关于Frida的更多信息,请查看我以前的文章。

然后点击"保存更改" (没有刷新图标的按钮).Now返回钩子>日志视图并单击“🗘respawn”。具有新错误消息的应用程序加载:

如前所述,Frida提供了一个用于在您的应用程序和目标过程内部运行的AP的双向通信通道。 dexcalibur使用此频道将日志数据发送到函数发送:

发送({id:" ytywotrkngu4m2viyjlmmzrjzjg5nmq3ythlodq1njg",msg:" java.lang.system.getproperty(< java.lang.string>)>",数据:{arg0:arg0,},action:"在之前和#34之前;,之后:false}); var ret = meth_f7b4eb07417e35b66dd2fc9687dd2fd3。致电(这,arg0);发送({id:" ytywotrkngu4m2viyjlmmzrjzjg5nmq3ythlodq1njg",msg:" java.lang.system.getproperty(< java.lang.string>)>",数据:{RET:RET},动作:"没有之前则没有*,之后:真实});

如果要发送返回其他数据,则Dexcalibur的创建者建议重用现有的发送功能并使用其他信息更新数据属性。

我没有考虑到相关的示例,所以我刚刚决定列出类资源的所有方法,并在日志中显示它们。这是GetProperty的修改挂钩,我添加了评论界定的评论,以便更容易阅读:

var cls_68cfa6743909fdea9bcb71194c415681 =。使用(' java.lang.system'); var meth_f7b4eb07417e35b66dd2fc9687dd2fd3 = cls_68cfa6743909fdea9bcb71194c415681。 getProperty。过载(' java.lang.string'); meth_f7b4eb07417e35b66dd2fc9687dd2fd3。实现=函数(arg0){// -------------------------------------- ---------- //我们将类资源的所有方法检索为字符串阵列const =。使用(" android.content.res.resources"); const方法=。班级 。 getmethods()。映射(函数(m){return m。toString();}); // ----------------结束额外的代码------------------------------- -----发送({id:" ytywotrkngu4m2viyjlmmzrjzjg5nmq3ythlodq1njg =",msg:" java.lang.system.getproperty(< java.lang.string>)< java.lang。字符串>" ------------------------------------- -------- //我们在这里添加对象"方法"数据:{arg0:arg0,方法:方法},// --------------- ----结束额外的代码--------------------------- - 行动:"没有之前和#34;,之后:false}); var ret = meth_f7b4eb07417e35b66dd2fc9687dd2fd3。致电(这,arg0);发送({id:" ytywotrkngu4m2viyjlmmzrjzjg5nmq3ythlodq1njg =",msg:" java.lang.system.getproperty(< java.lang.string>)>&#34 ;,数据:{RET:RET},动作:"没有之前则没有*,之后:真实});返回"俄罗斯" ; }

早些时候,当我们想要勾取System.getProperty,我们在视图中使用了搜索功能静态分析>搜索引擎。在本节中,我将列出一些额外的提示来搜索函数。

在我们的情况下,我们确切地了解函数的签名:java.lang.System.getProperty.we可以通过剪辑搜索筛选方法(" __签名__:< signature_hey_here_regex>)。

最初,我们搜索了与方法("名称:getProperty")的所有方法都搜索了名为getProperty的所有方法。我们可以添加另一个过滤器来选择其括号类的命名为系统的方法:

我们可以使用相同的逻辑,然后选择名为" getProperty&#34的所有方法;谁的封闭类是在包中的围类:

KGB-Messenger应用程序易于分解和反向,因此,使用Dexcalibur来解决这种挑战显然是一个矫枉过正。本文的目的是向您介绍动态分析的工具和概念。尽管我们主要依赖于解决挑战的静态分析,但您现在应该有基础使用Dexcalibur并对混淆应用程序进行动态分析。