山东科技大学 GiWiFi 自动登录脚本
前言
前几天买了一个路由器(OpenWrt)想在学校用,就诞生了几个需求:
- 可以认证Giwifi上网
- 因为宿舍断电,需要来电开机后自动认证
- 最好能够占用平板端的闲置名额
此项目地址:Giwifi_autoLogin
原理
Giwifi认证时因为尚未联网,走的是http明文,只是对一些参数进行了加密
API接口
POST /gportal/Web/loginAction
Host: 10.100.100.2
X-Requested-With: XMLHttpRequest
Origin: http://10.100.100.2
Referer: http://10.100.100.2/gportal/web/login?has_reload=1
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cookie: ...
载荷明文
sign=xxxxx&
sta_vlan=xxx&
sta_port=xxx&
sta_ip=xxx&
nas_ip=xxx&
nas_name=xxx&
last_url=xxx&
request_ip=xxx&
device_mode=xxx&
device_type=xxx&
device_os_type=xxx&
is_mobile=xxx&
iv=xxxxxxxxxxxxxxxx&
login_type=xxx&
account_type=xxx&
user_account=你的账号&
user_password=你的密码
载荷加密
明文字符串
-> 转成字节
-> 按 16 字节补 0
-> AES-128-CBC
-> Base64
参数
- 算法:AES-128-CBC
- key:1234567887654321
- iv:页面返回的 iv
- padding:Zero Padding
- 输出:Base64
enc = Base64(AES-CBC-Encrypt(zeropad(raw)))
模拟手机/平板/PC端
在编写此脚本时,UA使用的是Win,故此脚本模拟的是PC端。
而根据载荷参数,我们可以模拟其它端,只需要知道此端对应的device_mode=xxx&device_type=xxx&device_os_type=xxx&is_mobile=xxx&参数即可
后续有时间我会写一个第三方客户端,支持自定义模拟
更新:见第三方GiWifi客户端
脚本详细
内容
因为要在OpenWrt路由器上运行,故使用shell脚本
#!/bin/sh
# 用法:
# sh giwifi.sh 账号 密码 [base_url]
# 例子:
# sh giwifi.sh 12345678901 123456 http://10.100.100.2
UA='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36'
BASE_URL="${3:-http://10.100.100.2}"
LOGIN_URL="$BASE_URL/gportal/web/login?has_reload=1"
POST_URL="$BASE_URL/gportal/Web/loginAction"
TMP_DIR="/tmp/giwifi.$$"
COOKIE="$TMP_DIR/cookie.txt"
HTML="$TMP_DIR/login.html"
RAW="$TMP_DIR/raw.txt"
PADDED="$TMP_DIR/padded.bin"
RESP="$TMP_DIR/resp.txt"
cleanup() {
rm -rf "$TMP_DIR"
}
trap cleanup EXIT INT TERM
mkdir -p "$TMP_DIR" || exit 1
if [ $# -lt 2 ]; then
echo "Usage: sh $0 <user_account> <user_password> [base_url]" >&2
exit 1
fi
USER_ACCOUNT="$1"
USER_PASSWORD="$2"
need_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "missing command: $1" >&2
exit 1
}
}
need_cmd wget
need_cmd sed
need_cmd grep
need_cmd openssl
need_cmd hexdump
need_cmd awk
need_cmd tr
log() {
echo "[giwifi] $*"
}
get_input_value() {
name="$1"
sed -n "s/.*name=\"$name\" value=\"\\([^\"]*\\)\".*/\\1/p" "$HTML" | head -n 1
}
urlencode() {
local s="$1"
local out=""
local c
while [ -n "$s" ]; do
c="$(printf '%s' "$s" | cut -c1)"
s="$(printf '%s' "$s" | cut -c2-)"
case "$c" in
[a-zA-Z0-9.~_-])
out="${out}${c}"
;;
' ')
out="${out}%20"
;;
*)
hex="$(printf '%s' "$c" | hexdump -ve '1/1 "%.2x"')"
while [ -n "$hex" ]; do
out="${out}%$(printf '%s' "$hex" | cut -c1-2)"
hex="$(printf '%s' "$hex" | cut -c3-)"
done
;;
esac
done
printf '%s' "$out"
}
zeropad_file_16() {
infile="$1"
outfile="$2"
size="$(wc -c < "$infile" | tr -d ' ')"
rem=$((size % 16))
cp "$infile" "$outfile"
if [ "$rem" -ne 0 ]; then
pad=$((16 - rem))
i=0
while [ "$i" -lt "$pad" ]; do
printf '\000' >> "$outfile"
i=$((i + 1))
done
fi
}
fetch_page() {
log "fetch login page: $LOGIN_URL"
wget -q -O "$HTML" \
--save-cookies "$COOKIE" \
--keep-session-cookies \
--header="User-Agent: $UA" \
"$LOGIN_URL"
}
build_form() {
sign="$(get_input_value sign)"
sta_vlan="$(get_input_value sta_vlan)"
sta_port="$(get_input_value sta_port)"
sta_ip="$(get_input_value sta_ip)"
nas_ip="$(get_input_value nas_ip)"
nas_name="$(get_input_value nas_name)"
last_url="$(get_input_value last_url)"
request_ip="$(get_input_value request_ip)"
device_mode="$(get_input_value device_mode)"
device_type="$(get_input_value device_type)"
device_os_type="$(get_input_value device_os_type)"
is_mobile="$(get_input_value is_mobile)"
iv="$(get_input_value iv)"
login_type="$(get_input_value login_type)"
account_type="$(get_input_value account_type)"
[ -n "$sign" ] || { echo "failed to parse sign" >&2; exit 1; }
[ -n "$iv" ] || { echo "failed to parse iv" >&2; exit 1; }
[ "${#iv}" -eq 16 ] || { echo "bad iv length: ${#iv}" >&2; exit 1; }
body="sign=$(urlencode "$sign")"
body="$body&sta_vlan=$(urlencode "$sta_vlan")"
body="$body&sta_port=$(urlencode "$sta_port")"
body="$body&sta_ip=$(urlencode "$sta_ip")"
body="$body&nas_ip=$(urlencode "$nas_ip")"
body="$body&nas_name=$(urlencode "$nas_name")"
body="$body&last_url=$(urlencode "$last_url")"
body="$body&request_ip=$(urlencode "$request_ip")"
body="$body&device_mode=$(urlencode "$device_mode")"
body="$body&device_type=$(urlencode "$device_type")"
body="$body&device_os_type=$(urlencode "$device_os_type")"
body="$body&is_mobile=$(urlencode "$is_mobile")"
body="$body&iv=$(urlencode "$iv")"
body="$body&login_type=$(urlencode "$login_type")"
body="$body&account_type=$(urlencode "$account_type")"
body="$body&user_account=$(urlencode "$USER_ACCOUNT")"
body="$body&user_password=$(urlencode "$USER_PASSWORD")"
printf '%s' "$body" > "$RAW"
printf '%s' "$iv" > "$TMP_DIR/iv.txt"
}
encrypt_body() {
iv_ascii="$(cat "$TMP_DIR/iv.txt")"
iv_hex="$(printf '%s' "$iv_ascii" | hexdump -ve '1/1 "%.2x"')"
key_hex="$(printf '%s' '1234567887654321' | hexdump -ve '1/1 "%.2x"')"
zeropad_file_16 "$RAW" "$PADDED"
openssl enc -aes-128-cbc -K "$key_hex" -iv "$iv_hex" -nopad -base64 -A \
-in "$PADDED"
}
do_login() {
iv="$(cat "$TMP_DIR/iv.txt")"
enc="$(encrypt_body)"
log "post login action: $POST_URL"
wget -q -O "$RESP" \
--load-cookies "$COOKIE" \
--keep-session-cookies \
--header="User-Agent: $UA" \
--header="X-Requested-With: XMLHttpRequest" \
--header="Origin: $BASE_URL" \
--header="Referer: $LOGIN_URL" \
--header="Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
--post-data="data=$(urlencode "$enc")&iv=$(urlencode "$iv")" \
"$POST_URL"
cat "$RESP"
echo
}
fetch_page
build_form
do_login
介绍
这是一个能够自动登录GiWifi校园网的shell脚本,在原作者的基础上:
- 适配山东科技大学GIWIFI的接口、加密方式
- 增加适用于OpenWrt的开机自动运行配置
原作者: TwiceTry
使用
配置
路由器上面需要安装wget-ssl,bash(路由器自带的均为精简版,指令不全,会出现问题)和openssl-util
opkg update
opkg install bash
opkg install wget-ssl
opkg install openssl-util
运行
./giwifi.sh <username> <password> [baseUrl]
示例
chmod +x giwifi_new.sh
./giwifi_new.sh 12345678901 123456 http://10.100.100.2
开机运行
- 将giwifi.sh放到
/mnt下,推荐的目录结构如下:
/mnt/giwifi/
├─ giwifi_new.sh
└─ giwifi_log.txt
-
修改giwifi中的账号、密码
-
移动至
/etc/init.d/giwifi -
赋予权限
chmod +x /etc/init.d/giwifi -
加入开机自启动
/etc/init.d/giwifi enable -
直接运行测试
/etc/init.d/giwifi start或重启设备测试reboot
其它
Giwifi加密方式
明文字符串
-> 转成字节
-> 按 16 字节补 0
-> AES-128-CBC
-> Base64
多端设备
根据登录接口来说,可以在登录时伪装giwifi终端类型,此脚本是伪装成PC登录。
实测使用浏览器的开发者选项可以伪装成ipad,但不能伪装成apad
Giwifi:是高贵的苹果人,放行!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)