【转载】联通校园网不能开热点问题解决办法

本文转载自:https://blog.csdn.net/ElliotCs/article/details/79671322
原作者:追梦小猿@CSDN

转载前言:大概在这个学期开始的时候,学校的联通宽带不再像上个学期那样直接用,改成了与全国高校类似的「一人一号」制度。

以前连宽带就跟自己家里似的,把网线扯到路由器上,填上账号密码,整个宿舍都能用,月底平摊网费(也就一人5块钱)。不足的话就是8个人共享一个垃圾路由器的信号,晚上人一多就卡得跟ppt似的。不过这样的好处就是switch和macbook也能用,不用什么乱七八糟的portal认证之类的。改成「一人一号」制度后,还是一根网线接路由器(煞笔学校,每个人桌子底下都有网线口,结果一个宿舍四个口只给开一个,其他人只能接路由器用…),不过路由器只起桥接作用。每个人连上后还得用专用的登录器认证账号密码才能上网。


(这个是登录器主体)


(这个是启动主体前跳出的guard检查)

对于这个登录器,我TM真是有一大肚子苦水要倒…打开这个玩意后,不能开热点,不能开虚拟网卡。如果就这样也就算了,但问题是它bug奇多,经常你用着用着就突然弹出个窗口说你开热点、检测到多开(或者xxx的理由),然后10s后自动掉线,还经常在你玩游戏玩到最重要的时候弹…有的时候登上隔1分钟就提示10s后掉线,就这么来回重复,室友都苦笑:「今天是你运气不好了…昨天我也这样…」。而且有的时候想要上网,打都打不开,自带一个guard检测莫名其妙的提示你获得学校信息失败云云…最重要的是,switch、macbook和linux也没法用了(mac客户端都没有还指望有linux?),手机转发开热点也非常不稳定,splatoon2匹配从未成功过,几乎让我放弃了在学校玩switch…在几乎被逼疯后,我开始下定决心找解决方法。然而,它并不是像其他运营商那样用的现有的商业解决方案(比如「Drecom」(我们校园网用的这个,学生账号会被提示不允许用portal登录…),比如「NetKeeper」),而是自己搞的一个登录器,所以没法借鉴其他的现成破解方案。长时间搜索过后,就这样,看到了这篇文章。凑巧的是,这篇文章是隔壁信院的哥们写的,估计也是被惹毛了开始折腾的吧。这篇文章给解决这类问题提供了一个很好的思路,于是转载过来,以供借鉴。

PS:本文仅转载获得实际拨号用账号密码的部分,后续使用java制作登录器的部分忽略。

==========

背景:之前宿舍开一个宽带账号,然后用路由器开热点全宿舍用。今年开学以后,改成了一人一账号,电脑或手机必须用客户端登陆才能使用,而且开热点就掉线,虚拟网卡也不能打开,路由器也只是起到桥接作用。原本连上wifi就能用的现在却变得如此麻烦,登陆界面又太low,心中各种不爽。所以决定解决一下。

解决思路及过程如下:
1、首先想到的就是用google搜索解决办法或者是破解版的认证客户端。
由于DialClient是新出的登陆端,没有可用解决方法和破解版。所以决定自己解决并写下这篇博客。
2、先对客户端进行分析
客户端大体有两个功能:认证登陆+开热点等检测
所以第一种解决思路就是对原客户端进行破解,只保留认证部分,让检测部分不起作用。
对客户端的相关文件进行反编译后,结果并不理想。所以换一种思路。
第二种解决思路就是对原客户端全部放弃,自己来做认证部分。
认证无非就那么几种形式:一种像CMCC通过http协议登陆,另一种就是PPPoE登陆。
第一种模拟http请求,第二种获取加密的账号密码用系统自带的宽带连接,应该就能解决。


(HTTP登录)

3、解决问题:
第一步、同是打开抓包工具(我这里用的是wireshark)和登陆客户端
1、wireshark开始
2、客户端登陆
3、wireshark停止
第二步、分析抓到的数据

1、通过抓包发现它最先发送的是http协议的post请求,所以先对这两个post进行分析
第一个请求及响应:


第二个请求及响应:


根据请求文件名猜测check是检测网络连通性请求,authlogin是登陆请求,所以打算用模拟客户端发送登陆请求来实现登陆(当然后面实践证明是不可行的)。代码附上如下:

package denglu;  
import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.io.PrintWriter;  
import java.net.URL;  
import java.net.URLConnection;  
public class denglu {  
    public static void main(String[] args) {  
        String sr1=sendPost("http://139.198.3.98/mgr/api/account/check.html", "user_name=账号&school_id=学校编号&pwd=密码");  
        System.out.println(sr1);  
        String sr2=sendPost("http://139.198.3.98/mgr/api/authlogin.html", "loguser=账号&schoolId=学校编号");  
        System.out.println(sr2);  
    }  
      
     public static String sendPost(String url, String param) {  
        PrintWriter out = null;  
        BufferedReader in = null;  
        String result = "";  
        try {  
            URL realUrl = new URL(url);  
            // 打开和URL之间的连接  
            URLConnection conn = realUrl.openConnection();  
            // 设置通用的请求属性  
            conn.setRequestProperty("accept", "*,*/*");  
            conn.setRequestProperty("Accept-Language", "zh-cn,en-us;q=0.5");  
            conn.setRequestProperty("Accept-Encoding", "gzip, deflate");  
            conn.setRequestProperty("Proxy-Connection", "Keep-Alive");  
            conn.setRequestProperty("Accept-Language", "zh-cn,en-us;q=0.5");  
            conn.setRequestProperty("user-agent",  
                    "Mozilla/4.0 (MSIE 5.0; libcurl-7.53.1;)");  
            // 发送POST请求必须设置如下两行  
            conn.setDoOutput(true);  
            conn.setDoInput(true);  
            // 获取URLConnection对象对应的输出流  
            out = new PrintWriter(conn.getOutputStream());  
            // 发送请求参数  
            out.print(param);  
            // flush输出流的缓冲  
            out.flush();  
            // 定义BufferedReader输入流来读取URL的响应  
            in = new BufferedReader(  
                    new InputStreamReader(conn.getInputStream()));  
            String line;  
            while ((line = in.readLine()) != null) {  
                result += line;  
            }  
        } catch (Exception e) {  
            System.out.println("发送 POST 请求出现异常!"+e);  
            e.printStackTrace();  
        }  
        //使用finally块来关闭输出流、输入流  
        finally{  
            try{  
                if(out!=null){  
                    out.close();  
                }  
                if(in!=null){  
                    in.close();  
                }  
            }  
            catch(IOException ex){  
                ex.printStackTrace();  
            }  
        }  
        return result;  
    }      
}

运行结果如下:

虽然显示成功,但实际并未联通。所以对抓包数据继续往下分析。

上面两行应该是PPPoE的数据,展开如下:

根据得到的账号密码,使用系统自带的PPPoE连接软件进行登陆。
登不上去,再返回来查看抓包数据。

ASCII的第一个字符无法用键盘敲出,网上也没有现成的可以复制,可以用如下代码生成,然后复制。

System.out.println((char)1);

至此,已经通过自带的PPPoE连接上了,可以开wifi,用虚拟机,没有任何限制。
加密后的账号:手机号+@dxcwo201
加密后的密码:\001+密码(\001指的是ASCII编码为1的字符,代号为SOH,不可显示)

==========

转载后记:我曾经想过自己折腾,不过奈何技术水平不够,只能仰望大佬。观察过文件名,叫做「dialclient-shandong」,猜测除了这个版本之外应该还有给其他地区用的版本。后来拿到实际账号后搜了一下后缀「wo201」,发现是北京联通校园宽带的代号。还发现原来以前别的地区的学校就有过这种加密方法和破解方法…不过根据[这篇]文章来看联通已经在部分地区升级了登录器,采用了GET动态PIN构成密码的加密方式。虽然不难解决,但估计以后我们也会面对这个吧…希望在我毕业之前不要再搞什么幺蛾子了…
portal登录网站:http://139.198.3.98/sdjd,有兴趣的可以下载客户端尝试爆破一下。