个人兴趣学习,不负法律责任
本例纯属学习和科研参考,请勿用在商务用途(使用淘宝开放平台的api吧~~by凉 白开QQ)。
前言:
帮朋友的过程中,突然想到一个像淘宝这样安全性这么强的互联网企业(额,不太好定义这个帝国先这么叫着),是怎样的一个机制保证了这样的口碑呢?所以就用自己的方式进行抓包,然后自己hack一下,纯粹烧时间和游戏~~性质的。
之后发现,和淘宝软件相关的软件平台和客户端之间通信的机制比较复杂,从抓的包来看,起码有4~5种,还不清楚不同端口链接之间是否有逻辑关系。有些从包的内容大致可以看出哪些是控件api通信,哪些是gui-remote通信,不过怎么解码可难倒我了(估计得话大工夫)。所以找到了最简单的fmsas(服务器端口为16000)端口(用户间通信)的作用。
经过昨天一中午和今天一上午的调试,终于把淘宝千牛客户端与服务器最简单的fmsas端口的连接协议给搞明白了。
使用工具:
千牛
WireShark
winCap
UltralEdit
C# (有现成的库,编写快,主要是调试,所以不用C++了)
目标:
通过网络抓包手段分析网络端口以及时序。
过程:
客户端和服务器之间某些固定端口链接的时序。
1. DNS (这个是小菜,最最简单的,和淘宝没太大关系)
客户端 DNS服务器
DNS查询申请—> 处理
处理 <— 返回DNS结果
说明
第一步:客户端向DNS服务器查询gw.api.taobao.com
第二部:客户端接收关于淘宝的一系列网域网段端口内容:
包内主要内容:
quries :是你请求的DNS位置
Answers:返回了位置,ip4的adr。
另外还有几个服务器的域名位置:
split.taobao.com
gwns.taobao.com
splitns1~5.taobao.com
等等
2. TCP (从fmsas <——> 客户端口分析)
TCP的连接比较复杂,因为例子要求的是客户端之间通信的消息响应(就是有消息传来就反应)
因此但从客户端和服务器端的fmsas端口的连接时序进行分析
发现:
1. 起先是数据包,注意wireShark 的一个功能特性。图中 seq 和Ack不是其真实值,而是软件自身的定义的。
通过比对完整网络包,这个协议不太像是课本上标准的TCP,
一般来说本次包和下次包的seq和Ack应该是+1关系,而这个却是相等关系,本次Ack为随机值
图1. 接收1unicode
图2.接收3unicode
图3. 接收1unicode
图4. 发送
2. 调试
经过几次测试发现,
握手阶段的发送端第一个 PSH ACK的消息seq number 为任意(至少比较随意),Ackno number 为 0(任意值)
因此,这个例子应该从第二次开始,分析包的顺序码和确认码,从而获得一次数据的传输,发送消息。
使用c#编写,代码不附了。
伪代码+讲解
使用的类为 PackCap(到codeForge上下载吧)
之后使用的类为:
WinCapHelper 借鉴的前人的一个类,网上可以自己查看。
重写的public Action<string> _logAction = delegate(string x)函数,对string x
判断协议
Proctocl == 0x06 (TCP),
判断端口
查找Server port == 16000 (fmsas)
注意客户端是我们每次使用软件时系统自动分配的,所以这里就不用确定了。
客户端接收
fmsas(服务器发送) client port(客户端接收)
握手
PSH ACK ——> 接收
接收 < —— ACK
PSH ACK ——> 接收
。。。。。。
传输 两者PSH ACK包的交互
。。。。。。
挥手
ACK ——> 接收
PSH ACK ——> 接收
接收(结束) <—— ACK
客户端发送
fmsas(服务器发送) client port(客户端接收)
握手
PSH ACK <—— 接收
接收 ——> ACK
PSH ACK <—— 接收
。。。。。。
传输 两者PSH ACK包的交互
。。。。。。
挥手
ACK ——> 接收
PSH ACK ——> 接收
接收(结束) <—— ACK
当我们在千牛上点击一次“发送”或者收到对方消息时,都会发生一次fmsas端口的通信。
分三步
握手(传输开始)
数据传输
挥手(传输结束)
握手阶段第一次的PSH ACK由数据的发送方开始,之后是一次对方一次ACK,之后进入数据传输。
当然这是理想状态,当双方并不是马上应答或者发送数据量不一样的时候,会有一定的不同,
从图1到图3中,同样是接收数据,其过程不太一样。
数据传输阶段并没有发现什么规律,只是PSH ACK 的方式,因为是尽快传递到软件的API中去。也符合功能的要求~~
挥手阶段,每次过程都是由服务器端发起。连续发送ACK 和PSH ACK包,表示传输结束。客户端接收到之后,表示结束,回发一个ACK。
注意:这个和一般书上的TCP传输有些不一样的地方。
两个包之间的ack number 和seq number 并不是+1的关系,
而是上一个包的Ack number = 这个下个包的seq number ,而下个包的seq number 是随机数~~。
所以,
最后挥手的ACK和PSH ACK的中的seq number 和ack number都是一致的(这个不难理解)。服务器最后发送的ACK的seq number为PSH ACK的ack number,而ack number为随机数。
测试库:
C#的 PacketCap(国外一个本科毕业生写的,人家这水平。。。。,基于winCap,在Code Forge上自己找)
软件库:
照搬国内一位前人写的winCapHelper的类,
重写了其中的device_OnPacketArrival方法(就是析包)。。。。
实现了判断挥手、握手方法~~
实现对有消息接收和发出时的判断。。。。
嗯,其他的端口还需要分析一下,之后是端口间的联系。。。任重道远