抓取登录包
解决安全检测
使用木木模拟器,安装好app刚准备愉快的抓个包。竟然检测到root,不能进入。那就先把这个给他hook掉。
用jadx打开apk,全局搜索一下,提示的文字。
可以看到这里进行了几种检测,编写frida hook代码,直接把 initCheckSafe 方法置空
Java.perform( function () { var SecurityBuilder = Java.use('XXXXXXXX.SecurityBuilder'); var initCheckSafe = SecurityBuilder['initCheckSafe'].overload('android.content.Context','java.lang.String'); initCheckSafe.implementation = function () { send("hook initCheckSafe"); };}
解决完毕,我们再进入app
又提示要跟新,事是真的多。那就更新吧。点击更新后,加载了一些东西,然后进入了登录页面。(!!! 后面发现这里的坑)
抓包分析
配置好代理,直接抓包。
可以看到请求的数据模式都是
action=xxxx&data=json
把这个json数据拿出来看看,多尝试几次发现密码不变这个password不变,其他的参数都可以写死。到这里,如果账号少的话,手动抓一次包后续使用就可以了。但是咱能满足于此吗,盘它!
寻找加密位置
盲狙碰运气
这个参数看着像是,某种加密后base64的结果。先base64解码看看啥情况。将加密后的值urldecode之 后再base64解码
一堆乱码看不懂。那我们使用南山大佬写的xposed的模块把常见加密hook一波,尝试快速定位。激活xposed plus模块,然后打开ddms,查看日志信息。
可以看到常见的加密类都被hook到了,但是在保存的日志中尝试搜索输入的密码,抓包的加密结果等, 都一无所获。
搜索反编译代码
看来好事多磨,快的不行那我们去分析代码吧。
尝试搜索 登录链接 登录参数字段值等,都寻找不到有用的信息,事情好像陷入了僵局。
巧计寻出路
静静思考一会,回想到登录接口参数data后面的值是一个json类型,也就是字典类型。那能不能hook java中这个类,看看有没有password赋值的操作
百度一波,得到如下hook代码
var print = console.log;function hoon_map(cName, mName, args) { Java.perform(function () { var clz = Java.use(cName); if (clz == null) { throw "java.use()==null" }; var method = null; method = clz[mName].overload(args[0], args[1]); method.implementation = function () { print(cName + " " + arguments[0] + " " + arguments[1]); var ret = method.apply(this, arguments); return ret }})} function main() { print("runing"); hoon_map("java.util.HashMap", "put", ["java.lang.Object","java.lang.Object"]); hoon_map("java.util.LinkHashMap", "put", ["java.lang.Object","java.lang.Object"]);}main()
把这代码灵活运用一下,我们再登录一次看看结果。
果然发现了赋值操作,那就过滤一下无用的信息,再把这个操作的调用栈打印出来,顺藤摸瓜,那不就 能找到加密位置了嘛。感觉看到了希望。
还好调用栈不是很多,去掉 java开头的和proxy,剩下的我们从上面开始一个个看一下,有没有加密的地方。
一直找到最下面这个方法,参数可以看到是从 exec 这个函数的参数传来的。那么hook这个exec的入参看一下。
hook 结果:
这下蒙蔽了,都追到根了,咋还是加密过的值呢。
再肯硬骨头
发现线索一
有困难但是也不能放弃。再自己端详一下exec的代码,发现它头部有个@JavascriptInterface好像装饰 器一样的东西,和别的函数都不一样。
不懂咱就去搜索一下,然后发现这个是可以让 js 和 java 互相调用的一个东西。
那就知道方向了,加密是在js中进行的,然后js中调用java里的exec方法,将值传了进来。
将apk反编译,先去找找那些js中,有cbPassInfo setOfflineCache这些信息。
哟呵,搜到了这两个里面有。把他俩拖出来瞅一瞅。
在 login.js 里面只有这两处。先验证一下这里是不是传加密值的地方。
我把这里的 cbPassInfo 改成别的字符串,然后重新打包签名apk,安装,再抓取一次登录包,如果出现的是我修改的字符,那说明这就是调用的位置。
信心满满,又抓了一次包。结果啪啪打脸。还是 cbPassInfo 。
发现线索二
突然想到,重新安装打开后,有个提示框,更新资源,难道它又重新下载了这个文件,把我修改的重置 了。
卸载,重装后,抓包查看下它更新的资源,发现果然是这样。
既然修改apk不行,js又是静态文件,那直接在模拟器中搜索login.js
结果有3,4个,把文件重命名,app打开没了登录界面,那就是它了。
模拟加密
分析js
先分析一下js,密码就是通过蓝框两个方法加密的。
先搜索一下 D 和 Base64,Base64没有获得有效的信息。发现D应该和 sha1 有关系
这里js不好调试,我们利用js调用java的流程,把我们想要的值传给java层,然后去hook接收的函数。这 里把我把用到的函数,各种结果都打印了一下。
这个D刚才看是和sha1相关的,用标准的sha1对比一下。
发现和上面结果相同。那就只剩base64这个函数了。看打印出来的代码,发现这不是一个标准的base64,运行报错缺少 c 变量。
搜素函数内的代码,在common.js中发现了
现在逻辑清楚了,把c的值拿过来,用js来实现加密。可以看到结果和抓包一致,收工。
总结
之前遇到的app都是在java代码中加密,或者 so库里面。在js中的这是第一次遇到。
幸运的是js没有做处理,如果把web端的反扒应用在这,手机端又不好对js进行调试,那真是够秃头的了,可怕。