某音国际版抓包实践
前言
某音国际版(以下简写为TT)中使用了自定义的SSL框架,提高抓包的成本。如xp框架JustTrustMe、frida框架r0capture等均会失效。原因在于这些模块针对的是系统原生的SSL框架,而TT自定义了自己的SSL框架。那么如果我们需要对TT进行抓包的话,就需要对TT的检测动手脚,本文章会举例两种方式进行TT(Android)的网络请求获取。(网上都有相关教程,文章仅为自己实践记录)
TT版本为全球版(packageName:com.zhiliaoapp.musically version:25.0.3)。
方式一:通过修改so包跳过SSL检测
常见的抓包方式大多数是使用Fiddler、Charles等工具,本文使用Fiddler进行抓包操作,电脑系统Window 10。
Fiddler的安装及Https抓包配置就不赘述了,自行网上查找相关文章。这里需要注意一点,Android 7+的版本,系统将不信任用户证书,正常通过Fiddler下载安装的证书依旧无法抓包HTTPS。这时需要一台root后的手机,将Fiddler的证书转换为系统证书并安装到手机内。
Fiddler系统证书具体操作
1、点击Fiddler的Tools选择Options,弹窗的选项卡中选择HTTPS,点击右侧Actions选择Export Root Certificate to Desktop将Fiddler证书导出桌面,
2、打开cmd,通过openssl命令获取到Fiddler证书的hash值。
openssl x509 -inform DER -subject_hash_old -in FiddlerRoot.cer

3、将导出的证书重命名,格式为:获取到的hash值.0,如我获取到的hash值为e5c3944b,那么我的证书名字命名为e5c3944b.0。
4、将重命名后的文件放置到手机的/system/etc/security/cacerts/路径下即可。
以上操作完成后,正常抓包HTTPS已经可以了。
修改so包
TT防止抓包主要通过自定义SSL校验来实现,那么我们只要将TT检验的最终结果修改成校验通过就可以正常的抓包。以下操作参考文章《[原创] 听说最新版的某音大家都抓不到包,给大家一个方案》。
根据以上文章可以知道TT的自定义SSL校验在一个叫libsscronet.so的so包里,那我们就将TT的apk包重命名为zip,然后解压。解压后得到很多文件,点击lib目录,再点击对应的abi目录,可以找到这个so包。

获取到so包后需要在so包内找到TT最终校验的结果,通过IDA打开so包查找(多图预警)。
1、通过IDA打开

2、点击菜单栏 -> View -> Open subviews -> Strings

3、搜索关键词(Ctrl + F) verifycert

4、点击搜索结果

5、如上图点击sub_1A1B9C函数

6、点击键盘F5转成伪C代码

根据以上文章可以知道当so包return 0的时候就表示校验成功,那么我们只需要把图中的return 1修改为0即可。往下拉到最后有一个sub_1A2210的函数内还有两个返回结果需要修改自行查找。
7、鼠标选中这个1,然后点击菜单栏 -> View -> Open subviews -> Hex dump

这里面的01 20就是返回的那个1。
8、找到对应要修改的地址之后,就可以对so包进行修改了,我使用的工具是Hex_Editor,010Editor也都可以。
打开Hex_Editor并加载libsscronet.so

通过地址001A1C60找到对应的位置直接修改

修改完成后点击左上角保存,这样就算是修改完成了。
这时我们重新用IDA打开libsscronet.so后,可以看到值已经修改为0了

剩下的两个返回结果都在sub_1A2210函数中,根据以上方式修改即可。
9、so包修改完成之后,将手机中的/data/app/com.zhiliaoapp.musically-bhvw6FKsbL40BdQiFJ_kGg==/lib/arm/libsscronet.so替换为新的so包即可(app目录下的文件名认准包名即可)。
10、替换成功后,将手机设置好代理打开TT,即可看到抓包信息

通过以上方式可以抓到大部分TT的接口。不过在抓包过程中发现有部分接口如登录接口,抓包数据都可以获取到,但是请求结果都是失败,无法成功登录账号。这就导致无法通过这个方式抓包获取到登录成功后的数据。
这时候就需要使用我们的第二种方式,通过Hook进行请求数据的获取
方式二:Hook TT
在通过jadx反编译时发现TT使用的网络请求框架是Retrofit,熟悉的朋友都知道Retrofit底层使用依旧是Okhttp,那么我们Hook的切入点可以从拦截器或者初始化时传入的OkClient入手。
1、首先需要安装Hook的环境,本文使用frida进行Hook,代码逻辑基本上差不多,看个人意愿也可使用xposed。frida的安装可自行搜索教程。
注:若出现frida.ServerNotRunningError: unable to connect to remote frida-server问题可打开命令行输入adb forward tcp:27042 tcp:27042
2、通过反编译确认了TT初始化Retrofit的位置是com.bytedance.ies.ugc.aweme.network.RetrofitFactory。

此处可看到有一个代码初始化了OkClient,而下方的C25210xZ猜测为自定义的OkClient。
经过对这个类多次代码逻辑梳理及Hook,找到了X.MBJ的类,该类中的LIZ方法的返回值c内有请求的所有数据,猜测可能是response。

3、接下来就是编写Hook的代码
python
import frida, sys
import time
def on_message(message, data):
if message['type'] == 'send':
print("[*] {0}".format(message['payload']))
else:
print(message)
device = frida.get_remote_device()
pid = device.spawn(["com.zhiliaoapp.musically"])
device.resume(pid)
time.sleep(1)
process = device.attach(pid)
f = open('hook.js','r',encoding='utf-8')
script = process.create_script(f.read())
script.on('message', on_message)
print('[*] Running CTF')
script.load()
sys.stdin.read()
js
Java.perform(function() {
var gson = Java.use('com.google.gson.Gson');
var gson1 = gson.$new();
var clz = Java.use('X.MBJ')
clz.LIZ.overload().implementation = function() {
var result = this.LIZ()
var json = gson1.LIZIZ(result)
var jobj = JSON.parse(json)
if (jobj.LIZ.indexOf('service/2/app_log') != -1) {
console.log('**********************INTERFACE**********************');
console.log('url -> ' + jobj.LIZ)
console.log('')
console.log('request.headers ->', jobj.LJFF.LJJIII)
console.log('')
console.log('response.data -> ', String.fromCharCode.apply(String, jobj.LJ.bytes))
console.log('')
console.log('response.headers ->', jobj.LJFF.LJJIIJ)
console.log('**************************END************************');
}
return result
}
}
编写完成后,就可以运行了,结果如下:

该方式获取的请求头中无法找到加密参数,有兴趣的朋友可自行继续查找。
结尾
这两种方式理论适用所有TT版本,区别在于不同版本路径、代码位置有区别。
以上内容仅学习实践,若有什么问题,请及时联系我
转载自:https://juejin.cn/post/7122723176387346469