吵吵   2016-03-21  阅读:1,201

学校更换了港湾认证之后,我一度以为新的安朗登录依旧是802.1x的扩充协议,只不过是更换了格式以及进行了加密。实际上当我们真正的去分析安朗的协议之后,才发现原来已经是UDP协议了。

UDP是一种并不能保证传输质量的网络通信协议,腾讯的QQ是基于此的,与TCP协议对比,虽然不安全,但是也节省资源,面对内网上万客户端的连接数据,安朗采用UDP协议也是明智之举。

接下来我们就要仔细分析安朗的协议了:

一、通讯参数。

全部都采用UDP协议,服务器端口是3848和3849,除了确认包(Confirm)是3849外,其它的数据都发送到3848。

二、数据加密。

我本来以为安朗会采用一个牛逼的加密算法来加密它传输的数据,这样子它的协议分析就更加我从下手了,但是显然安朗并没有这么去做,至于为什么加密数据的算法比较简单,我猜是服务器撑不住太高的运算了。

我们发送给安朗的包以及安朗发送给我们的包都需要进行加密,所以如果你纯粹是用wireshark去抓包分析协议的话,是徒劳的,因为抓到的数据都是一堆乱码,需要先解密成原来的明文,才能进一步分析。

加密的算法其实蛮简单的,都是位操作。

3848端口发送的数据加密和解密的算法是:

function encrypt (buffer) { for (var i = 0; i < buffer.length; i++) { buffer[i] = (buffer[i] & 0x80) >> 6
| (buffer[i] & 0x40) >> 4
| (buffer[i] & 0x20) >> 2
| (buffer[i] & 0x10) << 2 | (buffer[i] & 0x08) << 2 | (buffer[i] & 0x04) << 2 | (buffer[i] & 0x02) >> 1
| (buffer[i] & 0x01) << 7 } }function decrypt (buffer) { for (var i = 0; i < buffer.length; i++) { buffer[i] = (buffer[i] & 0x80) >> 7
| (buffer[i] & 0x40) >> 2
| (buffer[i] & 0x20) >> 2
| (buffer[i] & 0x10) >> 2
| (buffer[i] & 0x08) << 2 | (buffer[i] & 0x04) << 4 | (buffer[i] & 0x02) << 6 | (buffer[i] & 0x01) << 1 } } 3849端口发送的数据包(即confirm数据包)加密算法如下,考虑到其实这个包是登录成功后的确认包,你不发送也不影响整个认证,所以你基本可以忽略。 function encrypt (buffer) { for (var i = 0; i < buffer.length; i++) { buffer[i] = (buffer[i] & 0x80) >> 4
| (buffer[i] & 0x40) >> 1
| (buffer[i] & 0x20) << 1 | (buffer[i] & 0x10) >> 3
| (buffer[i] & 0x08) << 4 | (buffer[i] & 0x04) | (buffer[i] & 0x02) >> 1
| (buffer[i] & 0x01) << 4 } }function decrypt (buffer) { for (var i = 0; i < buffer.length; i++) { buffer[i] = (buffer[i] & 0x80) >> 4
| (buffer[i] & 0x40) >> 1
| (buffer[i] & 0x20) << 1 | (buffer[i] & 0x10) >> 4
| (buffer[i] & 0x08) << 4 | (buffer[i] & 0x04) | (buffer[i] & 0x02) << 3 | (buffer[i] & 0x01) << 1 } } 三、数据包结构。 好了,假设你把抓到的数据用以上的方法解密之后,得到了真正的数据包,那么安朗的数据包格式是这样子的: 数据包类型【1byte】+数据包长度【1byte】+MD5校验值【16byte】+(字段l类型【1byte】+字段长度【1byte】+内容【由字段长度决定】)*n+...... 可以发现,安朗的数据包不是固定长度的,可以无限的扩充(字段+字段长度+内容),只要紧跟着后面扩充就可以了。但是考虑数据包长度和字段长度都用一个字节(byte)表示,所以不可能超过255长度。 数据包类型数值对应关系如下: // login 登录包:将账号密码等信息发送给服务器,请求上线。 LOGIN = 0x01 // login result 登录返回包:服务器返回是否登录成功。 LOGIN_RET = 0x02 // breathe 呼吸包(心跳包):每隔30秒发送一个心跳包,告诉服务器我在线。 BREATHE = 0x03 // breathe result(心跳返回包):服务器告诉认证程序我已经成功收到你在线的消息。 BREATHE_RET = 0x04 // logout(下线包):向服务器请求下线。 LOGOUT = 0x05 // logout result(下线返回包):服务器告知是否下线成功。 LOGOUT_RET = 0x06 // get access point(认证方式包):向服务器获取认证方式。 ENTRIES = 0x07 // return access point(认证方式返回包):服务器返回认证方式。 ENTRIES_RET = 0x08 // disconnect(强制下线包):服务器发给客户端,强制客户端下线。 DISCONNECT = 0x09 // confirm login(确认包) CONFIRM = 0x0A // confirm login result(确认返回包) CONFIRM_RET = 0x0B // get server(获取服务器地址包):像1.1.1.8广播信息,获取服务器的地址。 SERVER = 0X0C // return server(获取服务器地址返回包):1.1.1.8告知客户端服务器地址。 SERVER_RET = 0x0D 数据包的类型搞清楚之后,就是字段的类型的对应关系了: // username 用户名 USERNAME = 0x01 // password 密码 PASSWORD = 0x02 // whether it is success 是否成功字段,包括认证成功,下线成功等。 SUCCESS = 0x03 // unknown, appears while login successfully UNKNOWN05 = 0x05 UNKNOWN06 = 0x06 // mac address MAC地址 MAC = 0x07 // session (NOTE: wrong in return packet) SESSION = 0x08 // ip address IP地址 IP = 0x09 // access point 认证方式 ENTRY = 0x0A // message (NOTE: wrong in return packet) 消息 MESSAGE = 0x0B // server ip address 服务器IP地址 SERVER = 0x0C // unknown, appears while received server ip address UNKNOWN0D = 0x0D // is dhcp enabled 是否启用DHCP DHCP = 0x0E // self-services website link WEBSITE = 0x13 // serial no 计数器 INDEX = 0x14 // version 版本 VERSION = 0x1F // unknown, appears while login successfully UNKNOWN20 = 0x20 UNKNOWN23 = 0x23 // disconnect reason REASON = 0x24 // 4 bytes blocks, send in breathe and logout BLOCK2A = 0x2A BLOCK2B = 0x2B BLOCK2C = 0x2C BLOCK2D = 0x2D BLOCK2E = 0x2E BLOCK2F = 0x2F // unknown 4 bytes blocks, appears while confirmed BLOCK30 = 0x30 BLOCK31 = 0x31 // unknown UNKOWN32 = 0x32 // 4 bytes blocks, appears while login successfully BLOCK34 = 0x34 BLOCK35 = 0x35 BLOCK36 = 0x36 BLOCK37 = 0x37 BLOCK38 = 0x38 可以看出,字段中的有些值,并没有搞清楚是做什么用的,但是也不妨碍我们继续使用就是。 四、MD5校验。 我们从上文看到的字节2-18是MD5校验值,这个校验值是怎么产生的? 1、先将2-18字节置为0x00。 2、填充好包里面需要的字段。 3、将整个包进行MD5加密计算,得到md5值填充到2-18字节中去。 4、对整个包进行加密,然后发送。 以上的协议分析内容来自https://github.com/xingrz/swiftz-protocal。有兴趣可以自己去看看,明天接着讲认证流程以及如何编程实现。

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

发表评论

电子邮件地址不会被公开。 必填项已用*标注