浅笑博客
浅笑博客
APICloud美姿App接口逆向分析
APICloud美姿App接口逆向分析

也是第一次搞ApiCloudApp逆向。首先拿到Apk原包,进行查看,360加固,脱壳,然后发现dex里似乎找不到相关有用的信息。由于没有接触过,先百度一下相关教程,找到一片https://www.codercto.com/a/89463.html,从中也学习到ApiCloudApp的工作原理。他其实就是用html写的App,大部分资源如html、js、css都是加密本地Assets存放,然后webview加载时先解密再加载。然后ApiCloud提供了底层框架,方便与java互通调用。

上述的教程中,作者从加载的过程进行逐步分析,分析出了关键解密数据的位置,然后hook进行解密数据的输出。将其有用到我们的APP破解中时,我们就不用去根据原理重新找关键位置了,直接通过教程中的一些关键词定位即可。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_15-25.png

如分析到,关键位置调用了i类的构造方法中含有个字符串关键词“UTF-8”,我们可以通过此关键词进行定位。当然这么通用的关键词怎么找呢?发现ApiCloud打包的App,即使经过了混淆,到都会有包路径com.uzmap.pkg.uzcore,且上述教程所定位的位置也是在该路径下,所以使用MT管理器在改路径下完全匹配搜索“UTF-8”,显然缩小了定位范围,只搜到4个结果,然后结合一些特征,如所在类的父类是WebResourceResponse且构造方法第二个参数为InputStream。因此很快便找了这个关键位置。

(原包有360壳,脱壳过程不再累赘)

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-15-40-38-690_bin.mt_.plus_-492x1024.jpg

然后搜索在哪里进行了调用,使用MT管理器的代码正则搜索invoke(.*)Lcom/uzmap/pkg/uzcore/e/i;->(Ljava/lang/String;Ljava/io/InputStream;)V

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-15-40-09-132_bin.mt_.plus_-492x1024.jpg

搜到只有如上类中L27和L47调用。这是发现第二个参数传入的都是com.nzmap.pkg.uzcore.e.d(LB,String)对象。结合上面的教程,可以知道这里实例化的e.d(LB,String)的第一个参数就是解密后的数据的字节数组。因此同理进行hook,但我们可以使用更方便的frida,而不是编写hook模块app。

关于frida的使用,不会的可以取百度一下,基础教程也很多。

编写脚本如下,其中24行的index.html为所hook输出的资源,可以换成所需要的依次执行即可:

import frida
import sys

rdev = frida.get_remote_device()
process = rdev.enumerate_processes()
packagename = "com.mmzztt.app"
pid = -1
for e in process:
	if e.name==packagename:
		pid = e.pid
if pid==-1:
	print("NoProgress:%s"%(packagename))
	exit()
else:
	print("FindProgress PID:%d"%(pid))
session = rdev.attach(packagename)
script_js = """
setImmediate(function(){
	Java.perform(function(){
	    send("Ready");
	    var StringClass = Java.use("java.lang.String");
	    var HookClass = Java.use("com.uzmap.pkg.uzcore.e.d");
	    HookClass.$init.overload("[B","java.lang.String").implementation = function (param_1,param_2) {
		if(arguments[1].endsWith('index.html')){
			send(arguments[1].substr(22));
			send(StringClass.$new(arguments[0]).toString());
		}
	    	var result = this.$init(param_1, param_2);
	    	return result;
	    }
	});
});

"""
def on_message(message, data):
	if message['type']=='send':
		print(message['payload'])
	else:
		print(message)

script = session.create_script(script_js)
script.on('message',on_message)
script.load()
sys.stdin.read()

使用上面的脚本依次解密出进入app时加载的几个html和js,然后就可以直接找打所需要的接口了。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_15-52.png

开发时的注释都在,分析起来那就简单了。发现ajax后回调中进行了数据解密,因此我们还需要分析解密算法。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-39-1024x520.png

在list.js中找到了封装的ajax方法,发现其中请求头中添加了Referer,这个也需要注意,因为往往它的服务器会验证这个referer。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-40-1024x742.png

同时从上图看到了他的大概的解密逻辑是AESCBC解密。但我们怎么分析它的秘钥和偏移呢。突然没了头绪。

但到这里,大概可以感受到apicloudapp开发是有一定规范的,因此抱着试一试的态度去apicloud官网doc文档网站(https://docs.apicloud.com)看看能不能找到相关的信息。去doc官网搜索了上图L77、L81的loadSecureValue,果然搜索到了相关信息。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-35-1024x371.png

因此接下来关键定位到了assets下的key.xml文件,文件当然是加密过的,根据上面的经验已经可以猜到,其app加载时会先解密再读取加载的。因此app dex搜索“app.key”,搜到结果中简单分析可以发现一处关键位置。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-16-06-18-437_bin.mt_.plus_-492x1024.jpg

由于是私有静态变量,直接在这个类中找看是哪调用了它,并分析如如何调用的。我这里使用的mt管理器,直接smali代码搜索Lcom/uzmap/pkg/uzcore/g/b;->a:Ljava/lang/String;,只找到一处:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-16-06-47-909_bin.mt_.plus_-492x1024.jpg

然后转成java逐步分析,是如何调用的:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-16-08-07-983_bin.mt_.plus_-492x1024.jpg

最终发现L115的a方法返回的字节数组应该是明文数据,和上面一样使用frida hook查看:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-33-1024x947.png

虽然像是部分数据解密成功了,但没有分析我们需要的key和iv。但是意外发现一个关键字“signature”,是不是在前面的分析中遇到,对的,如下图L86:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-40-1024x742.png

我们好像明白了什么,这应该是apicloud框架提供的html js调用java的实现。因此我们可以通过signature对应的那个java类中进行尝试进一步分析。前往该java类搜索aescbc,果然搜到相关方法。

http://blog.qianxiao.fun/wp-content/uploads/2021/04/Screenshot_2021-04-19-16-37-35-242_bin.mt_.plus_-492x1024.jpg

且通过关键词data、key、iv确定其参数UZModuleContext类就是上面图中aesDecodeCBCSync函数传入的dict

{
         data: data,
         key: key,
         iv: iv
}

因此我们hook UZModuleContext类的optString方法,输出返回结果看看:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/2021-04-19_14-32.png

果然找到2个特别像秘钥和偏移的字符串。

我们模拟一个请求,来解密返回数据测试一下:

http://blog.qianxiao.fun/wp-content/uploads/2021/04/图片.png
http://blog.qianxiao.fun/wp-content/uploads/2021/04/图片-1-1024x395.png

Perfect! 至于各种接口,按照上面的方法分别解密其页面html查看其中的接口请求逻辑即可。

关于此文,如有错误,欢迎不吝指正,欢迎评论交流。转载请注明:来自浅笑博客[http://blog.qianxiao.fun/?p=1458]

发表评论

textsms
account_circle
email

浅笑博客

APICloud美姿App接口逆向分析
也是第一次搞ApiCloudApp逆向。首先拿到Apk原包,进行查看,360加固,脱壳,然后发现dex里似乎找不到相关有用的信息。由于没有接触过,先百度一下相关教程,找到一片https://www.codercto…
扫描二维码继续阅读
2021-04-19