PS:这里假设一个场景,我们在进行app渗透时常规渗透不能满足所需,只能通过逆向工程来实现特定的需求。(注:只是学习笔记,大佬勿喷,如有新的思路或错误还请指出)。
随便输入账号和密码提示:Login failed.
一番操作无果,于是分析从app源码入手。
这里全局搜索一下Login failed. 跳转到对应代码层,然后看代码的整体逻辑是怎么写的。
分析:
1、 在onCreate()方法中,设置了activity_login.xml的布局文件,并且找到用户名和密码的EditText控件及登录按钮,并为登录按钮设置了点击事件监听器。
2、 点击登录按钮时,会获取输入的用户名和密码,如果用户名或密码为空会提示"username or password is empty."。否则,将输入的用户名和密码传入a()方法进行加密处理(发现有两个a()方法,这里调用的是第二个a()方法)。
3、 a()方法接受两个参数,分别是用户名和密码。在该方法中使用HmacSHA256算法对密码进行加密处理,并返回加密后的结果。然后在调用第一个a()方法将这个字节数组转换为小写的十六进制字符串。
4、 加密后的密码与输入的密码进行比较,如果相等则跳转到FridaActivity1页面,否则提示:Login failed.
代码简单分析后,获取所需。因为我们最终是与obj2作比较,所以直接hook到obj2这个 “值”(这里描述不专业,就以值称呼吧)就好了。接下来编写我们的脚本。
启动Frida-server后,执行Frida-ps -aU 列出正在运行的程序
接下来编写我们的hook脚本。编写完成后在运行(Frida -U AndroidDemo -l hook_obj2.js)时发现报错,原因是因为源代码中有两个a()函数,我们要用到的是第二个a()函数。
对脚本进行更改后并运行,可以看到控制台已经输入:hook is ok! 此时说明脚本已经ok
当我们随便输入账号密码时,发现控制台已经可以打印出obj2
然后我们把hook到的obj2这段字符串通过input text “” 命令输入在编辑框(我这里执行了两次,是因为第一次没清空)。
最后点击SIGN IN即可成功通过。
往下暂时先不写了,最后在这里给大家简单分析一下这个hook脚本吧。
这个hook脚本主要是用于在Android应用中的LoginActivity类的a方法被调用时,输出用户输入的用户名和密码,并记录方法返回值。以下是个人对脚本的分析:
1、 首先定义了一个hook函数,用于实现Hook的功能。同时使用了Frida提供的Java.perform(function () {…})方法来执行后续特定的hook操作。
2、 使用Java.use()获取了com.example.androiddemo.Activity.LoginActivit类的引用,用于后续调用和重写。
3、 LoginActivity.a.overload('java.lang.String','java.lang.String').implementation = function (str1, str2) { ... }:
重写了 LoginActivity 类中的 a 方法,该方法接受两个参数类型为 String 的参数。
在重写的实现中,记录了用户输入的用户名和密码,并输出到日志中。
最后,返回了原始方法的返回值
4、 Implementation是在hook点被触发时,调用指定的函数或方法来替换原始的实现逻辑。