Android逆向之旅—Android中分析某手短视频的数据请求加密协议(IDA静态分析SO)第三篇

一、逆向分析

在之前的两篇文章中,我们已经介绍了短视频四小龙的某音,某山,某拍的数据请求加密协议,不了解的同学可以点击查看:某音短视频协议破解解析某拍短视频协议破解解析;那么今天继续最后一个短视频那就是某手,不多说了,还是老规矩直接抓包找入口:

看到请求参数分为两部分,一个是在url后面拼接的参数,一部分在body中的。不过这个没多大影响,分析参数信息之后发现在body字段中有一个sig,这个就是签名信息了。所以需要找到这个值的获取方法即可。这里我们使用Jadx打开某手应用,不过这里可能要注意,某手的包比较大,而且分了四个dex文件,所以打开可能点卡,可以先解压出四个dex文件,依次打开即可。在classes.dex中全局搜索可以看到:

这里看到他内部网络请求使用了retrofit框架,这个框架其实核心原理还是okhttp,只是用注解封装了。那么到这里就发现其实注解功能在逆向中分析起来是比较费劲的。所以我们就换个思路,直接全局搜索那个签名字段:”sig”,可惜的是在classes.dex中并没有搜到,在去第二个dex中搜:

看到了,搜到了直接点击进入即可:

这里看到调用了一个方法来获取sig字段信息,直接查看这个类:

这个是接口类型,那么查看他的实现类是哪个?这个变量在构造方法中进行赋值的,看看类型:

到这里遇到问题了,应该是拆分了dex,所以搜索这个类的全局调用会没有结果,这样就跟踪有点麻烦了,不过这里依然采用hook大法,直接hook这个类的构造方法,打印这个参数的类名称即可:

运行代码,看日志信息:

找到这个类了是:com.yxcorp.gifshow.retrofit.c,全局搜这个类,这时候要注意,如果在一个dex中找不到,就去下一个dex中搜索即可:

这个类果然是获取请求参数信息的,有一些公告参数信息,和基础信息,继续往下看:

看到了获取sig字段的方法方实现,其实很简单,直接将传入的两个map参数结构的key和value进行拼接,然后进行排序,最后调用CPU.getClock方法获取加密信息即可。继续看看这个加密方法:

果然还是把加密功能放到了native中做的,参数比较好理解:全局的context,排序好的参数字节数组,系统版本号,那么接下来用IDA简单分析他的native代码,直接打开libcore.so文件即可:

不过可惜的是,会发现没找到这个native函数,但是找到和这个函数可能有关系的,其实这个是他做了一次混淆,后面会出文章单独介绍这种混淆技术。点进去看看:

直接点击X键,查看这个函数的调用地方:

往上查看函数名:

这时候发现了,看到了这个函数了,我们点击F5查看他的大致C代码:

遇到这个警告,这个也是他进行了混淆,不过没关系,可以右键create function即可:

当然这里可以直接使用快捷键P即可,然后就可以顺利查看他的C代码了:

不过,这里不做太多介绍分析了,因为和之前文章一样,我们的目的直接调用这个so来获取加密结果即可。不过静态分析so还是要有的,主要大致看一下他有没有什么防护策略,不过这里大致看了,应该没有。

 

二、获取请求数据

直接去demo工程继续调用,依然在demo工程中新建一个CPU类:

记得报名和类型都必须保持一致即可,然后就开始构造参数调用这个方法了,这里首先来分析那个传入的两个map结构参数信息,这里依然还是用hook打开,来打印日志分析:

运行,看看打印的结果日志:

再去比对Fiddler中抓包信息的请求参数:

可以很容易发现,第一个参数map是公众参数也就是在url后面的,第二个是基础参数在body中的。那么就简单了,直接构造这两个map结构即可:

这里为了方便,依然将参数写死,后续会进行优化动态获取即可。然后直接调用加密方法,进行网络请求:

运行demo,看看加密信息以及是否能正确请求到数据:

惊奇的发现,尽然成功获取到数据了,说明他native中的加密函数真的没有什么防护策略,这个和之前的某音某拍差距了,我们把这json数据拷贝出来格式化看看结果:

后面我们只需要简单的解析这个json数据即可。

 

三、继续填坑

可惜的是,到这里算是结束了吗?原以为结束了,因为这里测试我一直用的都是4.4的系统,结果无意中用了5.1的系统测试发现,尽然拿不到数据,原因就是获取签名信息失败了,也就是那个native方法getClock获取失败,那么就恶心了,还得重新回头去看这个函数:

这里我们可以直接静态分析so文件,继续查看getClock函数,到这里会发现5.1的手机的cpu_cnt值是null,这个值在哪里赋值的呢?继续往下查看即可,看到了是个类似于检查cpu属性的函数checkCpuProperty:

而我们知道5.0系统之后cpu架构改变很大的,继续查看这个函数功能:

看到核心点了,这里用a4变量做判断了,看看这个a4是啥:

是这个函数的最后一个值传递进来的。继续往回看,这个参数是怎么传进来的:

这里为了演示方便,就把getClock的没用代码删了,主要看这个参数是怎么传递进来的,发现是getClock的最后一个参数,那么也就是Java层调用这个方法传递的最后一个参数,继续回去看这个方法的调用:

这里看到,最后一个参数的确是系统版本,那么就真相大白了:为何4.4的系统可以拿到数据,而5.1的设备拿不到,因为在底层so中对系统做了判断,大致应该是判断cpu信息啥的。那么为了能够让我们始终都能拿到数据,可以非常简单的操作,就是这里的方法最后一个参数直接写死就是4.4对应的api值19,这样永远都可以拿到数据了,那么有同学会觉得奇怪了,这么做是不是有点投机取巧?会影响后面的数据读取吗?其实从这里看到应该是应用当初做的一套版本兼容,而我们知道现在4.4系统的占有率还是很高的,应用短期内不可能把这个兼容去掉,而只要兼容不去掉,我们客户端就模拟4.4的系统从而顺利的拿到数据了,何乐而不为呢?

严重声明

本文的意图只有一个就是通过分析app学习更多的逆向技术,如果有人利用本文知识和技术进行非法操作进行牟利,带来的任何法律责任都将由操作者本人承担,和本文作者无任何关系,最终还是希望大家能够秉着学习的心态阅读此文。鉴于安全问题,样本和源码都去编码美丽小密圈自取!

 

四、总结

大家看完本文之后,会发现其实某手对协议并没有做太强的加密防护策略,我们很容易就获取到了,只是因为他进行了拆包,所以在跟踪代码的时候比较棘手,不过幸好我们有无敌的hook大法,无需痛苦的跟踪代码。那么到这里我们就成功的分析完了短视频四小龙:某音,某山,某拍,某手这四家app的数据请求加密协议了,后面就要开始我们的真正项目了,那么到底是什么项目呢?尽情期待。


发表评论

电子邮件地址不会被公开。 必填项已用*标注