前言
贪欲是人类与生俱来的陋习,但正是因为有贪欲,人类才能进步,“贪”才是我们探索精神的领袖。
在前两篇博文中,我对安朗(安腾)宽带认证客户端
(以下统称蝴蝶)进行了简单的爆破,达到了无障碍使用共享Wifi软件的目的,并且分析和试译了Swiftz协议
(以下统称蝴蝶协议),但这并不能满足我的贪欲,所以这一篇记录了我如何从零制作一个属于自己的蝴蝶
。
准备
说明
在你开始看这一篇博文之前,请务必看懂蝴蝶协议,并在动手制作之间实时查阅,这会让你的编程效率大大提高。
根据蝴蝶协议的分析,整个蝴蝶客户端,我们需要实现的是四个主要功能:搜索、上线、心跳、下线。
- 搜索:构建搜索包,发送搜索包从
本机IP:3848
至1.1.1.8:3850
,接收返回包。 - 上线:构建上线包,发送上线包从
本机IP:3848
至服务器IP:3848
,接收返回包。 - 心跳:构建心跳包,循环发送心跳包从
本机IP:3848
至服务器IP:3848
(间隔30秒),循环接收返回包。 - 下线:构建下线包,发送下线包从
本机IP:3848
至服务器IP:3848
,接收返回包。
实现
重点提一下构建数据包,以构建搜索服务器的数据包为例(构建上线、心跳、下线数据包大同小异),至于发送和接收数据包则非常简单,利用Socket
发报收报即可,但要注意是基于UDP
协议的。
另外,在发送和接收之前,需要加密和解密数据包。即:
构建数据包——加密数据包——发送数据包——接收数据包——解密数据包
构建搜索服务器数据包部分示例代码:
- [C]
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]
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]
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#]
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
这款工具是一个不错的选择。
我们主要检查的是包的长度、收发端口、以及最重要的Data
。
抓包之前,我们要利用蝴蝶协议中提到的3848端口解密算法
额外写一个解密程序,用来打印数据包被解密后的数据,以便我们能够更直观地检查。下图以上线数据包为例:
后记
在编写过程中,一定会遇到许许多多的问题(大神忽略),路漫漫其修远兮,你要上下而求索,要时刻铭记。因为在你想要放弃的时候,其实距离终点只有一步之遥。
下面说一下当初编写这个程序我的一些经验:
- 登录确认包可以完全省略。
- 如果你想节省时间,其实搜索包也可以省略,学校不会频繁更换服务类型和服务器IP地址,记下来填上即可。
- 服务器是固定三个端口
3848
、3849
、3850
,但是本地端口是随机的话也能正常认证,绑定同样的端口是为了防止多个认证客户端同时工作,这可能会造成一些错误。 - 上线包和下线包只发送一次,可以容许一点瑕疵,只要能成功接收到服务器返回的数据包,提取到需要的内容就行。
- 心跳包的构建必须完全正确,因为是循环地发送和接收,其过程必须稳定,这关系到你能否顺畅地使用校园网,在调试过程中可以拿学校官方的蝴蝶数据进行比对查错。
- 心跳包发送间隔是30秒,也可以小于30秒,如果心跳包不稳定可以尝试适当调整。
- 在构建数据包之前要把需要填充的数据整理打包好,例如类型的转换,以及
空字符
的处理等等,以减少不必要的程序异常。 - 编写这个程序很简单,但是错误处理和代码优化有点繁琐,将自己当成使用者,并不断测试程序的极限状态,你会发现bug比你头发还多(当然,其根本原因还是我学艺不精)。
完成程序后,还可以考虑增加一点自己常用的功能,例如集成无线热点,增加NAT穿透等等……
成品效果图:
标签:++,IP,packet,ppkt,安朗,校园网,byte,数据包,斗智斗勇 From: https://www.cnblogs.com/1gcat/p/17609807.html