环境
[ol]
[/ol]
工具
IDA、JADX、Frida、Charles、WireShark、x64dbg
逆向思路
总结:抓包 -> 分析数据包特征 -> 确定UDP/TCP -> HOOK 发包函数 -> 分析代码 -> 验证
流量抓包分析
经过抓取APP与摄像头之间通信的流量,发现以下几种固定特征流量。
magic: 3acf872a
经过反复抓包,发现同一个包有以下特征:
> 3a cf 87 2a 00 01 00 00 01 00 00 00
这12个字节固定不变,后面的数据在变。
不同包,同样的magic,对比后发现原先12个字节的中间四字节会变化。
如下:
同一个包的client和server包,对比后发现原先12个字节的中间四字节也会变化,其他部分相似度很高。如下:
最终发现,整个数据长度为0x11c,中间四字节为0x00000100,那么我们可以得出真实数据为magic往后20字节,其他字节含义未知。
magic: 20cf872a
这个数据包比较简单,整体固定不变,可能保活心跳之类的数据包。
通过对比,也可以发现前16个字节后的四字节为数据长度,而这个包数据似乎里面还嵌套这另外的数据结构。
三种特征数据都是通过UDP传输,接下来的思路就是Hook libc.so 的sendto函数,打印调用堆栈。
查壳、脱壳
未查到,那就先将APK拖进JADX里进行分析。
Frida Hook
撸起袖子就准备直接开干,Frida Server已启动,直接运行,HOOK libc.so的sendto函数,并打印堆栈。
加解密流程分析
经过回溯信息来看,相关函数都在libp2pc.so里面。这时候可以确定的是magic: 20cf872a为ACK,使用IDA打开该so,打开p2p_send_msg_by_udp函数,发现里面并没有加密相关函数,最终追溯追到下面这个函数就戛然而止了!!!
进入p2p_udt_send_msg函数中,也没有发现相关加解密函数,全部都在取数据,然后发送。
分析发现,所有操作基于多线程。到这断了思路。
代码翻来翻去,注意到了这个p2p_log函数,既然静态分析不行,那就看看log日志,了解整个流程,HOOK p2p_log函数后打印已知字符串,就可以得到一大堆log。
经过观察,字符串最前的应该是函数名,那么去p2p_conn_get_timer_retry函数看看。
里面也没啥重要函数,在看看p2p_make_c2m_q函数。
到这里,基本上有点头绪了,点进p2p_make_cmd函数看看。
最终找到了主体函数p2p_enc_cmd,在这个函数里面,进行了参数组装。
gP2P_pCmdTable里面是字符串表,如下:
里面字符大概有C2D_S、C2M_Q之类的
gP2P_pParaTable也是字符串表,如下:
里面字符大概有uid、sid之类的
数据结构上是一个xml结构,大概是下面这种:
\n....\n
通过交叉引用,发现了加解密的地方。
magic: 3acf872a数据
通过HOOK p2p_encrypt_and_decrypt和p2p_calc_crc函数后,发现这里就是magic: 3acf872a数据组装和加密的地方,至此该数据包结构解清晰了。
[table]
[tr]
[td]magic[/td]
[td]data size[/td]
[td]unknown[/td]
[td]transmission id[/td]
[td]checksum[/td]
[td]payload[/td]
[/tr]
[tr]
[td]3a cf 87 2a