简介:本次分析抖音版本:14.4X-gorgon版本:0404可以测试以下反钩记录来自抖音11.30401,新版本的hook与之前类似通信会涉及一个名为x-gorgon的签名,这是发送数据请求必不可少的参数。这次就带大家分析一下这个参数。小编自恋,逆向高手属于逆向爱好者,如需交流技术或算法,请在评论区留下邮箱,或联系我1610199291@qq.com抢包假设我们的业务需要爬虫获取抖音的热点视频列表,那么我们首先通过抓包定位到具体的接口。这里我选择使用charles工具抓包。具体的https方式可以自行百度配置。抓包最好使用6.0以下的安卓手机!通过抓包发现接口来自:https://aweme.snssdk.com/aweme/v2/feed/后面跟着一个很长的参数,具体字面分析估计是手机的型号和一些抖音信息生成的,我们发现它返回的是protobuf格式,Charles已经帮我们解析过了,所以我们写了一个python3脚本构造一个请求像他一样尝试。我们发现数据是可以正常返回的,但是我们看到他的headers除了x-gorgon和x-tt-trace-id之外都很好理解。我们会发现,如果我们更改了url的参数,但是如果header内容不能相应修改,则不会返回任何数据,如下图:{status_code:2154,aweme_list:[],has_more:1,min_cursor:0,max_cursor:0}分析那么我们就可以更加确定header里面的x-gorgon给它签过一次了,于是直接去jadx看了一波反编译代码。这里我直接搜索了x-gorgon关键字,列出了如下结果:这里我选择了hashMap。put("X-Gorgon",a3);这一行,跳进去分析一下它的代码这里我们看到有一个,它的值来自于a3,a3是通过Stringa3=a.a(com.ss.sys.ces.a.leviathan(i,currentTimeMillis,a.a(a2+str4+str5+str6)));这行代码得到的结果,我们看到它传递了4个参数,我们仔细看看这4个参数的具体内容是什么:a2的来源:Stringb2=tt.d(str);d.a(b2);str是这个方法传入的参数,后面我们可以通过hook方法获取它的具体内容,它会执行tt.d(),d.a()两次操作,我们跟进它的tt.d()我们看到它取了这个字符串的中间值了吗?而#,怀疑是url,如果url证明它只接受url后面的参数,那么继续看它的下一个方法:d.2parametersstr4source:这里很简单,就是枚举传入的第二个参数map,如果有X-SS-STUB的值就获取,否则补32个0,然后我们抓包发现没有X-SS-STUB参数。事实上,如果我们的包是POST,它就会有。其实就是POST数据的一部分。一个MD5签名值str5source:str5也很简单,同样是枚举map中是否有COOKIE,如果有,则COOKIE是MD5ed的,那么参数就在这边str6source:12345Stringc2=tt。e(str3);if(c2!=null&&c2.length()>0`){`str6=d.a(c2);StcSDKFactory.getInstance().setSession(c2);}这里我们记得str3是一个cookie,它执行tt。e(str3)方法获取返回值。如果不为空,它也给了返回值md5,那我们跟进看看它做了什么:这里我们看到它枚举了cookie中是否有sessionid的值,如果有,取出来,然后str6到此结束参数排列:a2=md5(url)疑似对urlstr4=x-ss-stub的参数进行md5,只有发帖时有效,否则为320sstr5=md5(cookie)md5thecookiestr6=md5(cookie['sessionid'])md5cookie中的sessionid,否则有32个0我们把这4个参数整理出来后继续分析,它会合并字符串,然后执行a.a(a2+str4+str5+str6),我们跟进看看里面都做了哪些操作我们看到它循环了总长度/2次,每次str[i]转为十进制左移4,然后添加str[i+1]是一个简单的操作,返回结果,原本是4个32位(128位),加密后缩短为64位长度。最后,它执行com.ss.sys.ces.a.leviathan(i,currentTimeMillis,a.a(a2+str4+str5+str6))进行计算,我们看到它还传递了2个参数,i和currentTimeMillis,我们期待,可以看到i是-1,currentTimeMillis是当前的十位时间戳。最后将计算出来的byteArray转成string类型放入map中。然后我们可以清楚的看到k-khronos刚到currentTimeMillis时间戳。我们发现因为om.ss.sys.ces.a.leviathan在libcms.so文件的so层,里面有很多混淆,所以我们没有再分析。我们可以通过xposed或者unidbg调用方法。0x02:Parameterconfirmation到这里我们分析了它的算法,完成了具体参数的构造,我们还需要确认传递给它的参数是不是我们想的,所以这里发现因为它的方法是回调,所以我们跟进,找一个合适的hook点,使用frida来hook这里我调用搜索了一下,看到只有一个地方,我们跟进看看,跟进后就是下面的内容,就是简单的pair分配给sAddSecurityFactorProcessCallback,我们正在调用它以查看它被调用的位置。publicstaticvoidsetAddSecurityFactorProcessCallback(aaVar){sAddSecurityFactorProcessCallback=aVar;}这里我们看到它从这里获取到的回调指针变量,然后判断不为null来执行,那么我们可以直接hook这个方法:tryAddSecurityFactor$___twin___,这里我的hook代码比较简单,直接输出值传入的map和str以及返回的map进行确认。//frida-Ucom.ss.android.ugc.aweme-ltest.jsJava.perform(function(){varNetworkParams=Java.use("com.bytedance.frameworks.baselib.network.http.NetworkParams");NetworkParams['tryAddSecurityFactor$___twin___'].implementation=function(str,map){varkeyset=map.keySet();varit=keyset.iterator();console.log("str:t"+str)while(it.hasNext()){varkeystr=it.next().toString();varvaluestr=map.get(keystr).toString()console.log("map:t"+keystr+"t"+valuestr)}varretret=this.tryAddSecurityFactor$___twin___(str,map);varkeyset=ret.keySet();varit=keyset.iterator();while(it.hasNext()){varkeystr=it.next().toString();varvaluestr=ret.get(keystr).toString()console.log("retmap:t"+keystr+"t"+valuestr)}returnret;}});绿色部分是str为参数1的值,黄色是地图,蓝色是返回的地图。我们看看Charles包头中的xgorgon是不是返回值。总结以上就是抖音对一个简单的x-gorgon的分析和笔记过程。希望对大家有所帮助,也可以作为自己产品安全的参考。免责声明:请勿将此服务用于商业目的。请勿使用此服务大量抢购。如因使用本服务与抖音官方引起不必要的纠纷,本人纯技术爱好概不负责。有意者请告知2021-01-12
