某音国际版抓包实践
前言
某音国际版(以下简写为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