2019年末的一个偶然机会,听到了“frida”这个词语,作为刚入行的安全小白,我对这个此产生浓厚的兴起,一步步走上了frida框架的学习之路。frida是一款基于python和java 的hook框架,可运行在Android、IOS、Linux和Widows等多个平台。期初,感觉这个框架真是有点意思,接触久了发现简直太有意思了,面对移动APP的时候,一旦拥有了Frida,也就拥有一切。本篇文章中,我们将重点介绍Frida方面的知识。
1、Hook是个什么鬼?
Hook翻译过来就是“钩子”的意思,钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。Hook技术无论对安全软件还是恶意软件都是十分关键的一项技术,其本质就是劫持函数调用。
2、Frida框架的那些事
frida是一款基于python和java 的hook框架,是一种动态插桩工具,可以插入代码到原生App的内存空间中,动态的监视和修改其行行为,可运行在Android、iOS、Linux和windows等多个平台。
插桩技术是指将额外的代码注入程序中以收集运行时的信息,可分为两种:一是源代码插桩【Source Code Instrumentation(SCI)】:额外代码注入到程序源代码中;二是二进制插桩【Binary Instrumentation】:额外代码注入到二进制可执行文件中,其又可分为两种:
图1 插桩技术分类
上面把Frida框架说的天花烂坠的,神乎其神,利用它到底能做什么呢?我们使用Frida框架可以:可以访问进程的内存,提取我们感兴趣的信息或敏感信息;可以在应用程序运行时覆盖一些功能,改变其程序运行逻辑;可以调用相关类中函数;可以在堆上查找对象实例并使用这些对象实例;可以动态跟踪、拦截变量和函数等等。
瞧,它能做的事情已经够多的了吧!现在让我们开启Frida框架之路吧!
3、如何让Frida奔跑起来?
今天我们用到的frida框架分为两部分: 一部分是“客户端”即:用于连接远程设备,提交要注入的 JS 代码到服务端,并接受服务端发来的消息; 另一部分是“服务器端”即:注入JS代码到目标进程,操作内存数据,并将相关信息发送至给客户端。
3.1如何获得frida CLI
3.1.1环境要求
系统环境 – Windows、macOS、Linux
Python – 最新的3.x版本
Adb环境 – 请自行下载adb工具或安装android studio工具
环境准备好了,让我们来安装frida CLI吧!安装frida CLI有很多种方法,这里只介绍两种,即:pip和npm:
3.1.2 pip 安装frida
Python 2.7.9+或Python3.4+以上版本都自带 pip 工具,请自行安装
执行pip install frida
执行pip install frida-tools
执行frida –version
3.1.3 npm安装frida
自行安装NodeJS
执行npm install frida
执行npm install frida-tools
执行frida –version
3.2如何获得frida-server
3.2.1环境要求
手机一部,本文主要讲述Android系统
手机必须被Root,具体Root方法请自行查询
3.2.2 安装方法
下载frida-server,地址:https://github.com/frida/frida/releases
执行以下命令
图2 列出安卓设备
图3 放置frida-server到设备
3.2.3如何运行frida
图4 启动frida
4、掀开Frida的神秘面纱
4.1 Frida CLI交互工具
frida-ps命令能够列出客户端进程的命令行工具
图5 frida CLI交互命令(一)
frida命令是一个交互式解释器,用于实现Hook代码的动态注入。
图6 frida CLI交互命令(二)
备注:这里的com.android.chrome就是通过frida-ps命令查询到的远程客户端进程。
另外还有四个命令分别是:
图7 frida CLI交互命令(三)
由于并不常用这里就不详细介绍了,感兴趣的同学可以去frida的官网查看详细介绍和用法。
4.2常用Java API
由于frida的注入脚本是Java,因此在开始frida初探之前,有必要对Java注入相关的API做一个简单介绍, 后面我们都将通过js脚本来操作设备上的Java代码。
图8 frida的Java API(一)
当我们使用Java.use()获取Java类之后,我们就可以通过class.method.implementations = function() {}的形式hook某类的某方法,不管是实例方法还是静态方法都可以。
另外,由于js代码注入时可能会出现超时的错误, 为了防止这个问题,我们通常还需要在最外面包装一层setImmediate(function(){})的代码,如下所示:
图9 frida的Java API(二)
5、初探Frida即:Hello World程序
通过上面的介绍,现在终于可以来真格的了。而这里所说的Hello World程序,和我们日常看编程书籍所说的有所不同,我们上网找了一个OWASP Uncrackable Crackme Level 1的APP,并对其“防Root检测”功能进行了Hook。
首先,我们下载OWASP Uncrackable Crackme Level 1的APK文件,并将其扩展名修改为.zip,然后找到classes.dex文件将其编译为classes.jar文件。
dex2jar classes.dex -o classes.jar
之后,使用JD-GUI打开classes.jar文件,查找关键字,这里的关键字是“Root detected”。
图10 代码片段(一)
另外,在 MainActivity 类中看到,函数 a 打开了一个对话设置了一个 onClickListener监听,当我们按ok按钮时,onClick事件函数就会被触发。
图11 代码片段(二)
图12 代码片段(三)
由以上代码可知,onClick事件函数只是简单的使用 system.exit ( 0 ) 来退出app。因此我们只需要不调用system.exit ( 0 ) 阻止App退出即可。
图13 frida代码
现在让我们运行此App程序,它依然弹出了Root检测的对话框。
图14 App运行界面
现在让我们来运行frida注入程序,然后点击OK按钮,神奇的事情发生了,App并没有退出,我们正常的进入了App界面。
图15 frida注入界面
图16 frida注入后的App界面
至此,我们以一个实例展示了frida框架的强大和神奇之处,这个Hook功能虽然简单,但是同样体现了整个的Hook过程,所谓麻雀虽小,但五脏俱全。
作者:范斌、孙颖嘉、卫斯赜
来源:51Testing软件测试网原创