TUST的抓包之旅(1)----- 一鍵登錄校園網(wǎng)

開(kāi)發(fā)初衷
很久之前做一鍵登錄校園網(wǎng)以失敗告終,最近看By_syk大神的文章By_syk簡(jiǎn)書(shū)寫(xiě)的一鍵登錄校園網(wǎng),很受鼓舞,于是自己動(dòng)手實(shí)驗(yàn)了一下,By_syk的校園網(wǎng)系統(tǒng)和我們的是同一個(gè)系統(tǒng)(很神奇),我們學(xué)校的校園網(wǎng)也是按流量計(jì)費(fèi),所以每個(gè)人都會(huì)有一個(gè)帳號(hào),然后連接校園網(wǎng)之后使用這個(gè)帳號(hào)登錄才能使用,由于每次都要登錄比較麻煩,所以才會(huì)考慮寫(xiě)簡(jiǎn)單的小工具。

開(kāi)發(fā)原型
做一個(gè)簡(jiǎn)單的APP,提供通知欄瓷片或者快捷方式登錄校園網(wǎng),同時(shí)可以提供流量統(tǒng)計(jì)等功能(在下一版本考慮)

第一階段截圖
可以看到第三排第二個(gè)圖標(biāo)就是我們的校園網(wǎng)登錄按鈕(這里由于我對(duì)Quick TIle不太熟悉,有一些小問(wèn)題,不影響使用)

這里寫(xiě)圖片描述

下面是具體信息頁(yè)面,只上傳一個(gè)看看


這里寫(xiě)圖片描述

**

一.分析登錄接口

**

首先我們進(jìn)入我們的校園網(wǎng)登錄頁(yè)面


這里寫(xiě)圖片描述
這里寫(xiě)圖片描述

我使用Chrome的開(kāi)發(fā)者工具來(lái)分析網(wǎng)站,發(fā)現(xiàn)有個(gè)Ipv6地址字段,是獲取本機(jī)的Ipv6地址上傳,于是訪問(wèn)了一下手機(jī)登錄頁(yè)面,也就是59.67.0.245/a30.html(本地址只能在校內(nèi)訪問(wèn)),發(fā)現(xiàn)沒(méi)有該字段,所以打算使用這個(gè)頁(yè)面來(lái)抓包

訪問(wèn)59.67.0.245/a30.html輸入賬號(hào)密碼,打開(kāi)瀏覽器網(wǎng)站分析工具(快捷鍵F12)切換到開(kāi)發(fā)者工具network選項(xiàng)卡進(jìn)行抓包,記得要勾選 ?Preserve log 選項(xiàng)進(jìn)行長(zhǎng)連接記錄日志。

當(dāng)點(diǎn)擊校園網(wǎng)登錄按鈕的時(shí)候,所有的數(shù)據(jù)都被開(kāi)發(fā)者工具記錄下來(lái),我們選擇a30.html這個(gè)頁(yè)面進(jìn)行分析,這個(gè)是post我們的賬號(hào)密碼數(shù)據(jù)的頁(yè)面,一般會(huì)列在第一位


圖片中間數(shù)據(jù)有隱私數(shù)據(jù)被處理掉了

在這個(gè)頁(yè)面header選項(xiàng)卡里我們可以看到
Request URL:http://59.67.0.245/a30.htm
這樣一行,這也就是我們的數(shù)據(jù)將要post到的地方,那我們的數(shù)據(jù)在哪呢?對(duì),就是下面打馬賽克的那一塊,F(xiàn)orm Data(表單數(shù)據(jù)),可以看到一共有8個(gè)數(shù)據(jù),第一個(gè)DDDDD是學(xué)號(hào)(網(wǎng)站的開(kāi)發(fā)者還真是隨便命名),第二個(gè)打馬賽克當(dāng)然是密碼啦,另外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

在這里我們的密碼并沒(méi)有通過(guò)任何方式加密,所以我也就不研究源碼了
直接使用postman(一款chrome插件)進(jìn)行測(cè)試


這里寫(xiě)圖片描述

打開(kāi)postman,第一步選擇post方式,第二步填入我們剛才所找到的請(qǐng)求url,然后就是填入表中所列的form,點(diǎn)擊藍(lán)色send按鈕后,出現(xiàn)PC登錄成功頁(yè)面,說(shuō)明已經(jīng)登錄成功,這也就意味著我們的測(cè)試成功了,我們可以準(zhǔn)備開(kāi)始寫(xiě)代碼了。

**

二.準(zhǔn)備 APP 藍(lán)圖

**
這里我們使用幕布(腦圖)分析一下,我們的APP分為3個(gè)頁(yè)面,狀態(tài),賬號(hào)和充值(本篇文章只講狀態(tài)里的登錄部分)


這里寫(xiě)圖片描述

一鍵登錄的按鈕是根據(jù)是否連接校園路由器決定的,但是在代碼中可能這部分不會(huì)判斷(也就是請(qǐng)求一下59.67.0.245這個(gè)頁(yè)面,如果成功說(shuō)明當(dāng)前連接著校園網(wǎng),否則連接的不是校園網(wǎng)),為了簡(jiǎn)單起見(jiàn),我們選擇連接上wifi之后,就可以登錄,然后如果不通過(guò)就顯示登錄失敗。

下面準(zhǔn)備開(kāi)發(fā),這里我使用的開(kāi)發(fā)環(huán)境是deepin15系統(tǒng)下的Android Studio2.3 。

配置依賴

    //網(wǎng)絡(luò)請(qǐng)求
    compile 'com.squareup.okhttp3:okhttp:3.8.1'
    //Material Design引導(dǎo)頁(yè)面
    compile 'agency.tango.android:material-intro-screen:0.0.5'
    //Design庫(kù)
    compile 'com.android.support:design:25.1.0'

配置權(quán)限

<!--網(wǎng)絡(luò)-->
 <uses-permission android:name="android.permission.INTERNET" />
 <!--網(wǎng)絡(luò)狀態(tài)讀取-->
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

有了這些我們就可以做登錄操作了(先實(shí)現(xiàn)核心功能)

三.核心代碼

1.第一步,我們把要post的數(shù)據(jù)單獨(dú)寫(xiě)一個(gè)文件
文件名:Data.java


public class Data {

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

    //固定參數(shù)
    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.第二步,新建類,里面包含兩個(gè)靜態(tài)方法,第一個(gè)是檢查網(wǎng)絡(luò)狀態(tài),第二個(gè)是登錄

獲取網(wǎng)絡(luò)狀態(tài)

  //3種網(wǎng)絡(luò)狀態(tài)(wifi鏈接,gprs鏈接,斷網(wǎng))
    private static final int NETWORK_WIFI_CONNECTION = 1;
    private static final int NETWORK_MOBILE_CONNECTION = 2;
    private static final int NETWORK_DISCONNECTION = 0;
   
 
    //獲取網(wǎng)絡(luò)狀態(tài)
    public static int getNetWorkStatus(Context context) {
        //連接管理器對(duì)象
        ConnectivityManager connectivityManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        //如果連接管理器不為null
        if (connectivityManager != null) {
            //通過(guò)連接管理器獲取網(wǎng)絡(luò)連接狀態(tài)
            NetworkInfo networkInfo = connectivityManager
                    .getActiveNetworkInfo();
             //如果網(wǎng)絡(luò)狀態(tài)不為null并且網(wǎng)絡(luò)已經(jīng)連接
            if (networkInfo != null && networkInfo.isConnected()) {
                //根據(jù)網(wǎng)絡(luò)信息狀態(tài)獲取連接種類
                if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                    return NETWORK_WIFI_CONNECTION;
                }
                return NETWORK_MOBILE_CONNECTION;
            }
        }
        //返回未連接
        return NETWORK_DISCONNECTION;
    }

登錄核心代碼

   //返回給調(diào)用者登錄狀態(tài)
   static int status = 0;
  public static int LoginNetWork(final Context mContext) {
        //這里是讀取文件中儲(chǔ)存的賬號(hào)密碼并解密的過(guò)程(使用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();
        //填寫(xiě)表單,如果APP自己用,賬號(hào)密碼可以寫(xiě)死,而不需要從保存的數(shù)值里讀取
        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() {
            //請(qǐng)求失敗回調(diào)
            @Override
            public void onFailure(Call call, IOException e) {
                status = -1;
            }

            //請(qǐng)求成功回調(diào)
            @Override
            public void onResponse(Call call, Response response) throws IOException {
               status = 1;
            }
        });
        //將狀態(tài)返回給調(diào)用者
        return status;

啊,猝不及防就結(jié)束了?

沒(méi)錯(cuò)就是這樣,使用了Okhttp讓請(qǐng)求變得更簡(jiǎn)單,剩下的,就是調(diào)用的過(guò)程咯
寫(xiě)一個(gè)Activity,名字叫ShortActivity,并且配置他為啟動(dòng)器,這樣我們就有了一個(gè)一鍵登錄的圖標(biāo),可以放在桌面上

  <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里調(diào)用登錄方法

//這是他的onCreate方法,不需要界面,直接登錄,隨后自己finish掉自己
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在這里我沒(méi)有寫(xiě)檢查網(wǎng)絡(luò)的代碼,當(dāng)然也非常簡(jiǎn)單,調(diào)用我們寫(xiě)好的方法,根據(jù)返回值來(lái)判斷是不是需要開(kāi)放登錄
//根據(jù)login方法的返回值確定是否登錄成功
        if(CheckWiFiANDLogin.LoginNetWork(this)==1){
            Toast.makeText(this,"登錄成功",Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this,"登錄失敗",Toast.LENGTH_SHORT).show();
        }

        finish();
    }

現(xiàn)在可以運(yùn)行試試了
此處沒(méi)有截圖……
連接校園網(wǎng),點(diǎn)擊登錄的圖標(biāo)就可以登錄

就這樣就結(jié)束了么?
應(yīng)該沒(méi)毛病啊Android4.0 - Android 8.0都兼容了

老板讓你兼容到Android2.0?。?!
日你MMP的2.0

在Android日益發(fā)展更迭的版本中,有這么一個(gè)版本(7.0),新增加了Quilk Setting TIle功能,這是個(gè)什么功能呢,就是在通知欄下拉的列表中,添加自定義的設(shè)置瓷片,達(dá)到快速設(shè)置的功能,所以叫快速設(shè)置瓷片


這里寫(xiě)圖片描述

對(duì),就是這個(gè)樣子

我們來(lái)實(shí)現(xiàn)更高大上的操作方式吧
不過(guò)很遺憾,大部分國(guó)產(chǎn)的Android Rom都被定制的不成樣子,根本就沒(méi)有這個(gè)功能,所以這個(gè)也只能在原生的系統(tǒng)上體驗(yàn)了。

如果你想體驗(yàn)的話,不妨試試刷機(jī)原生系統(tǒng)
寶寶這里是小米note 標(biāo)準(zhǔn)版 ,系統(tǒng)是Lineage os Android7.1.2

實(shí)現(xiàn)QST首先要在清單文件中注冊(cè)服務(wù)

//配置一些必須的參數(shù)
 <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>

下面實(shí)現(xiàn)這個(gè)服務(wù)


/**
 * 快速設(shè)置系統(tǒng)磁塊
 * 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";

  
    /**
     * 這個(gè)方法是打開(kāi)通知欄的時(shí)候進(jìn)行的處理
     * 比如說(shuō)我們這個(gè)情況就是打開(kāi)通知欄判斷網(wǎng)絡(luò)有沒(méi)有連接
     * 連接了就可用,沒(méi)連接就不可用
     */
    @Override
    public void onStartListening() {
        
        //如果網(wǎng)絡(luò)未連接或者gprs網(wǎng)絡(luò),設(shè)置圖塊不可見(jiàn)
        if (CheckWiFiANDLogin.getNetWorkStatus(this) == 0 || CheckWiFiANDLogin.getNetWorkStatus(this) == 2) {
        //我們自定義一個(gè)更新磁塊方法
            updateTile("校園網(wǎng)未連接", false);
        } else {
            updateTile("校園網(wǎng)已連接", true);
        }
    }

    /**
     * 當(dāng)磁塊點(diǎn)擊了會(huì)發(fā)生什么情況
     */
    @Override
    public void onClick() {
        Log.d("QS", "Tile tapped");

//開(kāi)一個(gè)子線程來(lái)執(zhí)行要發(fā)生的邏輯
        new Thread(new Runnable() {
            @Override
            public void run() {
//沒(méi)錯(cuò),就是登錄,并且返回登錄狀態(tài)
                    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;
        }

        // 設(shè)置標(biāo)簽,圖標(biāo),活躍度等
        tile.setLabel(title);
        tile.setState(newState);

        // 刷新
        tile.updateTile();
    }

}

本寶寶也是第一次接觸這個(gè)功能,所以不太會(huì),根據(jù)Google Code Lab提供的方法簡(jiǎn)單實(shí)現(xiàn)了一下,不過(guò)還有些ui上的小bug,不影響使用

到這里我們的瓷片也已經(jīng)做好了,一個(gè)簡(jiǎn)單的登錄校園網(wǎng)APP已經(jīng)做好了
以后終于不用使用瀏覽器登錄了。

四.寫(xiě)在最后

本篇文章主要講解了分析抓包,測(cè)試抓包,利用抓包實(shí)現(xiàn)實(shí)用功能
在下一篇文章中,我們將利用抓包進(jìn)行更多酷炫的操作

在這里很感謝By_syk大佬,在酷安遇到他,很巧在簡(jiǎn)書(shū)也遇到了他,他的文章給了我很大的幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,176評(píng)論 25 708
  • 這篇文章是對(duì)于上一篇文章TUST抓包之旅(1)的補(bǔ)充,上一篇文章我們實(shí)現(xiàn)了一鍵登錄校園網(wǎng),并做了快捷瓷片。那么這篇...
    做夢(mèng)枯島醒閱讀 1,013評(píng)論 0 1
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,645評(píng)論 19 139
  • 創(chuàng)建一個(gè)函數(shù)斷點(diǎn) 避免每次都去控制臺(tái)去做expr @import UIKit ...命令 出現(xiàn)錯(cuò)誤 iOS 開(kāi)始
    zhouwude閱讀 778評(píng)論 0 0
  • 銅錢(qián)草很有意思,看著嬌嬌弱弱的,卻朝氣蓬勃,但一少了水,就立馬焉吧,沒(méi)見(jiàn)過(guò)比她變臉更快的植物,還動(dòng)不動(dòng)就生病,沒(méi)辦...
    56東南西閱讀 208評(píng)論 0 0

友情鏈接更多精彩內(nèi)容