某游戏社区App | So层逆向分析

大家好,我是TheWeiJun,不知不觉已经来到了2022年底。回顾这一年,发生了太多事迹;有挫折、有喜悦、其中最开心的是结交了许多志同道合的朋友。本文将是笔者2022年最后一篇文章收官之战,全程高能,在阅读的同时不要忘记点赞+关注哦⛽️

特别声明:本公众号文章只作为学术研究,不用于其它不法用途;如有侵权请联系作者删除。

目录

一、抓包分析

二、Jadx反编译

三、frida hook调试

四、ida动态注册分析

五、算法还原

六、思路总结

趣味模块

新年新气象,永远行大运。2022年的最后一战由小军出场!小军的职业是一名计算机高级开发工程师,小军的爱好是喜欢玩游戏。他特别喜欢玩一些新游,然后关注下大家对新游的一些体验和看法。于是小军找到了某游戏社区,在小军想时刻关注游戏社区更新动态时,他遇到了难题,通过jadx定位到加密参数后,遇到了So层文件。今天我们将与小军并肩作战去探索我们未知的领域,感兴趣的读者记得给我一个star!

公众号:逆向与爬虫的故事

专注于网络爬虫、JS逆向、APP逆向、安全攻防实战经验分享及总结。

一、抓包分析

1、打开我们本次需要抓取的App,使用charles设置代理进行抓包,抓包截图如下所示:

说明:之所以进行打码处理,也是为了避免不必要的麻烦,希望大家能理解。我们的目的是要学习别人的加固思路而非破解!

2、搜索指定关键字,定位我们想要获取的数据包,然后截图如下所示:

总结:观察上图,确定我们本次需要还原的参数authorization后,初步判断该参数后,无法确定使用的什么加密手段;接下来让我们进入反编译调试环节吧!

二、Jadx反编译

1、使用Fart对指定App的apk脱壳后,直接使用jadx打开脱壳后保存的zip包,截图如下所示:

2、等待jadx反编译完毕后,我们使用查找参数名和关键字的方法进行加密位置定位,截图如下所示:

温馨提示:此刻如果你电脑内存不够16个G,介意还是换个电脑再来操作,相信我绝对没有错。

3、经过分析及追踪java源代码,最后定位到authorization参数加密的位置如下图所示:

总结:分析上面authorization的加密逻辑,我们需要确定return返回值中包含的多个参数的初始值即可完成对该参数的算法还原,接下来我们一起进入hook调试环节分析一下该算法吧。

三、frida hook调试

1、想要获取加密逻辑,我们首先需要先拿到str、e3、d2、f2的初始值,先hook一下c方法,构建frida代码如下所示:

2、启动frida脚本,执行刚刚写好的hook代码后,刷新手机界面,分析截图如下所示:

此刻,我们将charles中的该请求包也截图,进行对比分析,截图如下:

总结:观察上面两张图的参数值,我们可以清楚地看到入参、出参和charles中的参数一一对应,接下来我们只需要还原每一个参数算法即可。

3、各个参数hook调试分析后,所有参数初判断总结如下:

  • e3  当前unix时间戳,10位

  • d2  五位随机字符,由字母和数字组合。

  • str 40位长度,初步怀疑为sha1加密 待定分析

  • str2 40位长度,初步怀疑为sha1加密 待定分析

  • f2  hmac sha1加密,通过分析java源码得出

3.1  f2 参数 hook代码如下所示:

3.2  终端打印入参及出参输出如下所示:

4、接下来我们分析下str、str2两个参数的生成规则,只要解决掉这两个参数,我们就可以实现authorization参数的算法还原。经过多次hook,我们发现str、str2的值好像是固定不变的,截图如下所示:

结论:由于没有突破口,进行app卸载后重新安装,使用frida脚本重新hook,将hook到的str、str2的值进行查找,发现了该值是有新的接口返回的,截图如下所示:

frida hook界面截图如下:

charles定位截图如下:

总结:此刻我们已经知道了str、str2的生成规律,我们只需要还原该接口请求就能实现str、str2的参数生成,接下来我们需要对sign参数进行解密分析。

5、使用jadx查找sign参数,最后定位到该参数位置截图如下所示:

5.1  编写frida脚本进行函数hook,代码截图如下:

5.2  启动刚刚编写的hook脚本,终端输出截图如下:

5.3  此刻我们查看charles中的数据包sign截图如下:

总结:sign参数生成方法定位后,我们只需要还原sign加密方法即可完成所有代码闭环。

6、sign加密方法定位后,我们追踪java代码,最后确定到native层路径,截图如下:

总结:加载so、通过native关键字定义了需要调用的方法getSign,也就是说,它这里调用的是so层的加密算法,so是什么?简单来说,它是c/c++编译后的产物。context、bArr变量我们都已经知道明文信息,接下来,我们需要用ida打开so文件,去探索so层对该方法做了哪些加密操作吧。

四、ida动态注册分析

1、两个参数值确定了,下面要做的工作就是分析so层的加密算法获取sign值。我们通过压缩软件打开apk,因为我手机的cpu类型是arm64-v8a, 是向下兼容的,选择使用armeabi-v7a中的so文件是可以的。找到目标文件,使用ida打开后截图如下所示:

2、使用ctrl+F查找静态注册的指定方法名,结果无法搜寻到,这个时候可以肯定java调用的方法名在so文件中是动态注册的。找到JNI_Onload,点击该方法,使用F5打开该方法,截图如下所示:

3、点击v4后面的地址off_5004[0]进入指定代码块进行分析,截图如下所示:

总结:这个时候我们看到了java层的getSign方法和java层该方法的两个参数类型,接下来我们继续追踪分析so层是如何加密的。

4、点击sub_131c+1地址,然后按F5进入指定代码块,截图如下所示:

说明:这个地方会有签名校验,判断我们是否重新打包。如果为true,则直接返回0,否则执行下面的操作。

5、继续点击sub_1094地址方法,进入新的代码块,最新截图如下图所示:

总结:这个代码逻辑是拿我们在java native接口函数中传递的字符串与So中的字符串进行比较,然后给v8变量赋值,之后的加密逻辑会使用到v8变量。

6、点击sub_1B04地址进入到最新代码块区域,截图如下所示:

7、点击上图四个常量,然后点击按键H格式化常量值转为16进制,截图如下所示:

总结:看过md5源码的同学,应该对这个四个常量比较熟悉吧,这不就是A、B、C、D四个常量值吗?到这里,我们可以肯定,sign的加密算法就是md5加密;sign值的生成规则其实是指定参数拼接不同包名对应的salt进行md5加密即可。接下来,让我们进入算法还原环节吧!

五、算法还原 

1、sign参数算法还原如下:

import hashlib
def get_sign():
    salt = "PeCkE6Fu0B10Vm9BKfPfANwCUAn5POcs"
    data = f'X-UA=V=1&PN=xxx&VN_CODE=224003000&LOC=CN&LANG=zh_CN&CH=seo-baidu&UID=07e90f02-7def-4f28-a0b4-70098396e1df&NT=1&SR=1080x1794&DEB=Google&DEM=Pixel+2&OSV=10&action=active&android_id=84c16aaccd10a6e5&cpu=arm64-v8a&model=Pixel 2&name=Google&nonce=istb4&pn=0&push_id=6ce79a19f68c48779463dc893589c46c&screen=1080x1794&supplier=1&time=1671172755&uuid=07e90f02-7def-4f28-a0b4-70098396e1df&version=10{salt}'
    sign = hashlib.md5(data.encode(encoding='UTF-8')).hexdigest()
    print("e6a071ae2dc6cd117278b0f9d2fa04b1")
    print(sign)

pycharm终端输出如下:

总结:解决sign参数后,也就意味着str、str2参数我们能够获取到了,接下来我们对authorization参数mac做算法还原。

2、mac参数算法还原如下:

def get_mac():
    data = "1649340509\nhi9b4\nGET\n/landing/v5/timeline-with-device?action=refresh&X-UA=V%3D1%26PN%3D%26VN_CODE%3D224003000%26LOC%3DCN%26LANG%3Dzh_CN%26CH%3Dseo-baidu%26UID%3Dc2ff8daf-08ca-4e54-b051-6c5fde70bdda%26NT%3D1%26SR%3D1080x1794%26DEB%3DGoogle%26DEM%3DPixel%2B2%26OSV%3D10&show_channel_app=1\napi.xxxdada.com\n443\n\n"
    str2 = "d1e76439035449b521ea6c3d27aae758ef05ec65"
    mac = hash_hmac(data, str2)
    print("new--------")
    print(mac)
    print('ori--------')
    print("qrcn7ei6EBAPs/LkBO+undcifsk=")


def hash_hmac(code, key):
    hmac_code = hmac.new(key.encode(), code.encode(), sha1).digest()
    return base64.b64encode(hmac_code).decode()
 

pycharm终端输出如下:

总结:走到这里所有算法还原就结束了。我们只需要把分析的每个参数进行字符串拼接即可实现对authorization参数的生成!最后一步流程就省略了,结果已经很明朗了,感谢各位读者朋友阅读!


六、总结分享

回顾整个分析流程,本次难点主要概括为以下几点:

  • 如何快速定位加密参数的位置

  • 熟悉hmac sha1加密算法

  • 熟悉md5源码加密实现

  • 熟悉ida、jadx、frida使用

今天分享到这里就结束了,欢迎大家关注下期文章,我们不见不散⛽️

文章来源:逆向与爬虫的故事(公众号)

原文链接:某游戏社区App | So层逆向分析

微信搜:逆向与爬虫的故事;给我一个关注!

某flutter-app逆向分析是指对于一个使用flutter框架开发的应用进行逆向工程分析。逆向工程是通过分析应用的代码、二进制文件等来了解其内部实现细节。 首先,我们需要获取该应用的安装包文件(APK或IPA文件),然后进行解包操作,将其转换为可读取的文件目录结构。 接下来,我们可以使用一些工具来提取应用的资源文件、代码文件等。对于flutter-app来说,可以提取出dart文件,这是flutter的主要代码文件,其中包含了应用的逻辑实现。 通过阅读dart文件,我们可以了解应用的代码结构、数据模型、界面设计等。可以分析应用的逻辑实现方法,包括各种函数、类、方法的调用关系。 同时,还可以通过分析相关配置文件、资源文件等来了解应用的各种设置、资源加载方式等。 在逆向过程中,还可以使用一些调试工具来进一步了解应用的运行机制。例如,hook工具可以拦截应用的函数调用,并捕获输入输出数据,用于进一步分析。 逆向分析的目的可以有很多,比如了解应用的工作原理、发现潜在的漏洞或安全问题、提供参考用于自己的开发等。 需要注意的是,逆向分析需要遵守法律规定。未经授权的逆向分析可能侵犯他人的知识产权,涉及到隐私等方面的问题。因此,在进行逆向分析之前,应该了解并遵守当地相关法律法规,避免产生法律纠纷。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逆向与爬虫的故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值