APP动态分析系列 – Frida的基础用法(上)

APP动态分析系列 - Frida的基础用法(上)


APP动态分析系列 - Frida的基础用法(上)

APP动态分析系列 - Frida的基础用法(上)

大狗涉网线索分析平台是无糖信息旗下一款针对“新型电信网络诈骗犯罪”专业化、智能化、跨境化等特征,提供涉诈网站识别及监控、预警数据分析、案件研判的一体化服务平台。为公安部门在预警防范、侦查破案提供多方位、深层次、多类型的情报信息及数据支持,助力公安机关形成反网络犯罪的打击能力。









当我们分析恶意APP样本时,难免会遇到单靠静态和逆向分析无法解决问题的情况。例如:

  • Hook一个方法:如,分析APP通信加密时,需要Hook加密函数来查看其具体实现方法和参数。

  • 调用静态方法:如,尝试越权访问API时,需要调用APP中某个用于验证用户权限的静态方法,来绕过权限验证。

  • 更改变量的值:如,分析用户身份、权限信息的过程中,需要查看并修改APP本地缓存用户身份信息等变量的数值,以模拟不同用户身份或权限级别。


诸如此类,都需要引入基于Frida的动态插桩技术。Frida 是一款强大的动态代码分析工具,可以用于在移动应用程序中进行代码注入、调试和反编译等操作。使用Frida需要安装前置的Python、Frida、安卓模拟器及其依赖环境(可参考官方文档:https://frida.re/docs/home/)。这些繁琐的过程,可能会对有意愿了解和使用该类技术的人员造成阻碍。【大狗涉网线索分析平台】的【云真机操作台】引入了 Frida 脚本功能,该功能不仅可以省去复杂的安装过程,还能够实现一键运行 Frida 脚本。这意味着,用户可以在无糖浏览器中随时随地对恶意 APP 进行动态调试,大大提高了工作效率和便利性。


为了使用Frida达到Hook函数/方法、调用静态方法、更改变量值等目的,我们需要掌握以下技术和方法:

  • Frida框架:了解Frida框架的基本原理和架构,包括Frida Server和Frida Client之间的通信机制。

  • Frida脚本:学习使用JavaScript编写Frida脚本,这些脚本可以用于在目标应用程序中执行各种操作,如函数钩子、数据修改、调试等。

  • 函数Hook(钩子):掌握如何在目标应用程序中通过Frida对特定函数进行Hook,以便监视、修改或替换函数的行为。

下面将对这些基础用法进行讲解和演示。





基础用法示例




本系列文章将以Frida-lab中的题目为例,首先分上、下两篇为大家介绍云真机操作台中Frida脚本的基础用法和背景知识,然后分篇为大家讲解Frida脚本的更多进阶用法。Frida-lab是Github上的一个开源项目,是专为学习Frida for Android而设计的一系列挑战,包含多个CTF风格的APP样本,旨在帮助初学者掌握Frida及其常用的API基础知识。


项目链接:https://github.com/DERE-ad2001/Frida-Labs


使用工具


  • Jadx反编译工具:jadx是一个功能强大、使用简单的Android反编译利器,适合开发者在逆向工程和代码分析时使用。(官方网站:https://github.com/skylot/jadx)


  • JavaScript脚本:我们将使用JavaScript API来完成Frida脚本的编写。(API文档地址:https://frida.re/docs/javascript-api/)(值得注意的是,Frida也支持Python。)


  • Frida框架:本次我们使用【大狗涉网线索分析平台】-【云真机操作台】中引入的Frida脚本功能。


前期知识储备


  • 了解Frida框架的基本原理和架构。

  • 了解Hook技术拦截和修改函数或方法的基础知识。

  • 掌握使用jadx进行逆向工程的基础知识。

  • 具备理解Java代码的能力。

  • 具备编写小型JavaScript代码片段的能力。



01




用法1:Hook一个方法


APP下载地址https://github.com/DERE-ad2001/Frida-Labs/tree/main/Frida%200×1


01
安装APP


打开【无糖浏览器】进入【大狗平台专区】-【云真机操作台】(图1),上传Challenge 0x1.apk文件,在云真机操作台中完成模拟安装(图2)。

APP动态分析系列 - Frida的基础用法(上)

图1. 进入云真机操作台


APP动态分析系列 - Frida的基础用法(上)

图2. 点击上传APK文件


02
了解APP样本


下载apk文件并上传至大狗-云真机操作平台后,可以看到该APP提示我们输入数字(图3),随意输入一个数字后看到会出现一个“Try again”提示(图4),猜测只有输入正确数字后,才会出现flag提示。那么我们将APK放入jadx开始静态分析。


APP动态分析系列 - Frida的基础用法(上)

图3. 应用程序Challenge 0x1界面


APP动态分析系列 - Frida的基础用法(上)

图4. 输入数字


03
静态分析


我们使用jadx反编译APP,获取程序源代码。首先,查看反编译源代码,找到程序入口(图5)。(关于如何查找APP入口,可以参考之前的文章《APP动态分析系列 – 实战:某木马APP行为过程分析》 ,后续不再赘述。)


APP动态分析系列 - Frida的基础用法(上)

图5. 程序入口


可以看到,APP中位于com.ad2001.frida0x1MainActivity类的onCreate方法在程序初始化时会调用get_random()方法生成一个介于0到100之间的随机数并赋值给变量i。同时,监听button的点击,当按下按钮后,程序首先判断输入的内容是不是数字,如果是数字就将其从string转化为int,并将该整数与生成的随机数一起传递给check方法。接下来,继续分析check方法实现了哪些功能。


1 public void onCreate(Bundle bundle) { 

2         super.onCreate(bundle); 

3         setContentView(R.layout.activity_main); 

4         final EditText editText = (EditText) findViewById(R.id.editTextTextPassword); 

5         this.t1 = (TextView) findViewById(R.id.textview1); 

6         final int i = get_random(); 

7         ((Button) findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() { // from class: com.ad2001.frida0x1.MainActivity.1 

8             @Override // android.view.View.OnClickListener 

9             public void onClick(View view) { 

10                 String obj = editText.getText().toString(); 

11                 if (TextUtils.isDigitsOnly(obj)) { 12                     MainActivity.this.check(i, Integer.parseInt(obj)); 

13                 } else {             14  Toast.makeText(MainActivity.this.getApplicationContext(), "Enter a valid number !!", 1).show(); 

15                 } 

16             } 

17         });

18     }



1 int get_random() { 

2        return new Random().nextInt(100);          

3    }


check方法被传入了两个参数,一个是我们在APP页面输入后提交的的数字i2,一个是程序启动时调用get_random方法生成的随机数i。该方法会检查表达式(i * 2) + 4 == i2)是否成立,如果成立则将正确的flag输出到绑定的textView控件上,反之则会提示“Try again”。


1 void check(int i, int i2) { 

2        if ((i * 2) + 4 == i2) { 

3           Toast.makeText(getApplicationContext(), “Yey you guessed it right”, 1).show(); 

4            StringBuilder sb = new StringBuilder(); 

5            … 

6            this.t1.setText(sb.toString()); 

7            return

8        } 

9        Toast.makeText(getApplicationContext(), “Try again”, 1).show(); 

10    }



分析完APP源代码,我们可以知道,当该APP启动后,会首先生成一个随机数i,接着在check方法中对用户的输入和该随机值做判断。如果输入的数字i2等于 (i * 2) + 4 那么程序就会将flag输出到绑定的textView控件。想要获取这个flag完成挑战,我们需要知道程序生成的随机数 i 的值,或者将每次随机值生成的结果修改成我们已知的一个值(这个在后续更改变量值的用法中会讲到),Frida在这个时候就派上用场了。


04
编写Frida脚本


我们需要使用Frida框架,编写一个JavaScript脚本,在程序启动时Hook get_random方法,来获取随机数i的值。


编写这个脚本,我们可以在jadx中右键get_random方法,选择复制为Firda片段。复制下来的Firda片段展示了Hook这个方法的一般流程,从中我们可以提取出关键信息,Hook这个方法需要使用APP中com.ad2001.frida0x1包的MainActivity类。


1 let MainActivity = Java.use(“com.ad2001.frida0x1.MainActivity”); 

2 MainActivity[“get_random”].implementation = function () { 

3    console.log(`MainActivity.get_random is called`); 

4    let result = this[“get_random”](); 

5    console.log(`MainActivity.get_random result=${result}`); 

6    return result; 

7 };


然后,在这个基础上修改代码,实现Hook get_random方法,并获取其返回值——随机数i值的JavaScript脚本代码实现如下:


1 /** 

2 Java.perform是Frida中的一个函数,用于为脚本创建特殊上下文,进入此上下文后,可以执行挂钩方法或访问 Java 类等操作来控制或观察应用程序的行为。

3 **/ 

5 Java.perform(function() { 

6   

7 var a= Java.use(“com.ad2001.frida0x1.MainActivity”); 

8  //声明了一个变量a来表示目标 Android应用程序中的Java类,Java.use 函数指定要使用 com.ad2001.frida0x1包中的MainActivity类。 

10   a.get_random.implementation = function(){ 

11   //使用变量a在所选类的内部勾取get_random方法。 

12   

13   console.log(“MainActivity.get_random is called”); 

14   var ret_val = this.get_random(); 

15   //获取get_random方法运行的返回值,随机数i的值。 

16 

17   console.log(“MainActivity.get_random result is “ + ret_val); 

18   //将获取到的i值输出到控制台。 

19 

20   return ret_val; 

21 } 

22 })



下面是关于这段代码的解释:

Java.perform 是Frida中的一个函数,用于为脚本创建特殊上下文,进入此上下文后,可以执行挂钩方法或访问 Java 类等操作来控制或观察应用程序的行为。

var a=Java.use(“com.ad2001.frida0x1.MainActivity”); 声明了一个变量a来表示目标 Android应用程序中的Java类,Java.use函数指定要使用com.ad2001.frida0x1包中的MainActivity类。

a.get_random.implementation = function(){…}使用变量a在所选类的内部勾取get_random方法。

var ret_val = this.get_random(); console.log(“MainActivity.get_random result is ” + ret_val); 获取get_random方法运行的返回值,将其输出到控制台。


05
运行脚本


【云真机操作台】【Frida脚本】空白处点击【新增脚本】,或在左侧脚本库【运行脚本】功能区点击添加,来新增一个Frida脚本(图6),命名为Challenge_0x1_hook,将编写好的代码复制进来(当然,也可以直接在这里编写脚本)。然后点击【加载脚本】,由于反编译代码中get_random方法是在APP加载的时候被调用的,因此我们运行Frida脚本时,需要选择重启APP(图7)。脚本运行成功后,get_random方法的返回值已经输出到控制台(图8)。


APP动态分析系列 - Frida的基础用法(上)

图6. 在云真机操作台添加Frida脚本


APP动态分析系列 - Frida的基础用法(上)

图7. 运行Frida脚本


APP动态分析系列 - Frida的基础用法(上)

图8. 查看get_random方法返回值


现在我们已经获取程序初始化时生成的随机数i的值为97。接着,计算表达式(97 * 2) + 4 = 198,我们只需要在输入框中输入198并提交,就可以让check方法判断值为真,在程序界面成功获得flag(图9)。


APP动态分析系列 - Frida的基础用法(上)

图9. 输入正确答案获取flag


06
总结


Frida Hook方法的脚本模板:


1 Java.perform(function() { 

2   var <class_reference> = Java.use(“<package_name>.<class>”); 

3   <class_reference>.<method_to_hook>.implementation = function(<args>) { 

4     /* 

5       我们自己的方法实现 

6     */ 

7   }



02




用法2:调用静态方法


APP下载地址:https://github.com/DERE-ad2001/Frida-Labs/tree/main/Frida%200×2


01
了解APP样本


在下载Challenge 0x2.apk文件并上传至大狗云真机操作平台后,可以看到该APP程序界面非常简单,只有一个静态页面提示“HOOK ME!”,没有任何输入框和按钮(图10)。很明显我们需要Hook其中的某个方法,我们先将APK放入jadx分析。


APP动态分析系列 - Frida的基础用法(上)

图10. 应用程序Challenge 0x2界面


02
静态分析


使用jadx反编译APP,得到程序源代码。分析代码可以发现,应用程序只包含一个MainActivity类,在程序启动时加载activity_main布局,并获取该布局中的TextView控件对象赋值给静态变量t1。这个类中存在一个未被使用的静态方法get_flag,在get_flag中比较了传入的参数,如果传入的参数为4919则解密flag,设置给TxtView控件(图11)。


APP动态分析系列 - Frida的基础用法(上)

图11. 反编译源代码


1 public static void get_flag(int a) { 

2        if (a == 4919) { 

3            try

4                 SecretKeySpec secretKeySpec = new SecretKeySpec(“HILLBILLWILLBINN”.getBytes(), “AES”); 

5                 Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”); 

6                 IvParameterSpec iv = new IvParameterSpec(new byte[16]); 

7                 cipher.init(2, secretKeySpec, iv); 

8                 byte[] decryptedBytes = cipher.doFinal(Base64.decode(“q7mBQegjhpfIAr0OgfLvH0t/D0Xi0ieG0vd+8ZVW+b4=”, 0)); 

9                 String decryptedText = new String(decryptedBytes); 

10                 t1.setText(decryptedText); 

11             } catch (Exception e) { 

12                 e.printStackTrace(); 

13             } 

14         } 

15     }



分析完APP源代码可以知道,程序中只包含了一个MainActivity类,类中定义了一个静态get_flag方法,方法中比较了传入的参数是否为4919。我们要找的flag就藏在get_flag方法中,但是程序本身不会从任何地方调用该方法。因此,要获取flag,我们需要使用Frida框架来调用该静态方法,并将传入的参数变量设置为4919。


03
编写Frida脚本


我们需要使用Frida框架,编写一个JavaScript脚本,调用get_flag方法,并将传入的参数变量设置为4919。


首先明确我们要调用的get_flag静态方法位于程序com.ad2001.frida0x2MainActivity类中。调用该方法,并将传入的参数变量设置为4919的代码实现如下:


1 /*** 

2 Java.perform 是Frida中的一个函数,用于为脚本创建特殊上下文,进入此上下文后,可以执行挂钩方法或访问Java类等操作来控制或观察应用程序的行为。 

3 **/ 

5 Java.perform(function() { 

6   

7     var a = Java.use(“com.ad2001.frida0x2.MainActivity”); 

8     //声明了一个变量a来表示目标Android应用程序中的Java类。

9     //Java.use函数指定要使用com.ad2001.frida0x2包中的MainActivity类。 

10   

11     a.get_flag(4919);   

12     //调用get_flag方法并传入参数4919

13 })



04
运行脚本


在云真机操作台添加Frida脚本,命名为Challenge_0x2_hook,将编写好的代码复制进来。点击【加载脚本】,由于此方法为程序中的一个静态方法,不需要在程序启动时调用,因此我们只需要启动APP后点击运行即可,不需要在运行脚本时重启APP。脚本运行成功的同时,flag已经显示在程序界面中(图12)。


APP动态分析系列 - Frida的基础用法(上)

图12 运行Frida脚本获取flag


05
总结


Frida 调用静态方法的脚本模板:


1 Java.perform(function (){ 

2     var <class_reference> = Java.use(“<package_name>.<class>”); 

3     a.function(val); // 需要调用的方法名称 

4 })



03





用法3:更改变量的值


APP下载:https://github.com/DERE-ad2001/Frida-Labs/tree/main/Frida%200×3


01
了解APP样本


下载Challenge 0x3.apk文件并上传至大狗云真机操作平台后,可以看到该APP有一个按钮和一个 TextView,TextView 提供有关标志的提示,没有EditText可以输入任何内容。如果您单击该按钮,它会显示“TRY AGAIN”,重复点击界面仍然显示“TRY AGAIN”(图13)。猜测程序中可能存在某个变量的值,只有当它达到预设值时才能触发下一步操作,我们将APK放入jadx进行静态分析。


APP动态分析系列 - Frida的基础用法(上)

图13. 应用程序Challenge 0x3界面


02
静态分析


使用jadx反编译APP,查看反编译源代码,找到程序入口(图14)。分析代码可以发现,应用程序MainActivity类的btn.setOnClickListener方法为按钮添加了一个点击事件监听器,当按钮被点击时会执行onClick方法。在onClick方法中,会检查Checker.code的值是否为512,如果是,则会将解密后的flag显示在TextView控件上。code参数保存在Checker类中,我们需要对Checker类进行进一步分析。


APP动态分析系列 - Frida的基础用法(上)

图14. Challenge 0x3程序入口


1 btn.setOnClickListener(new View.OnClickListener() { // from class: com.ad2001.frida0x3.MainActivity.1 

2     @Override // android.view.View.OnClickListener 

3     public void onClick(View v) { 

4         if (Checker.code == 512) { 

5             … 

6             … 

7             …

8         } 

9         … 

10     } 

11 });



进入Checker类查看。在这个类中,有一个名为code的静态int变量,其值为0。此外,还有一个名为increase的静态方法,方法在被调用时向变量加2。但是此方法并没有在应用程序中的任何位置被调用,因此变量的值不会更改(图15)。


APP动态分析系列 - Frida的基础用法(上)

图15. Checker类


分析完APP源代码可以发现,程序在每次点击按钮时,会去检查Checker类中的code变量是否等于512。只有当该变量的值等于512时,点击按钮,APP才会输出flag到TextView控件上。要让code变量等于512,我们需要使用Frida调用Checker类中的increase的静态方法256次,或者将变量的值修改为512,这次我们尝试更改变量的值。


03
编写Frida脚本

我们需要使用Frida框架,编写一个JavaScript脚本,将code变量的值修改为512.


首先明确code变量位于程序com.ad2001.frida0x3包的Checker类中,将它的值修改为512的代码实现如下:


1 /*** 

2 Java.perform 是Frida中的一个函数,用于为脚本创建特殊上下文,进入此上下文后,可以执行挂钩方法或访问Java类等操作来控制或观察应用程序的行为。 

3 **/ 

5 Java.perform(function (){

6   

7   var a = Java.use(“com.ad2001.frida0x3.Checker”); 

8   // 声明了一个变量a来表示目标Android 应用程序中的Java 类。 

9   // Java.use函数指定要使用com.ad2001.frida0x3包中的Checker类。 

10   

11   a.code.value = 512

12   // 使用变量a将所选类的code变量值修改为512 

13    

14 })



04
运行脚本


在云真机操作台添加Frida脚本,命名为Challenge_0x3_hook,将编写好的代码复制进来。点击【加载脚本】,由于code作为Checker类中的静态变量,不需要在程序启动时调用,因此不需要在运行脚本时重启APP。脚本运行成功后,再次点击按钮,此时flag成功显示在程序界面中(图16)。


APP动态分析系列 - Frida的基础用法(上)

图16. 运行Frida脚本再次点击按钮获取flag


05
总结


Frida 更改变量值的脚本模板:



1 Java.perform(function (){ 

2     var <class_reference> = Java.use(“<package_name>.<class>”); 

3     <class_reference>.<variable>.value = <value>; //需要修改的变量 

4 })





结语



以上为本期分享的三个Frida的基础用法,后续我们还将分享更多相关基础和进阶用法。欢迎相关公检法技术工作者注册安装【无糖浏览器】,自行通过【大狗平台专区】的【云真机操作台】复现研究。大家还可以根据Frida-lab项目中的参考答案,尝试更多有趣的解题方法。


参考链接


[1]用法1:https://github.com/DERE-ad2001/Frida-Labs/blob/main/Frida+0x1/Solution/Solution.md

[2]用法2:https://github.com/DERE-ad2001/Frida-Labs/blob/main/Frida+0x2/Solution/Solution.md

[3]用法3:https://github.com/DERE-ad2001/Frida-Labs/blob/main/Frida+0x3/Solution/Solution.md


让我们一起借助Frida,揭开恶意APP的面纱,保护网络安全,捍卫用户权益!



无糖浏览器-您身边的办案助手




01

下载地址(PC端与APP同链接):

http://browser.nosugar.tech

02

邀请码:注册邀请码可从已认证通过的公安民警处获得,完成注册流程并审核通过可开通完整使用权限。

如有疑问,可以扫描下方二维码进入无糖反网络犯罪研究中心。

APP动态分析系列 - Frida的基础用法(上)


原文始发于微信公众号(无糖反网络犯罪研究中心):APP动态分析系列 – Frida的基础用法(上)

版权声明:admin 发表于 2024年4月8日 上午11:02。
转载请注明:APP动态分析系列 – Frida的基础用法(上) | CTF导航

相关文章