Frida Hook(八) – Android APP强制升级Bypass

简介

Frida Hook(八) - Android APP强制升级Bypass

本文介绍比较常见的APP强制升级的一种Hook 绕过手段,在日常使用中往往会碰到App迭代升级,大多数情况下升级都会给出可选项,但有的时候会发现必须强制升级完后才可以使用App,不然就无法正常使用;APP 强制升级可能有以下一些原因:

  • 修复重要漏洞:为了保障用户的信息安全和系统稳定,需要及时修复可能被黑客利用或导致数据泄露的严重漏洞。

  • 适配新的操作系统:随着操作系统的更新,APP 可能需要升级以兼容新的系统特性和技术标准。

  • 功能改进和优化:增加新的功能、提升性能、改善用户体验等。

  • 法规和政策要求:某些行业的法规政策变化可能要求 APP 进行相应的调整和升级。

  • 停止对旧版本的支持:为了集中资源维护和优化最新版本,开发者可能会停止对旧版本的技术支持和服务。

可以明显看到修复重要漏洞往往是一个主要因素,所以旧版本通常会存在一些高危风险,对于安全研究有一些参考价值(普通用户建议看到强升最好就升级,听劝,别死犟;当然也不排除某些纯商业化行为的强升)    

Frida Hook(八) - Android APP强制升级Bypass

Frida Hook(八) - Android APP强制升级Bypass

          

          


基础-函数调用关系Hook

Frida Hook(八) - Android APP强制升级Bypass

在分析app时,往往需要知道对某个hook的类或者函数的上下游调用函数关系,方便分析出具体需要绕过的核心逻辑处

想要在Java代码中打印函数栈,往往使用Log类的getStackTraceString方法

 Log.getStackTraceString (new Throwable ()) ;

所以需要对该函数进行hook,以下就是最简单基础的Frida Hook JS 脚本,在后续的其他函数hook中,只需要调用showStacks,就可以打印出被hook函数的函数调用关系    

JavaScript                  
function showStacks() {                  
    Java.perform(function() {                  
        console.log(                  
            Java.use(“android.util.Log”).getStackTraceString(                  
                Java.use(“java.lang.Throwable”).$new()))                  
        )                  
    });                  
}

          


实战举例

Frida Hook(八) - Android APP强制升级Bypass

首先,观察到该App应用程序进行版本更新前会弹出提示信息。根据提示信息的样式,猜测其使用了Toast组件。因此先对Toast进行Hook,

JavaScript                  
//定义打印函数栈                  
function showStacks() {                  
    Java.perform(function() {                  
        console.log(                  
            Java.use(“android.util.Log”).getStackTraceString(                  
                Java.use(“java.lang.Throwable”).$new()))                  
        )                  
    });                  
}                  
                 
Java.perform(function () {                  
    var ToastClass = Java.use(‘android.widget.Toast’);                  
    ToastClass.show.implementation = function (text) {                  
        console.log(‘Original Toast text:’, text);                  
                         
        //调用打印函数栈                  
        showStacks()                  
                         
        // 在这里可以添加你想要的自定义逻辑                  
        return this.show();                  
    };                  
});

              

代码注入运行后,从打印出来的函数栈信息中,可以发现有一个名为com.pikasec.util.UpgraderUtil.run的方法。接着借助Objection来Hook该类下的所有方法。需要注意的是,该App应用程序的强制升级发生在应用程序被启动之初,因此要在启动前使用Objection,在终端Command中输入下列命令

JavaScript                  
objection -g com.pikasec.app explore –startup-command “android hooking watch class                  
‘com.pikasec.util.UpgraderUtil’ “

关于Objection基础用法可以参考之前的文章,–startup-command 命令用于在启动 objection explore 时自动执行指定的命令

          

当App应用程序强制升级的弹窗再次出现时,Objection中也打印出相关的函数调用,格式基本如下:

JavaScript                  
com.pikasec.util.Upgrader.b(java.lang.String)                  
com.pikasec.util.Upgrader.a(android.content.Context)                  
com.pikasec.util.Upgrader.b(java.lang.String, java.lang.String,java.lang.String)

接下来使用jadx-gui反编译app,结合静态分析,找到对应的具体函数实现逻辑,分析其强升逻辑即可

使用jadx全局搜索,发现其中的a函数就是用于获取App应用程序自身版本号的,代码如下:

Frida Hook(八) - Android APP强制升级Bypass

阐释下代码,该函数通过Context获得全局包管理器,之后从包相关信息中取出当前App应用程序的versionCode(即版本号)。由该App应用程序强制升级弹窗可知,最新版本号为6.6.6。因此可以得到最简单的绕过逻辑,只需要Hook该函数,将返回值修改为最新版本,即可去除强制升级。    

那么就可以动手写hook 脚本了

JavaScript                  
//定义打印函数栈                  
function showStacks() {                  
    Java.perform(function() {                  
        console.log(                  
            Java.use(“android.util.Log”).getStackTraceString(                  
                Java.use(“java.lang.Throwable”).$new()))                  
        )                  
    });                  
}                  
                 
//编写核心hook绕过逻辑                  
Java.perform(function () {                  
    var upgraderUtil=Java.use(“com.xxxx.util.UpgraderUtil”);                  
    upgraderUtil.a.overload(‘android.content,Context’).implementation=function(context){                  
        showStacks ();                  
        var result = this.a(context);                  
        console.log(“versionCode:”,result);                  
        return 666;                  
    }                  
}

将Hook代码注入后,再次运行该App应用程序,就可以发现没有弹出强制更新弹窗,可以正常浏览界面。是不是比想象中还简单。

          

还有一种思路就是将升级逻辑hook掉,去除升级操作,在本例中升级操作是由com.pikasec.util.Upgrader.b函数完成,那么只需要将其内容变为空,这样即使点击确定升级也不会升级了,hook脚本如下

JavaScript                  
Java.perform(function () {                  
    var upgraderUtil=Java.use(“com.xxxx.util.UpgraderUtil”);                  
    upgraderUtil.b.overload(‘java.lang.String’).implementation = function(context) [                  
        //返回空内容                  
        return “”                  
    }                  
}
       




原文始发于微信公众号(暴暴的皮卡丘):Frida Hook(八) – Android APP强制升级Bypass

版权声明:admin 发表于 2024年7月20日 下午5:39。
转载请注明:Frida Hook(八) – Android APP强制升级Bypass | CTF导航

相关文章