Netkeeper基本流程分析(旧版本)

  • 内容
  • 评论
  • 相关

由于近期信利已更新Netkeeper至4.5.3,并且在新版中做出了大量改动,因此在此注明:此文中的内容只适用于Netkeeper(星空极速类软件)4.0以前的版本。

可能这东西对于大大们来说算是没什么技术含量的东西了,不过为了凑文(zhuang)章(bi)数我决定还是写点东西来玩玩吧。好歹这玩意儿坑了好几个省的高校学生,不发点什么都对不起三大运营商了,对不对。

话不多说,直接正题。

1.基本思路

Netkeeper相对于普通的拨号模式其实并没有太多的区别(我是说在拨号协议上并没有什么区别),为了达到坑害广大学子必须一机一号的要求,那么相对之下就要保证账号不能直接被用上各种共享设备(比如路由器)。一般来说,运营商给用户提供的登录账号是可以直接用在这些上面的,如果要让这些账号不能顺利通过认证,而是必须通过客户端,那么就得做点手脚,让BAS(接入服务器)知道:哦这个账号是客户端发的。所以在不修改及本协议的情况下,修改账号本身就成了一种选择,也就是说,运营商给你的账号和实际登陆过程中使用的账号是不一样的,最开始星空极速用的便是这一招,在账号前面加上了”^~1″前缀,来作出“标识”(实际上湖南电信校园网今年开始还在用这套,我也是帮基友看的时候发现的)。

但是好景不长啊,加固定前缀很快就被各种技术人员发现了,然后客户端就基本GG了,要你有卵用啊,在这个时候呢Netkeeper也算是从中吸取教训。没错,我继续加前缀,但是这个前缀实际上是变的,基于时间计算,而不是固定的。这样即便你抓到了账号你也没办法一直用,因为账号会变。而且为了让用户无法通过一般方式设置宽带拨号,这个前缀还加入了换行符(n),这意味着除非你自己是写程序的或者CRACK掉拨号程序,否则你没法输入这个字符就会一直无法通过身份验证。

对于Netkeeper现有算法来说,它通过每5秒变化一次来对时间进行各种位运算和与运算,来随机取得几位字符,然后附加两位(随机字符+用户名(如果用户名带有@xxxxx,则取@前面的部分)+加密参数(RADIUS))取MD5高2位再加上你的原始账号

所以经过处理以后,你在实际上发给验证服务器的账号就成了

前缀(rn或者r1)+ 时间HASH + MD5前两位 + 你本身账号

由于前缀中r的存在(换行符,也就是回车),一般用户无法通过正常的复制粘贴进行操作,也就达到了“避免一般用户抓包破解”的目的。

但是,聪明的大众是绝对不会屈服于你客户端的,我既然没办法复制你的账号,我拨完号直接把你进程结束掉,我看你还怎么限制我。于是针对这种情况,Netkeeper就有了“心跳包”功能,这个功能意味着当客户端进程没有结束时,登录网络以后客户端会定时向服务器发送一个“在线”的数据包,表示“哎电信大大我客户端在线这傻逼没有把我结束掉不用踢他下线了”,一旦客户端进程被结束,心跳包就会断掉(因为心跳包只能由Netkeeper本身发送),然后过了一段时间后电信的服务器发现“哎这孙子怎么还不给我发信息告诉我他还在线呢估计是GG了”,然后发条消息给BAS(宽带接入服务器)说“你们下面有个人把客户端结束掉了,这家伙大大的坏,给老子把他踢下线”,于是在这种情况下结束了客户端的同学会在一段时间后断线,就是这个道理。

2015/12/03更新:根据对江西电信新版客户端(4.0)的一个简单分析,现在客户端使用了xLoader模式,即运行前修改NETKEEPER主程序名称为一个UUID,然后启动双进程进行守护。此外,新版本的账号格式与以前的格式类似,但更改了算法(包括TimeHash,radius可能已被psk模式替代),所有的配置内容均从一个main.cfg的加密文件中读取,包括用于账号计算的PSK/前缀/后缀。

2.过程解析

说了上面这些东西,现在来说下一个大致流程。

Netkeeper在用户点击登录-》检查驱动是否存在,是否存在共享软件进程-》开始账号计算过程(加前缀)-》调用系统RasDialA拨号-》成功后到一个指定的端口下载配置文件,包括心跳、代理配置(要杀掉的共享进程列表)、更新配置等等-》开始周期性发送心跳

检查共享进程主要是检查是否存在系统自带ICS共享、360、猎豹、共享精灵等等,有的话尝试KILL这些进程,否则弹窗无法登陆。驱动检查主要是为了保证他自家的防共享驱动能够运行(用于清洗共享流量)

账号计算算法我就不说了,我之前的项目Git里面有,大家可以自己去看下。算法里面只有两个参数是会变化的,一个是Radius(不同地区/同地区不同版本都可能变化),一个是前缀(江西用的r1,其他地方是rn)

RasDial完成后根据情况返回错误内容(使用WinPcap抓取服务器返回数据,也就是PPPOE的最后返回包的内容,包含了错误信息,比如“You are calling outside your timespan”等),或者拨号成功,进入配置文件抓取阶段

配置文件抓取阶段主要是获取心跳配置以及防代理/共享,以及广告信息内容。服务器地址固定在程序里面,比如重庆地区指向gxyw.online.cq.cn,河北指向yewu.cncceshi.com。使用TCP连接,服务器端口号80。(你用浏览器直接访问当然没用啦,因为浏览器发的数据他根本不认嘛,不符合格式)

      • 客户端首先发送一个0x03开头的数据包,然后4字节表示后续内容长度,使用DES/ECB/NoPadding以密钥”xinlides”加密,此数据包经过解密后的内容包括用户名,客户端版本。
      • 服务器返回一个0x02开头的响应包,4字节表示后续内容长度,同样的加密方式,包括一些附加信息以及广告链接内容(江西地区返回的则是一些加密后的内容,比如黑名单,调试反馈地址等等)
      • 收到第一个回复后,客户端发送和前面结构一样的以0x01开头数据包,内容为PIN码(就是账号加密算法计算出来的8位字符),LANPIN(和PIN码似乎是一样的),操作系统名称,浏览器版本,网卡信息,以及操作系统语言、IP、账号信息
      • 服务器确认信息无误后返回0x02响应包,包括UDP心跳地址:端口,心跳次数,间隔,https方式心跳地址(如果有),是否允许更新,验证错误代码,以及代理配置部分地区,部分开启了心跳KEY的可能还包括了心跳使用的KEY参数。则还附加了额外需要“照顾”的进程名,根据返回内容推断应该是指定Netkeeper客户端要监控并清理的进程,主要是共享软件,以及部分似乎是需要客户端忽略(抑或额外设置路由表)的IP段。
      • 根据对陕西电信客户端配置文件的拆解,服务器可以决定是否要求客户端进行共享封杀(360/猎豹)

Netkeeper目录下有一个CheckPin.log记录链接过程(只包括发送接收多少数据以及是否加密而已,不要想太多,没什么关键内容的,下面这段是某次黑洞PPPOE处理后留下的内容)

>>2015年10月19日,星期1,21:25:31
with encrypt

socket value when create:1512
connect to gxyw.online.cq.cn:80 failed with error:10060

 

在配置文件抓取到以后,客户端分析服务器发送的配置,设置心跳服务器地址(heartUDPAddress),间隔(interval),以及心跳次数(heartcount),但是比较让我费解的是河北和湖北两地的心跳次数都是5,而江西和重庆则是5000,尽管根据一段时间分析证明这个数据与电信是否开了心跳验证无关,但是这个数据差别还是让我觉得有点蛋疼(是因为nk服务器设定的上限只能到5000次所以才是这些数字么?目前根据实际情况看来这些数字应该是可以自定义的,因为山东/陕西等星空极速部署地区的心跳次数为1W次),尽管没什么卵用。我并没有进一步去分析达到心跳次数后客户端是否会重新请求配置,主要是因为懒,没有写黑盒程序模拟服务器返回数据,而且PPPOE的服务器也没有配置对,所以暂时没去管这部分。分析湖北电信心跳表明心跳次数达到后服务器会将账号移除心跳列表,不再要求重新请求。

心跳开始后,客户端按照间隔值(秒)发送心跳包,当前版本的Netkeeper设置了总计发送4个UDP包,分别到心跳服务器的443,444,445,446。其中443这个端口是配置文件获取到的端口,加上根据dump客户端获取到的数据来看后面三个端口都是写死在客户端里面的,因此推测远端服务器具有变更心跳端口的功能,并且以这个端口为主要心跳。(实际上根据测试在只发送了443这个心跳的情况下的确没有出现掉线的情况,因而上述结论应该是成立的)

      • 443端口和444端口的数据包采用AES128(部分地区使用DES类)加密(自己试试,不细说)。其中发送到443端口的基本内容(除开地区特定内容)为“TYPE=HEARTBEAT&USER_NAME=用户名&PASSWORD=密码&MAC=00%2D00%2D00%2D00%2D00%2D00&VERSION=客户端版本号&DRIVER=1”,其他的心跳参数根据地区不同还可以包括IPV6状态(湖北地区),PIN码(重庆、湖北、星空极速客户端使用地区(山东、陕西、青海、新疆)),IP2(江西、湖北),HOOK(江西),以及KEY(上一次心跳服务器返回的参数KEY)。发送到444端口的内容包括一个时间戳、用户名、密码、客户端版本。
      • 445和446端口使用3DES加密(老版本的星空极速可能仍然在使用AES)。
      • 心跳密钥根据0070+版本的客户端dump推断以后发现可以从dump文件中查找“XINLIAPSECRET0123456789”字符串,在其后的几个加密字符串则为心跳使用的密钥(3DES密钥及其初始向量,以及AES密钥)。
      • 根据当前情况,服务器在收到443端口的UDP后可以选择返回一个心跳结果,指示客户端是否继续,或者指示客户端下线(HEARTBEATRESULT中包含了“心跳下线”这个定义),还可以携带一个心跳KEY,要求客户端下一次心跳带上这个KEY,否则认为心跳无效(一个特例是河北联通的心跳返回了KEY,但是客户端并没有发送这个KEY,dump发现是因为客户端不存在KEY的逻辑导致的。根据客户端相似性可以推断山东移动同样如此)。根据前面配置文件拆解过程分析可以确认,首次心跳发送的KEY是来自于心跳开始前的配置文件中首次发送的KEY还是来自于第一次心跳。服务器也可以选择不返回数据,此时客户端不会执行其他操作。
      • 根据对陕西电信星空极速客户端配置文件的拆解,当服务器返回的配置文件不包含heartUDPAddress时,客户端将不发送UDP的心跳。此外根据对山东电信配置文件的拆解,PIN码计算规则可由服务器控制,即配置文件中的PINSection定义PIN码计算起始时间,否则将由客户端随机决定。

根据推测,心跳操作对于服务器端的流程应该是:

      • BAS通知服务器用户上线,并告诉心跳服务器用户域(就是用户名中@后面的部分)
      • 根据服务端配置,如果指定用户域在心跳检测配置中,则放入在线用户列表,否则不进行心跳验证。(为什么这么说。。。因为根据现在的情况重庆地区动态密码账号是没有带用户域的,而动态密码账号没有心跳检测,推断重庆电信没有将这类用户纳入心跳检测范围,电信开始对动态密码下手了,所有账号只要发送过心跳的都会被加入心跳列表中,但暂时无法确定是否是永久加入。)
      • 收到UDP心跳请求后,如果心跳内容合法,刷新用户在线时间
      • 轮询检查用户列表,如果超过指定时间间隔没有收到用户心跳包反馈,则认为用户下线,发送下线通知给BAS要求踢掉用户。
      • 如果用户下线,BAS发送信息给心跳服务器,服务器将用户从列表中移除。(原则上也可以不这么做,因为超时后心跳服务器还是会发送信息给BAS下线,BAS对于不在线用户应该会进行忽略)

至此,心跳检测导致的间歇性断线原因已经说明。大致上整个Netkeeper的过程也推测完毕。

评论

6条评论
  1. Gravatar 头像

    yk

    我竟然看完了,只能说666666

  2. Gravatar 头像

    Peter

    昨天开始湖北大面积开启心跳...我等苦逼大学僧药丸啊~

  3. Gravatar 头像

    陈祥梦

    大神你好!2016级新生,宿舍4人办了一个湖北e信账号,我们在学校买个路由器,老板给了这个软件,可是学校熄灯了!每次都要立即设置,而且还会断网额!好苦逼啊!

    • Gravatar 头像

      miss mono

      @陈祥梦 那你们是被坑了,这个软件我都是免费送人的。现在在找弄这个也是为了解决断电后重新设置的问题。

  4. Gravatar 头像

    邹金虎

    那现在重庆电信把netkeeper更新成了创翼客户端 现在netkeeper拨号都是5分钟断线了 路由器也是这样 是它改掉了心跳??

  5. Gravatar 头像

    张雨生

    山东移动好像更新了,连不上或者链接一会就掉。求大神