与校园网斗智斗勇(三)之制作第三方安朗客户端

前言

  贪欲是人类与生俱来的陋习,但正是因为有贪欲,人类才能进步,“贪”才是我们探索精神的领袖。
  在前两篇博文中,博主对安朗(安腾)宽带认证客户端(以下统称蝴蝶)进行了简单的爆破,达到了无障碍使用共享Wifi软件的目的,并且分析和试译了Swiftz协议(以下统称蝴蝶协议),但这并不能满足博主的贪欲,所以这一篇记录了博主如何从零制作一个属于自己的蝴蝶

准备

说明

  在你开始看这一篇博文之前,请务必看懂蝴蝶协议,并在动手制作之间实时查阅,这会让你的编程效率大大提高。
  根据蝴蝶协议的分析,整个蝴蝶客户端,我们需要实现的是四个主要功能:搜索、上线、呼吸、下线。

  • 搜索:构建搜索包,发送搜索包从本机IP:38481.1.1.8:3850,接收返回包。
  • 上线:构建上线包,发送上线包从本机IP:3848服务器IP:3848,接收返回包。
  • 呼吸:构建呼吸包,循环发送呼吸包从本机IP:3848服务器IP:3848(间隔30秒),循环接收返回包。
  • 下线:构建下线包,发送下线包从本机IP:3848服务器IP:3848,接收返回包。

实现

  重点提一下构建数据包,以构建搜索服务器的数据包为例(构建上线、呼吸、下线数据包大同小异),至于发送接收数据包则非常简单,利用Socket发报收报即可,但要注意是基于UDP协议的。
  另外,在发送和接收之前,需要加密和解密数据包。即:

  构建数据包——加密数据包——发送数据包——接收数据包——解密数据包

  构建搜索服务器数据包部分示例代码:

  • [C语言]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void search_server(int sockfd,struct infoset * const pinfo){
char md5[0x10] = {0x0};
int md5len = 0x10;
char *pkt, *ppkt, *tmphost;
struct usrinfoSet *psu = pinfo -> psu;
struct sockaddr_in *pss = pinfo -> pss;
int sendbytes = 51;

int iplen = strlen(psu -> local_ip), maclen = 0x6;
pkt = (char *)calloc(sendbytes, sizeof(char));
ppkt = pkt;
*ppkt++ = 0x0c;
*ppkt++ = sendbytes;
ppkt += 0x10;

*ppkt++ = 0x08;
*ppkt++ = 0x07;
*ppkt++ = 0x00;
*ppkt++ = 0x01;
*ppkt++ = 0x02;
*ppkt++ = 0x03;
*ppkt++ = 0x04;
……
……
……
  • [Python语言]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def search_server_ip(ip, mac):
packet = []
packet.append(0x0c)
packet_len = 1 + 1 + 16 + 1 + 1 + 5 + 1 + 1 + 16 + 1 + 1 + 6
packet.append(packet_len)
packet.extend([i * 0 for i in range(16)])
packet.append(0x08)
packet.append(0x07)
packet.extend([i * 1 for i in range(5)])
packet.append(0x09)
packet.append(0x12)
packet.extend([ord(i) for i in ip])
packet.extend([i * 0 for i in range(16 - len(ip))])
packet.append(0x07)
……
……
……
  • [Java语言]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private void searchServerIp() {
byte packet_len = 1 + 1 + 16 + 1 + 1 + 5 + 1 + 1 + 16 + 1 + 1 + 6;
byte[] packet = new byte[packet_len];
byte i = -1;
packet[++i] = 0x0c;
packet[++i] = packet_len;
for (; i < 17;) {
packet[++i] = 0;
}
packet[++i] = 0x08;
packet[++i] = 0x07;
for (byte j = 0; j < 5; j++) {
packet[++i] = j;
}
packet[++i] = 0x09;
packet[++i] = 0x12;
byte[] bytes = LOCAL_IP.getBytes();
for (byte b : bytes) {
packet[++i] = b;
}
for (int j = 0; j < 16 - bytes.length; j++) {
packet[++i] = 0;
}
packet[++i] = 0x07;
packet[++i] = 0x08;
……
……
……
  • [C#语言]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class SearchSend
{
public byte[] SessionBytes;
public string IP;
public string Mac;
public SearchSend(string ip, string mac)
{
IP = ip;
Mac = mac;
SessionBytes = new byte[5]
{
0,1,2,3,4
};
}
public byte[] ToBytes()
{
int offset = 0;
int iLen = 51;
byte[] bts = new byte[iLen];
bts[offset] = 0x0C;
offset++;
bts[offset] = 51;
for (int i = 1; i < 16; i++)
{
bts[++offset] = 0;
}
offset++;
offset++;
bts[offset] = 8;
……
……
……

抓包

  在构建数据包完成后,我们需要利用抓包工具来测试我们构建的数据包是否正确、发送和接收数据包是否正常,而Wireshark这款工具是一个不错的选择。

1.jpg

  我们主要检查的是包的长度、收发端口、以及最重要的Data

2.jpg

  抓包之前,我们要利用蝴蝶协议中提到的3848端口解密算法额外写一个解密程序,用来打印数据包被解密后的数据,以便我们能够更直观地检查。下图以上线数据包为例:

3.jpg

后记

  在编写过程中,一定会遇到许许多多的问题(大神忽略),路漫漫其修远兮,你要上下而求索,要时刻铭记。因为在你想要放弃的时候,其实距离终点只有一步之遥。
  下面说一下当初编写这个程序博主的一些经验:

  • 登录确认包可以完全省略。
  • 如果你想节省时间,其实搜索包也可以省略,学校不会频繁更换服务类型和服务器IP地址,记下来填上即可。
  • 服务器是固定三个端口384838493850,但是本地端口是随机的话也能正常认证,绑定同样的端口是为了防止多个认证客户端同时工作,这可能会造成一些错误。
  • 上线包和下线包只发送一次,可以容许一点瑕疵,只要能成功接收到服务器返回的数据包,提取到需要的内容就行。
  • 呼吸包的构建必须完全正确,因为是循环地发送和接收,其过程必须稳定,这关系到你能否顺畅地使用校园网,在调试过程中可以拿学校官方的蝴蝶数据进行比对查错。
  • 呼吸包发送间隔是30秒,也可以小于30秒,如果呼吸包不稳定可以尝试适当调整。
  • 在构建数据包之前要把需要填充的数据整理打包好,例如类型的转换,以及空字符的处理等等,以减少不必要的程序异常。
  • 编写这个程序很简单,但是错误处理和代码优化有点繁琐,将自己当成使用者,并不断测试程序的极限状态,你会发现bug比你头发还多(当然,其根本原因还是博主学艺不精)。

  完成程序后,还可以考虑增加一点自己常用的功能,例如集成无线热点,增加NAT穿透等等……

  成品效果图:

4.jpg

-------------本文结束❤感谢阅读-------------

本文标题:与校园网斗智斗勇(三)之制作第三方安朗客户端

文章作者:三水非冰

发布时间:2018年05月06日

最后更新:2018年05月06日

原始链接:https://www.sanshuifeibing.cn/posts/2925d687.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

如果觉得我的文章对您有用,请随意打赏,您的支持将鼓励我继续创作。