【网页逆向】东莞理工学院版优学院快速进入
东莞理工学院中央认证逻辑逆向分析
前言:每次进入东莞理工学院版优学院要登录7次,真不明白怎么想的,去qq群里反馈了也不改
那行呗,开逆
一、登陆流程分析
首先我觉得这个登陆流程很诡异,具体来说
lms.dgut.edu.cn (优学院) 因为没登陆被踢出来
↓
application.dgut.edu.cn (应用中心)
↓
auth.dgut.edu.cn (认证中心)
↓
application.dgut.edu.cn (应用中心)
↓
application.dgut.edu.cn/#/index (工作台)
↓
lms.dgut.edu.cn (优学院)
当然可以做一个模拟点击,但是不够优雅
二、开始抓包
首先我们打开官网进行抓包,把登陆过程一通分析,发现只有这个包是重要的

具体内容如下:(账号部分使用xxx代替)
POST /authserver/login HTTP/1.1
Host: auth.dgut.edu.cn
Connection: keep-alive
Content-Length: 2454
Cache-Control: max-age=0
sec-ch-ua: "Not;A=Brand";v="8", "Chromium";v="150", "Google Chrome";v="150"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36
Origin: https://auth.dgut.edu.cn
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://auth.dgut.edu.cn/authserver/login
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cookie: route=e0c866529e27fd2821fa205a604dfd9e;
JSESSIONID=A2900C1F62D3D100FF57E688E2F195BA;
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=zh_CN;
MULTIFACTOR_USERS=uqRZ/RtsPUbpFa7lYjXqGrDMPsZD6SB0dnTKJb/2CX64xaMTM7nqTMhXtX0x4+5XxAkFqnNcbl5bRbnwaYPh45ZwvG2oNiyWPdXuaX0y2qPFMAcGVDiCMdsNVmeIP8RV; route=69008ebf35388d0d897186cd9c69f5ca;
app_login_way=unifiedEntry;
loginFrom=https%3A%2F%2Fapplication.dgut.edu.cn%2F%23%2Flogin;
AUTHORIZATION=9F170DBD3AC25F5213B32463251DCE52;
token=9F170DBD3AC25F5213B32463251DCE52;
lms_user_org=3755; Admin-Token=admin-token; ROLES=stu;
USER_INFO=%7B%22orgName%22%3A%22%u4E1C%u839E%u7406%u5DE5%u5B66%u9662%22%2C%22headimage%22%3A%22https%3A%2F%2Flms.dgut.edu.cn%2Fuobs%2Fview%2Fresources%2Fharmonyos%2Fheader%2F12460097_2025-10-20_19-58-177.jpg%22%2C%22institutionId%22%3A%2217645%22%2C%22roleId%22%3A9%2C%22sex%22%3A%221%22%2C%22userNo%22%3A%222024xxxxxxxxx%22%2C%22userId%22%3A12460097%2C%22orgId%22%3A3755%2C%22authorization%22%3A%229F170DBD3AC25F5213B32463251DCE52%22%2C%22studentId%22%3A%222024xxxxxxxxx%22%2C%22loginName%22%3A%22dgut2024xxxxxxxxx%22%2C%22grade%22%3A%222024%22%2C%22name%22%3A%22%u5510%u9AD8%u5B87%22%2C%22uversion%22%3A2%7D;
USERINFO=%7B%22orgName%22%3A%22%E4%B8%9C%E8%8E%9E%E7%90%86%E5%B7%A5%E5%AD%A6%E9%99%A2%22%2C%22headimage%22%3A%22https%3A%2F%2Flms.dgut.edu.cn%2Fuobs%2Fview%2Fresources%2Fharmonyos%2Fheader%2F12460097_2025-10-20_19-58-177.jpg%22%2C%22institutionId%22%3A%2217645%22%2C%22roleId%22%3A9%2C%22sex%22%3A%221%22%2C%22userNo%22%3A%222024xxxxxxxxx%22%2C%22userId%22%3A12460097%2C%22orgId%22%3A3755%2C%22authorization%22%3A%229F170DBD3AC25F5213B32463251DCE52%22%2C%22studentId%22%3A%222024xxxxxxxxx%22%2C%22loginName%22%3A%22dgut2024xxxxxxxxx%22%2C%22grade%22%3A%222024%22%2C%22name%22%3A%22%E5%94%90%E9%AB%98%E5%AE%87%22%2C%22uversion%22%3A2%7D;
smartClassRoomHomePageUrl=https://zhlb.dgut.edu.cn;
smartClassRoomApiUrl=https://zhlb.dgut.edu.cn/api;
recordState=1; ROOT_ORIGIN=appapi; happyVoyage=/+/KEXxk848Tr+oiBazmv4KFt3FADVsTX548qxBbecWrtyTE2y/5oMtVhofid9JjWg8trsUUZikUDRcp3FxNaibC9atNrDlusEbU8A2rYGZDFw53bv5JkQCBOJk19QR5bG/EPvoMWz+87+VaSXEBCT5FuhvqS1QAzuzgBLZx3D8=;
WIS_PER_ENC=ZavKZy0ucTS5T9L6;
REFERERCE_TOKEN=1c875c3f-286e-4b41-af53-e055b8d6300f
username=2024xxxxxxxxx&
password=m3rkO4VN0X3pytHNiXDf15KcGwYpiOCMqI9PUYXuFsfbRDzmb8KTQxeh5GGHQAKLVsJqLXd%2BZn2wA1X%2FU5rG7k2bbsWEt7ii%2BhP8OFHKq38%3D&captcha=&_eventId=submit&cllt=userNameLogin&dllt=generalLogin<=&
execution=72fd1865-4e06-4cbf-b02d-0aa48ed395c4_ZXlKaGJHY2lPaUpJVXpVeE1pSjkuWkxGb0xjWisyNU5yeklPY1pVOVFxUWJJbWd2dnNtYTBzQjJrQ0dmbVFzNEM2aDRWSEY4RmgwOEViL0YxbHRtRDFIZEpVcU90RndzWjJ2ZHFEc0hKV1lBcUZGWlo0b2dMS1hHSU11S2p2a001aCthU0NnVUxaYlJxdnlCZS92OTdmNGI0TkxoTHhqdHdQOXM5QWpvMlpzMGhQdE9yVFkzdUoyK1NRSm10czhQMWVtL0JVN2tKVDErVFBuRVA5djBpbVFualhEK3N0VTBsTkJhNDh4U2pFU3BRVUNneksyU2F1UjRvQWVua0taUG4rQ3M1MTF4aENGRVU5Y1RCVTlZMjZVSWdxRndaQS9NczJLOEQ0R0cvbFVMc1lPVDg1TDJpeXMvWVlYN1hGcG1kMFFNeUM2cnhFbEtGRVNCNjJMRytzc3JtUlRXNlo1QW5KS2FuNkRHL05rUmFpQ25xYkZ0NDFWU2tiUEJ2MTlOMERVQlRZTStKbDFtL1cwVnkyTFRkNWN5ZUYrNXZuZUkwQTFLdGNvL2QyemJ1cGdYaktXTlRFdHNJYWROeGdOK1J2YlpPblRXZEc0YmdERXQ5ZW1TRDJIYkxmVk9ycjhLQ1YvTW1mL1BwVVpVRGlVcXgvOWJXNExsb0Via0d6a05pYUlkZWk3RUFWeHRPajNsc0wrdmxhWndhUXpsNkdxZnRRcGxFMU9QZVlRTkE1Nlc1bGRjdmVPamxocDlhSTNac2ZzcGpDbGRsRjN5bTFxdDZ4MkE3aGNEeUFKbzVaQnluWk1UdW4vdDlTenJMcVZHcW54c0F6dVFpc0YwbjZuTjNycW1EVFBmRmlveGNlMStGWmxWYVpqRmh5VTJZZy9YdnRVZHZoOE9UMm1vMlE3NXA5ZFdzNlVYclREdUlrejMzbDZzRkZrUUdVV3UzVmk3TlNRVW9YWEZ5eUxhdEo3ZHV3ZUJ0eGhFL2JnVzZpVDdqVUZHOEo2aEJPTjVibXVCODBTM0NLWDJFNXUrT1hVWUE5VXBYR2s2UmJtQlpiOCtGd3JrMGNYcHAxb1BNSklPUEVoWWxKcDhRblBtQ0hLODg4MEh2TkVhYS9ZVHo1WlhjYW9VZE1VdEdYallTdHZVUlJ4emdIdGk2dDVsSExjQ3BJdCtzd2UyK1hNeWs5VmVzRmxZSDJGMUpoeWtoNW9BVHdzenlacFhKTitRODZTeVowNzRsVGZWTjJPVG5FRHczNXJCNUkrSHRnZlZveXg0MU1ROFFJemNUYTVtRDhlOGc1NmpWcDNoeDBhNUNrOG9TWlc2Nm9wMW1SYnJkblhwWXZRYTNlelNjK2xSQkNCdWdIVnRoblZpQW95Mm1nWXBxRTA4UFlkU1NXWWxJcVgxMUE3ZGFnMnNCM2RlWUtudkpiOGk1RnZSV3FWMXVRUDBIams5L1kwcUtvUmh3MHE5eDFwUHRvamlmVjRleFE5Q3plaHJtcHdzV0lRdVFBckRGUkUzS0ZBK3hHb2NVemwvNzEyeHJFYWQxTEMxN21weFNqbWtqSlROUjFuYkkxc2NwV2hHVk1MZ21DRERDcithVmh1c0plS0g4Z1pRVnMxRzNxSDRjc1l2STBUYk1WdVVoV1VWNEtGQ0owS3duZlBjelRBOXozQ2pXdmo4NkV4SGJRdHhWeDBJeTBsbXM0WlhEZlVpMnlYL0FvbGpDQlJzaXZidWpTVXlUZ0VZN0t1QktydFBRS1JSZlN4UFhOMVU2Q2E1Z1NMUGh1d0tVSnlQYzYxVDRldEJNQzFnaUpYRVc5TTduMUtwSWRoNEdudkZqeFlBRjNqSm4xdnV5MzR5TzVYNlFVNkI1WmZOZ240b3U5ZmdQVU5TVmVmcDk5dldyUkVPQnM2MGlzTmg5WmZnZkE2UTlRaWdiRHJ6NFBMRHprbEY4YkpINERWNmJwMjh5QXpiUGE2elp5OW9VbFJzOFQ0TTlzSTl1TldScUxFR1lWSTFCZFIzeDJYZktrT1Q5YXdZbmRHelJrbXhreVg3WmZINFlVeFRFSUxJMEJnTGREVGxvLi1pQjVNMGFnWW9PRE5WM2x2cnNMMDZuZkJvVmlIMzZKOXZLQUVVM0FWaFRpZm5tNHFCVzdITXBMTThsUklJZ0xHZUozYzIzTGN0ME1ndGJ1TDlqZFRR
这个就是主要的登陆包,首先别害怕这一大堆参数,我们从cookie看起,虽然看起来一大堆,但是我们最开始一定是不携带cookie的,我们向上找第一个出现cookie的地方

发现几乎所有重要的响应里面都出现了Set-Cookie,所以我们可以利用python的requests.Session自动跟踪cookie功能就可以完成这个登陆流程。
然后我们看一下请求体部分,首先是username,这个是明文的,没什么好说的,password部分是加密的,我们需要逆向分析一下加密逻辑,其他参数我们先不管它。

打开测试工具,寻找按钮绑定的事件,定位到login.js

用户输入密码
↓
$(LOGIN_PASSWORD_ID).val() // 原始密码
↓
encryptPassword(密码, salt) // 加密
↓
$("#saltPassword").val(加密值) // 存入隐藏字段
↓
$(LOGIN_PASSWORD_ID).attr("disabled","disabled") // 禁用原始密码框
↓
$(".loginFromClass").submit() // 提交表单(saltPassword 被提交)
然后找encryptPassword,下断点,单步进入

发现到jquery-latest.min.js?v=20250429.142348,继续分析
// 入口函数(在 login.js 中调用)
encryptPassword(password, salt)
↓
encryptAES(password, salt)
↓
getAesString(randomString(64) + password, salt, randomString(16))
↓
CryptoJS.AES.encrypt(明文, 密钥, {iv: 向量, mode: CBC, padding: Pkcs7})
- 生成随机前缀:
randomString(64)- 生成64位随机字符串(字符集:ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678) - 拼接明文:随机字符串(64位) + 原始密码
- AES-CBC加密:
算法:AES(高级加密标准)
模式:CBC(Cipher Block Chaining)
填充:Pkcs7
密钥:传入的 salt 参数(即$("#pwdEncryptSalt").val()的值)
IV向量:16位随机字符串(通过randomString(16)生成) - 返回结果:CryptoJS加密后的字符串(Base64格式)
发现就是标准的AES-CBC加密,密钥未知,IV向量是随机生成的,所以每次加密结果都不一样,但是只要知道salt,就可以正确加密出密码。
下一步分析salt的来源,回溯调用链

发现是从一个隐藏字段pwdEncryptSalt中获取的,这个字段是在登录页面加载时由服务器生成并返回的,所以我们需要在模拟登录之前先访问一次登录页面,获取这个salt值。
回到抓包搜索pwdEncryptSalt,发现它是在登录页面的HTML中以隐藏字段的形式存在的

同时注意到后面的value值是一个随机字符串,这个就是刚刚要传递的execution参数。至于其它参数发现只要保持默认值就行了,没什么特别的意义。
三、编写脚本思路
- 创建一个
requests.Session对象,自动处理cookie - 访问登录页面,获取
salt和execution值 - 使用AES-CBC加密算法加密密码,生成加密后的密码字符串
- 构造登录请求的表单数据,包含用户名、加密后的密码、
execution等参数
貌似这样就好了,但是此时直接访问lms.dgut.edu.cn还是会直接被踢出
三、中央认证跳转原理
现在我们已经成功模拟了登录流程,获取了认证中心的cookie,但是直接访问优学院还是会被踢出,这个时候我们需要分析一下中央认证的跳转原理。
首先我们在登陆时候,请求的并不是https://auth.dgut.edu.cn/authserver/login 而是 https://auth.dgut.edu.cn/authserver/login?service=https%3A%2F%2Fapplication.dgut.edu.cn%2Fappapi%2Fcas%2Ffromcas 这个URL中包含了一个service参数,这个参数指定了认证成功后要跳转的目标URL,也就是application.dgut.edu.cn,这个URL是认证中心和优学院之间的桥梁。同时抓包证据也表明认证成功后会先跳转到application.dgut.edu.cn,然后再由application.dgut.edu.cn跳转到优学院。
那么如果直接把这个service参数改成优学院的URL,直接访问认证中心,是否就能直接跳转到优学院呢?答案是不能的,你猜猜为什么,这里就是dgut抽象的地方了
答案:因为lsm.dgut.edu.cn(优学院)和auth.dgut.edu.cn(认证中心)之间的信任关系是通过application.dgut.edu.cn(应用中心)来建立的,认证中心只会信任来自应用中心的请求,而不会直接信任来自优学院的请求,所以如果直接访问认证中心,认证中心会认为这是一个不受信任的请求,无法建立信任关系,自然也就无法跳转到优学院了。
说人话就是:认证中心只会接受来自应用中心的请求,而不会直接接受来自优学院的请求,所以我们必须先访问认证中心,获取认证中心的cookie,然后再访问应用中心,建立信任关系,最后才能访问优学院。
虽然说这里只有短短的一句话,但是在这里吃屎了不少,请看vcr:
这里是从认证中心出来时候cookie:

只要求设置两个:JSESSIONID、AUTHORIZATION,但是正常情况下要访问的话,要带上如图左边的一大堆奇奇怪怪的,尤其是这个USER_INFO和USERINFO两个一模一样的神人字段
那么如何带上这两个字段呢,答案是:中央认证回到应用中心,最后访问优学院,这样就能带上应用中心的cookie了。


四、浏览器初次登陆验证
自从上次被“红客认证”交了edu后,多了一个二次认证,陌生的浏览器要求验证,验证方式是发送验证码到绑定的手机号上,输入验证码后才能继续访问。
这个其实问题不大,按照流程走完https://auth.dgut.edu.cn/authserver/login,如果不是301重定向,说明不需要验证,直接访问目标系统就好了,如果是200,说明需要验证,提示用户输入验证码,完成验证后继续访问目标系统即可
五、具体python代码
from bs4 import BeautifulSoup
import requests
import random
import base64
from urllib.parse import urljoin
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
SERVER_HOST = r"https://auth.dgut.edu.cn/authserver/login?service=https%3A%2F%2Fapplication.dgut.edu.cn%2Fappapi%2Fcas%2Ffromcas"
DIT_HOST = r"https://lms.dgut.edu.cn/courseweb/ulearning/index.html"
# 密码加密部分
AES_CHARS = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"
def random_string(length: int) -> str:
return "".join(random.choice(AES_CHARS) for _ in range(length))
def encrypt_password(password: str, salt: str) -> str:
"""与 encrypt.js 的 encryptPassword 等价:AES-CBC + PKCS7 + Base64。"""
if not salt:
return password
try:
key = salt.strip().encode("utf-8")
iv = random_string(16).encode("utf-8")
plaintext = (random_string(64) + password).encode("utf-8")
padder = padding.PKCS7(128).padder()
padded = padder.update(plaintext) + padder.finalize()
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
encryptor = cipher.encryptor()
ciphertext = encryptor.update(padded) + encryptor.finalize()
return base64.b64encode(ciphertext).decode("utf-8")
except Exception:
return password
USERNAME = "2024xxxxxxxxx"
PASSWORD = "your_password_here"
def fetch_login_context(session: requests.Session) -> tuple[str | None, str | None, requests.Response]:
req = session.get(SERVER_HOST, allow_redirects=False)
soup = BeautifulSoup(req.text, "html.parser")
pwd_encrypt_salt_node = soup.find("input", {"id": "pwdEncryptSalt"})
execution_node = soup.find("input", {"id": "execution"})
pwd_encrypt_salt = str(
pwd_encrypt_salt_node["value"]) if pwd_encrypt_salt_node else None
execution = str(execution_node["value"]) if execution_node else None
return pwd_encrypt_salt, execution, req
def request_mfa_code(session: requests.Session, username: str) -> None:
url = "https://auth.dgut.edu.cn/authserver/dynamicCode/getDynamicCodeByReauth.do"
body = {
"userName": username,
"authCodeTypeName": "reAuthDynamicCodeType",
}
session.post(url, data=body)
def submit_mfa(session: requests.Session) -> bool:
print("请输入手机验证码进行多因子认证(MFA)。")
code = input("验证码: ")
url = "https://auth.dgut.edu.cn/authserver/reAuthCheck/reAuthSubmit.do"
body = {
"service": "",
"reAuthType": "3",
"isMultifactor": "true",
"password": "",
"dynamicCode": code,
"uuid": "",
"answer1": "",
"answer2": "",
"otpCode": "",
"skipTmpReAuth": "true",
}
response = session.post(url, data=body)
return "认证成功" in response.text
def print_all_cookies(session: requests.Session) -> None:
print("All Session Cookies:")
for cookie in session.cookies:
print(
f"- name={cookie.name}, value={cookie.value}, domain={cookie.domain}, path={cookie.path}"
)
def follow_ticket_and_print_cookies(session: requests.Session, ticket_url: str) -> None:
final_resp = session.get(ticket_url, allow_redirects=True)
print("Final Service URL:", final_resp.url)
print("Final Service Status Code:", final_resp.status_code)
print_all_cookies(session)
def run_login_flow(session: requests.Session, username: str, password: str) -> None:
while True:
pwd_encrypt_salt, execution, login_page_resp = fetch_login_context(
session)
if not pwd_encrypt_salt or not execution:
location = login_page_resp.headers.get("Location")
if login_page_resp.status_code in (301, 302, 303, 307, 308) and location:
ticket_url = urljoin(SERVER_HOST, location)
print("Result: 当前 session 已认证,拿到了服务跳转地址。")
print("Ticket URL:", ticket_url)
follow_ticket_and_print_cookies(session, ticket_url)
return
print("Result: 当前响应已不是登录表单页,说明这个 session 可能已经通过认证或已跳到后续系统。")
print("Current URL:", login_page_resp.url)
print("Status Code:", login_page_resp.status_code)
return
encrypted_password = encrypt_password(password, pwd_encrypt_salt)
body = {
"username": username,
"password": encrypted_password,
"captcha": "",
"_eventId": "submit",
"cllt": "userNameLogin",
"dllt": "generalLogin",
"lt": "",
"execution": execution,
}
# print("Session Default Headers:", session.headers)
# print("Session Cookies Before POST:", session.cookies.get_dict())
# print("Request Body:", body)
login_response = session.post(
SERVER_HOST, data=body, allow_redirects=False)
print("Sent Request Headers:", dict(login_response.request.headers))
print("Sent Cookie Header:", login_response.request.headers.get("Cookie"))
print("Status Code:", login_response.status_code)
print("Location:", login_response.headers.get("Location"))
if login_response.status_code not in (301, 302, 303, 307, 308):
text = login_response.text
if "showErrorTip" in text or "密码错误" in text or "用户名或密码" in text:
print("Result: 用户名或密码校验失败。")
else:
print("Result: 未命中明确标识,请检查响应页面内容。")
return
next_url = urljoin(
SERVER_HOST, login_response.headers.get("Location", ""))
print("Next URL:", next_url)
final_resp = session.get(next_url)
text = final_resp.text
print("Final Status Code:", final_resp.status_code)
if "多因子认证" in text or "reAuthType" in text or "isMultifactor" in text:
print("Result: 用户名密码已通过,但被要求进行多因子认证(MFA)。")
request_mfa_code(session, username)
if submit_mfa(session):
print("Result: 多因子认证成功,使用同一个 session 重新发起登录流程。")
continue
print("Result: 多因子认证失败,登录未完成。")
return
if "showErrorTip" in text or "密码错误" in text or "用户名或密码" in text:
print("Result: 用户名或密码校验失败。")
return
print("Result: 已跳转,可能已登录成功或进入其他后续流程。")
print(f"跳转到{next_url}")
follow_ticket_and_print_cookies(session, next_url)
return
session = requests.Session()
# 尝试访问,禁止跟踪重定向,以验证是否需要登录
req = session.get(
DIT_HOST, allow_redirects=False)
if req.status_code == 301:
print("需要登陆")
input("请按回车键继续...")
run_login_flow(session, USERNAME, PASSWORD)
else:
print("不需要登录,直接访问目标系统,响应状态码:", req.status_code)
# 可以直接访问目标 https://lms.dgut.edu.cn/organization/index.html
# 查看DIT_HOST的响应状态码和内容,验证是否成功访问了目标系统
response = session.get(
DIT_HOST)
print("访问DIT_HOST的状态码:", response.status_code)
if response.status_code == 200:
print("成功访问了DIT_HOST,响应内容前500字符:")
print(response.text[:500])
else:
print("未能成功访问DIT_HOST,可能没有正确登录或会话失效。")
六、变成浏览器插件
现在python跑通了,那么就要把这个流程变成浏览器插件
我最开始考虑的是篡改猴,但是我发现拦截不了301重定向,所以只能自己写一个插件了,插件的核心逻辑就是在用户访问优学院的时候,先访问认证中心,获取cookie,然后再访问优学院,这样就能带上认证中心的cookie了。
这方面压力一下GPT就好了(
反正流程自己摸清楚了,剩下的就是照着葫芦画瓢了,主要就是在用户访问优学院的时候,先访问认证中心,获取cookie,然后再访问优学院,这样就能带上认证中心的cookie了。
这里我发现对于二次认证十分不稳定,于是要求一定要求用户先登录一次,完成二次认证后再使用插件,这样就能保证插件的稳定性了。
七,总结:
就不能一次登陆吗,不能搞点正常的登陆吗
一页一页,这就和普通的edu没有区别了,我必须让你看看我辛辛苦苦作出的(根本没人用)的应用中心啊,这是特制的
插件链接:
『来自123云盘用户的分享』dgut进入优学院
链接:https://1818161038.share.123865.com/123pan/dlcdjv-chqY?pwd=FfUq#
提取码:FfUq

浙公网安备 33010602011771号