路由器自动认证

背景及需求
我校的有线网络并不会限制路由器的使用。然而,有线网络的认证方式是动态 IP + Web 认证。在每天凌晨会重置,访问任意页面就会被劫持到学校的认证网页,在该网页上输入账号密码后,才能联网。虽说不算太麻烦,但每次都要手动输入账号密码,还是让人有些不爽。之前从网上找了别人类似情况造好的轮子,直接使用:

### 自动登陆内网
#!/bin/sh
logger "开始检测网络认证状态"
KEYWORD=$(curl -s http://baidu.com | grep "Moved")
if [[ ${KEYWORD} != "" ]]; then
logger "检测到尚未认证,尝试自动认证"
LOGIN_STATUS=$(curl -s -X POST "http://10.69.253.12/ac_portal/login.php" -H "Origin: http://10.69.253.12" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: zh-CN,zh;q=0.9" -H "User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36" -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" -H "Accept: */*" -H "Referer: http://10.69.253.12/ac_portal/20190610083017/pc.html?template=20190610083017&tabs=pwd-sms&vlanid=0&url=http://www.msftconnecttest.com%2fredirect" -H "X-Requested-With: XMLHttpRequest" -H "Connection: keep-alive" --data "opr=pwdLogin&userName=账号&pwd=密码&rememberPwd=0")
SUCCESS=$(echo ${LOGIN_STATUS} | grep success)
if [[ ${SUCCESS} != "" ]]; then
logger "自动认证成功"
else
LOGIN_STATUS=$(echo ${LOGIN_STATUS} | cut -d ',' -f3 | cut -d '"' -f4)
logger "自动认证失败: ${LOGIN_STATUS}"
fi
else
logger "检测到已经认证"
fi

然而,最近学校升级了认证机制,密码需要进行rc4加密后再提交,linux的bash脚本对于加密函数编写不太友好,因此需要另想他法。

网上找到了python对于rc4加密现成的算法,直接拿来使用。

首先在路由器上开启Entware,插入U盘,将U盘挂载到/opt,用来安装Entware。保证U盘为exfat格式。

ejusb #卸载usb
mount -t exfat /dev/sda1 /opt #将usb挂载到/opt

然后,安装entware

wget http://mirrors.bfsu.edu.cn/entware/mipselsf-k3.4/installer/opkg -O /opt/bin/opkg
chmod 755 /opt/bin/opkg
wget http://mirrors.bfsu.edu.cn/entware/mipselsf-k3.4/installer/opkg.conf -O /opt/etc/opkg.conf
sed -i 's|bin.entware.net|mirrors.bfsu.edu.cn/entware|g' /opt/etc/opkg.conf
/opt/bin/opkg update

接着安装python3

opkg install python3         #python3
opkg install python3-pip     #pip3

接着将挂载U盘的动作添加到开机启动里

ejusb #卸载usb
mount -t exfat /dev/sda1 /opt #将usb挂载到/opt

然后将登录的python脚本拷贝到路由器中,例如/etc/storage/

登录脚本如下:


import time
import urllib.parse
import urllib.request

def do_encrypt_rc4(src, passwd):
    src = src.strip()
    passwd = str(passwd)

    key = [0] * 256
    sbox = list(range(256))
    output = []

    plen = len(passwd)
    size = len(src)

    for i in range(256):
        key[i] = ord(passwd[i % plen])

    j = 0
    for i in range(256):
        j = (j + sbox[i] + key[i]) % 256
        sbox[i], sbox[j] = sbox[j], sbox[i]

    a = b = c = 0
    for i in range(size):
        a = (a + 1) % 256
        b = (b + sbox[a]) % 256
        sbox[a], sbox[b] = sbox[b], sbox[a]
        c = (sbox[a] + sbox[b]) % 256
        temp = src[i]
        temp = ord(temp) ^ sbox[c]
        temp = format(temp, '02x')
        output.append(temp)

    return ''.join(output)


def send_post_request(password):
    url = "http://1.1.1.3/ac_portal/login.php"
    current_time = str(int(time.time()))  # 获取当前时间戳并转换为字符串

    # 使用do_encrypt_rc4函数加密密码
    encrypted_pwd = do_encrypt_rc4(password, current_time)

    # 构建POST请求的数据
    data = {
        "opr": "pwdLogin",
        "userName": "账号",
        "pwd": encrypted_pwd,
        "auth_tag": current_time,
        "rememberPwd": "0"
    }

    # 将数据进行URL编码
    data_encoded = urllib.parse.urlencode(data).encode('utf-8')

    # 创建请求对象并发送POST请求
    request = urllib.request.Request(url, data=data_encoded, method='POST')
    try:
        with urllib.request.urlopen(request) as response:
            # 读取响应内容
            response_data = response.read().decode('utf-8')
            print("Response:")
            print(response_data)
    except urllib.error.HTTPError as e:
        # 返回错误状态码
        print("HTTP Error:", e.code)
        return e.code
    except urllib.error.URLError as e:
        # 返回URL错误
        print("URL Error:", e.reason)
        return e.reason

    # 如果没有错误,则返回 None 或其他合适的值
    return None

# 调用发送POST请求的函数,并传入密码
result = send_post_request("密码")

if result is None:
    print("登录成功!")
else:
    print("登录失败:", result)

最后,在开机脚本加入:
/opt/bin/python3 /etc/storage/login.py

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注