第一步,开启wireshark抓包。一般直播平台,登录是HTTP协yi,而用户行为包括送花,发言等则是webSocket协yi,在充分利用资源的同时,提高了效率。在对这个直播平台抓包的过程中,只发现了登录的HTTP数据包,而并未发现送花、发言的webSocket数据包。但是发现了一个swf文件。猜想可能是利用flash文件,通过tcp协yi进行传输。
下载swf文件。载入到JPEXS中进行分析。因为逆向出来的资源没办法直接导入flash中进行调试。所以下文仅涉及到静态分析,对于动态部分,若有人精通,请与我联系。
首先,在js中寻找相关函数,没有什么大的发现,跟踪调试也比较麻烦,不如先直接通览逆向出来的swf文件。打开swf文件,发现目录说明较为齐全,代码也并未经过混淆,这带来了一个好的开始。
着重关注脚本这一目标。
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/638d246322834bc58aaf17b3c2fa4018/tof4%5D3_e7aoh.png
首先在SPlayer中,进行了初始化,而SPlayer又是继承自simplemvc.view.SpriteView。跟进未发现有用信息。我们查看其他目录,在ggcj.player.service.SingleService中发现了几个可能有用的函数,首先是getCasListFromUrl函数。这个函数进行了HTTP请求获取服务器IP地址和端口,接着startConnectCAS函数便尝试连接获取到的第一个IP,连接成功则进行socketProxyConnectHandler,该函数调用了S1039函数,而S1039函数则携带用户信息进行了认证。在ggcj.player.service.SingleService中还发现了一些以P和S开头命名的函数,通过分析,P开头的函数,是flash推送给JS的消息,而S开头的函数则是JS推送给flash的消息。
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/489fc5863e494387abb1f2d01b794126/s_sxwn3_%5Dzss.png
此外,还发现了jsCallFla及flaCallJs函数。这两个函数分别是js调用flash及flash调用js的函数。以jsCallFlash函数为例进行说明。
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/7359e140e0df40c79a16f10630db17b2/%29bfb7jk%7Bizxs.png
从代码中可以看到,一共实现了八个接口,那么在js中,也肯定有八个方法与其对应,这个随后进行分析。以发送消息即sendMessage为例进行分析,跟进sendMessage函数,
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/9129f2a200f842d8a20a87969978a5fb/cxr%7D6%5D1%7D4a3q.png
发现最后调用了S1007函数,继续跟进S1007,具体的代码便出来了:
file:///C:\Users\ZMoffice\AppData\Roaming\Tencent\Users\244036962\TIM\WinTemp\RichOle\%2591%7D1ZHKWNFVF3SK%40)%5BVUF7.png
这种传输协yi让我想起了QQ的传输协yi,很是类似。看到这儿便理解了S1007这个函数名,1007具体是代表了命令号。首先,设定_loc8这个字节数组的字节排序方式为小端排序。简单普及一下小端排序,即低位在前,高位在后。以十六进制0x12345678为例。大端排序,结果即为0x12345678,小端排序,结果则为0x78563412。接着呢,写入了一个短整数1007,而这个1007,正是函数名中S1007所涉及到的。服务器收到客户Duan的消息,首先判断开头代码是多少,是1007,即认为该条消息为发送信息的消息。具体其他分析添加在了注释里面。数据包封装完成之后,被传送到了下一步,即socketProxy.sendBytes函数,进入socketProxy.sendBytes函数,该函数调用encode函数完成了包头的添加,数据的拼装及加密的任务:
file:///C:\Users\ZMoffice\AppData\Roaming\Tencent\Users\244036962\TIM\WinTemp\RichOle\8SV%7DO01%5DR%7D2AYK8%5D3(_%60C%5DU.png
通过对encode函数分析,发现数据包头都是由03020101220001开头,以060504结尾。中间则写入了是否加密,内容长度,短整数型0以及内容(也可能是加密过的内容,从encode函数开头可以看到,加密方式为AES加密,模式为ECB,NoPadding,密钥为:66CBC149-A49F-48F9-B17A-6A3EA9B4)。抓包也同样验证了这一点:
file:///C:\Users\ZMoffice\AppData\Roaming\Tencent\Users\244036962\TIM\WinTemp\RichOle\%7BL~5K%5DB1Q4TRQ36T%5D2M1%25D4.png
到这儿,该swf文件分析已经比较深入了。在重构代码的时候,发现自己手头的AES算法与该文件中采用的AES有出入,因为对算法研究不是很深入。便放弃了自己重新写用户各种功能。如果可以直接调用flash文件,代码构建起来应该会很简单。
有了这个想法,便想到了ShockwaveFlash对象。利用这个可以实现对flash函数的调用。想要调用ShockwaveFlash中的各种方法,我们首先需要明白,js调用flash,只能传递字符串。因此,在js端,肯定有函数负责将传递的信息编码为xml格式,然后调用flash。到这一步,需要深入去分析js文件了。在送花sendFlower函数下断点,在步入的过程中,发现了许多有用的信息。首先是各个接口:
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/c913c9e1ce2d4f87b255f6777f3ddc03/%5Dwz9%7B%5Dsnk%5B%24%5B41w%25%7D3bd54b.png
在js中同样发现了jsCallFla及flaCallJs函数,与flash文件相交互的接口:
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/e8934e9c62ba4620a83d3e315fa9eaf7/2z5%5B4z%7Bwcoz%253%7Eweprq%5B_ib.png
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/375d4cdc50204f1cadf98876bd6c8618/r5aw6%60vah0x8%5D%28226ya7%7Ec5.png
最后跟踪到了
file:///C:/Users/ZMoffice/AppData/Local/YNote/data/qqDA089A461B3E834A10A1D73EE2EC3604/5a7fb0e7d898438b84b2e1807c5571e4/ghkfha0iu%5D%247i%28cexfg%25b5j.png
VM2144这个文件里面,就实现了对参数的xml格式化以及传递工作。
最后请求的例程如下:
<invoke name="jsCallFla" returntype="javascript"><arguments><string>OperateOtherUser</string><array><property id="0"><string>10754665956</string></property><property id="1"><number>5</number></property><property id="2"><number>10</number></property></array></arguments></invoke>
可以看到首先定义了接口的名字是jsCallFla,返回类型是js。接着说明了调用方法为OperateOtherUser,后面array即为参数。
分析到这儿,整个的流程便完毕了。
也就可以调用接口进行数据处理
发表评论: