TUST的抓包之旅(1)----- 一键登录校园网

开发初衷
很久之前做一键登录校园网以失败告终,最近看By_syk大神的文章By_syk简书写的一键登录校园网,很受鼓舞,于是自己动手实验了一下,By_syk的校园网系统和我们的是同一个系统(很神奇),我们学校的校园网也是按流量计费,所以每个人都会有一个帐号,然后连接校园网之后使用这个帐号登录才能使用,由于每次都要登录比较麻烦,所以才会考虑写简单的小工具。

开发原型
做一个简单的APP,提供通知栏瓷片或者快捷方式登录校园网,同时可以提供流量统计等功能(在下一版本考虑)

第一阶段截图
可以看到第三排第二个图标就是我们的校园网登录按钮(这里由于我对Quick TIle不太熟悉,有一些小问题,不影响使用)

这里写图片描述

下面是具体信息页面,只上传一个看看


这里写图片描述

**

一.分析登录接口

**

首先我们进入我们的校园网登录页面


这里写图片描述
这里写图片描述

我使用Chrome的开发者工具来分析网站,发现有个Ipv6地址字段,是获取本机的Ipv6地址上传,于是访问了一下手机登录页面,也就是59.67.0.245/a30.html(本地址只能在校内访问),发现没有该字段,所以打算使用这个页面来抓包

访问59.67.0.245/a30.html输入账号密码,打开浏览器网站分析工具(快捷键F12)切换到开发者工具network选项卡进行抓包,记得要勾选 ️Preserve log 选项进行长连接记录日志。

当点击校园网登录按钮的时候,所有的数据都被开发者工具记录下来,我们选择a30.html这个页面进行分析,这个是post我们的账号密码数据的页面,一般会列在第一位


图片中间数据有隐私数据被处理掉了

在这个页面header选项卡里我们可以看到
Request URL:http://59.67.0.245/a30.htm
这样一行,这也就是我们的数据将要post到的地方,那我们的数据在哪呢?对,就是下面打马赛克的那一块,Form Data(表单数据),可以看到一共有8个数据,第一个DDDDD是学号(网站的开发者还真是随便命名),第二个打马赛克当然是密码啦,另外R1,R2,R6,R7,para,0MKKey初步判断为定值

字段
DDDDD 15104413
upass ×××××××××××
R1 0
R2
R6 1
R7 0
para 00
0MKKey 123456

那我下面列出了本次我们需要提交的值

字段
DDDDD 15104413
upass ×××××××××××
R1 0
R2
R6 1
R7 0
para 00
0MKKey 123456

在这里我们的密码并没有通过任何方式加密,所以我也就不研究源码了
直接使用postman(一款chrome插件)进行测试


这里写图片描述

打开postman,第一步选择post方式,第二步填入我们刚才所找到的请求url,然后就是填入表中所列的form,点击蓝色send按钮后,出现PC登录成功页面,说明已经登录成功,这也就意味着我们的测试成功了,我们可以准备开始写代码了。

**

二.准备 APP 蓝图

**
这里我们使用幕布(脑图)分析一下,我们的APP分为3个页面,状态,账号和充值(本篇文章只讲状态里的登录部分)


这里写图片描述

一键登录的按钮是根据是否连接校园路由器决定的,但是在代码中可能这部分不会判断(也就是请求一下59.67.0.245这个页面,如果成功说明当前连接着校园网,否则连接的不是校园网),为了简单起见,我们选择连接上wifi之后,就可以登录,然后如果不通过就显示登录失败。

下面准备开发,这里我使用的开发环境是deepin15系统下的Android Studio2.3 。

配置依赖

    //网络请求
    compile 'com.squareup.okhttp3:okhttp:3.8.1'
    //Material Design引导页面
    compile 'agency.tango.android:material-intro-screen:0.0.5'
    //Design库
    compile 'com.android.support:design:25.1.0'

配置权限

<!--网络-->
 <uses-permission android:name="android.permission.INTERNET" />
 <!--网络状态读取-->
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

有了这些我们就可以做登录操作了(先实现核心功能)

三.核心代码

1.第一步,我们把要post的数据单独写一个文件
文件名:Data.java


public class Data {

    //post地址
    public static final String post_url = "http://59.67.0.245/a70.htm";

    //固定参数
    public static final String R1 = "0";
    public static final String R2 = "";
    public static final String R7 = "0";
    public static final String para = "00";
    public static final String MKKey = "123456";
    public static final String R6 = "1";
}

2.第二步,新建类,里面包含两个静态方法,第一个是检查网络状态,第二个是登录

获取网络状态

  //3种网络状态(wifi链接,gprs链接,断网)
    private static final int NETWORK_WIFI_CONNECTION = 1;
    private static final int NETWORK_MOBILE_CONNECTION = 2;
    private static final int NETWORK_DISCONNECTION = 0;
   
 
    //获取网络状态
    public static int getNetWorkStatus(Context context) {
        //连接管理器对象
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        //如果连接管理器不为null
        if (connectivityManager != null) {
            //通过连接管理器获取网络连接状态
            NetworkInfo networkInfo = connectivityManager
                    .getActiveNetworkInfo();
             //如果网络状态不为null并且网络已经连接
            if (networkInfo != null && networkInfo.isConnected()) {
                //根据网络信息状态获取连接种类
                if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                    return NETWORK_WIFI_CONNECTION;
                }
                return NETWORK_MOBILE_CONNECTION;
            }
        }
        //返回未连接
        return NETWORK_DISCONNECTION;
    }

登录核心代码

   //返回给调用者登录状态
   static int status = 0;
  public static int LoginNetWork(final Context mContext) {
        //这里是读取文件中储存的账号密码并解密的过程(使用base64加密)
        SharedPreferences sharedPreferences = mContext.getSharedPreferences("data",MODE_PRIVATE);
        String id = new String(Base64.
             decode(sharedPreferences.getString("id","0"),Base64.DEFAULT));
        String pwd = new String(Base64.
                decode(sharedPreferences.getString("pwd","0"),Base64.DEFAULT));
 //初始化okhttp的客户端      
  OkHttpClient client = new OkHttpClient();
        //填写表单,如果APP自己用,账号密码可以写死,而不需要从保存的数值里读取
        FormBody formBody = new FormBody.Builder()
                .add("DDDDD", id)
                .add("R1", Data.R1)
                .add("R2", Data.R2)
                .add("R7", Data.R7)
                .add("upass", pwd)
                .add("para", Data.para)
                .add("0MKKey", Data.MKKey)
                .add("R6", Data.R6)
                .build();
        //将表单提交到url
        Request request=new Request.Builder().url(Data.post_url).post(formBody).build();
        client.newCall(request).enqueue(new Callback() {
            //请求失败回调
            @Override
            public void onFailure(Call call, IOException e) {
                status = -1;
            }

            //请求成功回调
            @Override
            public void onResponse(Call call, Response response) throws IOException {
               status = 1;
            }
        });
        //将状态返回给调用者
        return status;

啊,猝不及防就结束了?

没错就是这样,使用了Okhttp让请求变得更简单,剩下的,就是调用的过程咯
写一个Activity,名字叫ShortActivity,并且配置他为启动器,这样我们就有了一个一键登录的图标,可以放在桌面上

  <activity android:name=".ShortActivity"
            android:label="快捷登录"
            android:theme="@style/myTransparent"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

3.最后一步吧,在shortActivity里调用登录方法

//这是他的onCreate方法,不需要界面,直接登录,随后自己finish掉自己
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在这里我没有写检查网络的代码,当然也非常简单,调用我们写好的方法,根据返回值来判断是不是需要开放登录
//根据login方法的返回值确定是否登录成功
        if(CheckWiFiANDLogin.LoginNetWork(this)==1){
            Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this,"登录失败",Toast.LENGTH_SHORT).show();
        }

        finish();
    }

现在可以运行试试了
此处没有截图……
连接校园网,点击登录的图标就可以登录

就这样就结束了么?
应该没毛病啊Android4.0 - Android 8.0都兼容了

老板让你兼容到Android2.0!!!
日你MMP的2.0

在Android日益发展更迭的版本中,有这么一个版本(7.0),新增加了Quilk Setting TIle功能,这是个什么功能呢,就是在通知栏下拉的列表中,添加自定义的设置瓷片,达到快速设置的功能,所以叫快速设置瓷片


这里写图片描述

对,就是这个样子

我们来实现更高大上的操作方式吧
不过很遗憾,大部分国产的Android Rom都被定制的不成样子,根本就没有这个功能,所以这个也只能在原生的系统上体验了。

如果你想体验的话,不妨试试刷机原生系统
宝宝这里是小米note 标准版 ,系统是Lineage os Android7.1.2

实现QST首先要在清单文件中注册服务

//配置一些必须的参数
 <service
            android:name=".Service.QSTileService"
            android:icon="@drawable/ic_action_wifi2"
            android:label="@string/app_name"
       //必须     android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
            //必须
            <intent-filter>
                <action android:name="android.service.quicksettings.action.QS_TILE" />
            </intent-filter>
        </service>

下面实现这个服务


/**
 * 快速设置系统磁块
 * Created by surine on 17-7-6.
 */

//Android7.0使用注解
@SuppressLint("NewApi")
public class QSTileService extends TileService {

    int net_status = 0;
    private static final String SERVICE_STATUS_FLAG = "serviceStatus";
    private static final String PREFERENCES_KEY = "com.google.android_quick_settings";

  
    /**
     * 这个方法是打开通知栏的时候进行的处理
     * 比如说我们这个情况就是打开通知栏判断网络有没有连接
     * 连接了就可用,没连接就不可用
     */
    @Override
    public void onStartListening() {
        
        //如果网络未连接或者gprs网络,设置图块不可见
        if (CheckWiFiANDLogin.getNetWorkStatus(this) == 0 || CheckWiFiANDLogin.getNetWorkStatus(this) == 2) {
        //我们自定义一个更新磁块方法
            updateTile("校园网未连接", false);
        } else {
            updateTile("校园网已连接", true);
        }
    }

    /**
     * 当磁块点击了会发生什么情况
     */
    @Override
    public void onClick() {
        Log.d("QS", "Tile tapped");

//开一个子线程来执行要发生的逻辑
        new Thread(new Runnable() {
            @Override
            public void run() {
//没错,就是登录,并且返回登录状态
                    if(CheckWiFiANDLogin.LoginNetWork(QSTileService.this) == -1){
                        updateTile("登录失败",true);
                    }else{
                        updateTile("登录成功",true);
                    }

                }

        }).start();
    }
    // 更新瓷片方法
    private void updateTile(String title,boolean b) {

         //获取瓷片
        Tile tile = this.getQsTile();
        int newState;

        // 改变瓷片活跃度
        if (b){
            newState = Tile.STATE_ACTIVE;
        }else{
            newState = Tile.STATE_UNAVAILABLE;
        }

        // 设置标签,图标,活跃度等
        tile.setLabel(title);
        tile.setState(newState);

        // 刷新
        tile.updateTile();
    }

}

本宝宝也是第一次接触这个功能,所以不太会,根据Google Code Lab提供的方法简单实现了一下,不过还有些ui上的小bug,不影响使用

到这里我们的瓷片也已经做好了,一个简单的登录校园网APP已经做好了
以后终于不用使用浏览器登录了。

四.写在最后

本篇文章主要讲解了分析抓包,测试抓包,利用抓包实现实用功能
在下一篇文章中,我们将利用抓包进行更多酷炫的操作

在这里很感谢By_syk大佬,在酷安遇到他,很巧在简书也遇到了他,他的文章给了我很大的帮助。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 179,316评论 25 708
  • 这篇文章是对于上一篇文章TUST抓包之旅(1)的补充,上一篇文章我们实现了一键登录校园网,并做了快捷瓷片。那么这篇...
    做梦枯岛醒阅读 1,015评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,688评论 19 139
  • 创建一个函数断点 避免每次都去控制台去做expr @import UIKit ...命令 出现错误 iOS 开始
    zhouwude阅读 791评论 0 0
  • 铜钱草很有意思,看着娇娇弱弱的,却朝气蓬勃,但一少了水,就立马焉吧,没见过比她变脸更快的植物,还动不动就生病,没办...
    56东南西阅读 208评论 0 0

友情链接更多精彩内容