首页
壁纸
每日60s早报
直播
更多
关于
统计
Search
1
青龙面板安装教程
31 阅读
2
通过ai进行某大学洗澡软件sign值分析
14 阅读
3
kingosoft高校智慧校园教学管理平台登录
10 阅读
4
雨课堂websocket登录获取登录数据
8 阅读
生活日常
技术分享
登录
Search
标签搜索
逆向分析
青龙面板
日落晚阳.
累计撰写
4
篇文章
累计收到
2
条评论
首页
栏目
生活日常
技术分享
页面
壁纸
每日60s早报
直播
关于
统计
搜索到
4
篇与
的结果
2025-12-26
kingosoft高校智慧校园教学管理平台登录
request登录kingosoft高校智慧校园教学管理平台简单的花一小时写了一个登录获取token剩下的根据token都能实现import re import requests import base64 import hashlib class KingoDES: """JS自定义DES加密(核心逻辑精准还原)""" def __init__(self): # DES S盒(与JS完全一致) self.sbox = [ [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]], [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]], [[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]], [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]], [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]], [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]], [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]], [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]] ] self.loop = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] # 轮移位次数 def str_to_bt(self, s): """字符串→64位比特数组""" bt = [0] * 64 for i in range(min(len(s), 4)): k = ord(s[i]) for j in range(16): bt[16 * i + j] = (k // (2 ** (15 - j))) % 2 return bt def enc(self, data_byte, key_byte): """单块DES加密(核心逻辑)""" # 生成子密钥 key = [0] * 56 for i in range(7): for j in range(8): key[i * 8 + j] = key_byte[8 * (7 - j) + i] keys = [] for i in range(16): # 循环左移 for _ in range(self.loop[i]): temp_l, temp_r = key[0], key[28] key[:27] = key[1:28] key[27] = temp_l key[28:55] = key[29:56] key[55] = temp_r # 压缩置换 keys.append([ key[13], key[16], key[10], key[23], key[0], key[4], key[2], key[27], key[14], key[5], key[20], key[9], key[22], key[18], key[11], key[3], key[25], key[7], key[15], key[6], key[26], key[19], key[12], key[1], key[40], key[51], key[30], key[36], key[46], key[54], key[29], key[39], key[50], key[44], key[32], key[47], key[43], key[48], key[38], key[55], key[33], key[52], key[45], key[41], key[49], key[35], key[28], key[31] ]) # 初始置换 ip = [0] * 64 for i in range(4): m, n = 1 + 2 * i, 0 + 2 * i for j in range(8): k = 7 - j ip[i * 8 + j] = data_byte[k * 8 + m] ip[i * 8 + j + 32] = data_byte[k * 8 + n] ip_l, ip_r = ip[:32], ip[32:] # 16轮迭代 for i in range(16): temp_l = ip_l.copy() ip_l = ip_r.copy() # 扩展置换 ep = [0] * 48 for j in range(8): ep[j * 6] = ip_r[31] if j == 0 else ip_r[j * 4 - 1] ep[j * 6 + 1:j * 6 + 5] = ip_r[j * 4:j * 4 + 4] ep[j * 6 + 5] = ip_r[0] if j == 7 else ip_r[j * 4 + 4] # 异或+S盒+P盒 xor1 = [a ^ b for a, b in zip(ep, keys[i])] sbox_byte = [0] * 32 for j in range(8): block = xor1[j * 6:j * 6 + 6] row = block[0] * 2 + block[5] col = block[1] * 8 + block[2] * 4 + block[3] * 2 + block[4] val = self.sbox[j][row][col] for k in range(4): sbox_byte[j * 4 + 3 - k] = val % 2 val //= 2 # P盒置换 p = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] pbox = [sbox_byte[k] for k in p] ip_r = [a ^ b for a, b in zip(pbox, temp_l)] # 最终置换 fp = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24] final_data = ip_r + ip_l return [final_data[k] for k in fp] def des_enc(self, data, key): """完整DES加密(分块处理)""" # 密钥分块 key_bytes = [] for i in range(0, len(key), 4): key_bytes.append(self.str_to_bt(key[i:i + 4])) # 数据分块加密 enc_data = "" hex_tab = "0123456789ABCDEF" for i in range(0, len(data), 4): temp_byte = self.str_to_bt(data[i:i + 4]) for kb in key_bytes: temp_byte = self.enc(temp_byte, kb) # 比特数组转十六进制 hex_str = "" for j in range(16): bt = ''.join([str(temp_byte[j * 4 + k]) for k in range(4)]) hex_str += hex_tab[int(bt, 2)] enc_data += hex_str return enc_data class KingoLogin: def __init__(self): self.session = requests.Session() self.urls = { "encrypt": "http://你的学校域名/custom/js/SetKingoEncypt.jsp", "login": "http://你的学校域名/cas/logon.action" } self.headers = { 'Host': "124.89.76.198:8002", 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 Chrome/57.0.2987.98 Safari/537.36", 'Referer': "http://你的学校域名/cas/login.action", 'Content-Type': "application/x-www-form-urlencoded; charset=UTF-8" } self.des = KingoDES() self.deskey = self.nowtime = self.ssessionid = "" def get_dynamic_params(self): """提取动态密钥/时间戳/SessionID""" try: res = self.session.get(self.urls["encrypt"], headers=self.headers, timeout=10) self.deskey = re.search(r'_deskey\s*=\s*["\'](.*?)["\'];', res.text).group(1) self.nowtime = re.search(r'_nowtime\s*=\s*["\'](.*?)["\'];', res.text).group(1) self.ssessionid = re.search(r'_ssessionid\s*=\s*["\'](.*?)["\'];', res.text).group(1) return True except Exception as e: print(f"提取参数失败: {e}") return False def encrypt_data(self, username, password, rand=""): """生成登录加密参数(1次Base64)""" # 1. 用户名加密:1次Base64 + 1次拼接 user_enc = base64.b64encode(f"{username};;{self.ssessionid}".encode()).decode() user_enc = f"{user_enc};;{self.ssessionid}" # 2. 密码加密:MD5嵌套 md5_pwd = hashlib.md5(password.encode()).hexdigest() md5_rand = hashlib.md5(rand.lower().encode()).hexdigest() if rand else hashlib.md5(b"").hexdigest() pwd_enc = hashlib.md5((md5_pwd + md5_rand).encode()).hexdigest() # 3. 拼接初始参数 + DES+Base64加密 initial_params = ( f"_u={user_enc}&_p={pwd_enc}&randnumber={rand}&isPasswordPolicy=1" f"&txt_mm_expression=12&txt_mm_length={len(password)}&txt_mm_userzh=0" f"&hid_flag=1&hidlag=1&hid_dxyzm=0" ) # 4. 生成token + 最终参数 md5_params = hashlib.md5(initial_params.encode()).hexdigest() token = hashlib.md5((md5_params + hashlib.md5(self.nowtime.encode()).hexdigest()).encode()).hexdigest() des_enc = self.des.des_enc(initial_params, self.deskey) # 模拟JS的utf16to8 + Base64 def utf16to8(s): out = [] for c in s: cc = ord(c) if cc <= 0x7F: out.append(cc) elif cc <= 0x7FF: out.extend([0xC0 | ((cc >> 6) & 0x1F), 0x80 | (cc & 0x3F)]) else: out.extend([0xE0 | ((cc >> 12) & 0x0F), 0x80 | ((cc >> 6) & 0x3F), 0x80 | (cc & 0x3F)]) return bytes(out) b64_enc = base64.b64encode(utf16to8(des_enc)).decode() return f"params={b64_enc}&token={token}×tamp={self.nowtime}&deskey={self.deskey}&ssessionid={self.ssessionid}" def login(self, username, password, rand=""): """执行登录""" if not self.get_dynamic_params(): return False try: login_data = self.encrypt_data(username, password, rand) res = self.session.post(self.urls["login"], headers=self.headers, data=login_data, timeout=10) print(f"响应码: {res.status_code}\n响应内容: {res.text}") # 尝试解析JSON try: result = res.json() if result.get("status") == "200": print(f"登录成功!跳转地址: {result.get('result')}") return True except: print("响应非JSON格式") return False except Exception as e: print(f"登录失败: {e}") return False if __name__ == "__main__": # 替换为实际账号密码 KingoLogin().login("你的账号", "你的密码", "")
2025年12月26日
10 阅读
0 评论
0 点赞
2025-12-03
雨课堂websocket登录获取登录数据
前言本内容仅用于技术交流学习,严禁商用;爬取行为需遵守网站协议及法律规定,如有侵权请联系删除。雨课堂网页版的登录流程在https://www.yuketang.cn/web?next=/v2/web/index&type=3页面加载完毕后,客户端与服务端建立websocket链接。随即客户端发送一段数据,用于请求微信二维码。服务端拿到数据后反馈二维码相关信息。并每隔一段时间重新发送一次二维码信息。客户端根据信息去请求二维码图片。用户扫码,由移动客户端发送信息至服务端确认用户正在登录。服务端再通过websocket发送登录的相关信息回客户端。客户端拿到登录的相关信息后post到login接口进行登录,至此登录成功。具体步骤一、找到websocket接口雨课堂的websocket接口为wss://www.yuketang.cn/wsapp/二、查看websocket数据交流情况数据内容长度时间{"op":"requestlogin","role":"web","version":1.4,"type":"qrcode","from":"web"}7723:06:57.966{"op":"requestlogin","loginid":"7e3115fc-ce02-439f-9e95-f7cc797f6b13","expire_seconds":60,"ticket":"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQG_8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUGRSMEZUN2pkczExNENHU2hGY3EAAgSmLy1pAwSAOgkA","qrcode":"http://weixin.qq.com/q/02PdR0FT7jds114CGShFcq"}30623:06:57.996登录之后发现多了一串数据{ "subscribe_status": true, "AppOpenID": "", "profile_edit_status": false, "UserID": "", "DateJoined": "2025-03-22T00:12:43", "Role": 0, "LastLogin": "2025-12-03T23:22:35", "Department": "", "WeixinUnionID": "", "LastLoginIP": "", "noRecArticle": true, "Auth": "", "ppt_config_data": {}, "Nickname": "", "School": "", "Name": "", "Language": "zh-cn", "Gender": 0, "YearOfBirth": null, "is_self_set": false, "Avatar": "", "Position": null, "subscribe_message_templates": [], "MinaOpenID": "", "isBind": true, "user_on_lessons": [], "AndroidOpenID": "", "op": "loginsuccess", "loginid": "***" }关键信息是里面的UserID和Auth三、登录将之前获得的UserID和Auth POST到https://www.yuketang.cn/pc/web_login获取sessionid与csrftoken。然后就登录成功了下面是代码import requests import websocket import json import cv2 as cv import numpy as np session = requests.Session() user_info = {} def on_message(ws, msg): global user_info user_info = json.loads(msg) if 'subscribe_status' in user_info: ws.close() return # 显示二维码 resp = session.get(user_info['ticket']) img = cv.imdecode(np.array(bytearray(resp.content), np.uint8), cv.IMREAD_UNCHANGED) cv.imshow('登录码', img) cv.waitKey(0) cv.destroyAllWindows() # 建立WS连接 ws = websocket.WebSocketApp("wss://www.yuketang.cn/wsapp/", on_message=on_message, on_error=lambda ws, e: print(e)) ws.on_open = lambda ws: ws.send(json.dumps({"op":"requestlogin","role":"web","version":1.4,"type":"qrcode","from":"web"})) ws.run_forever() req = session.post("https://www.yuketang.cn/pc/web_login",data=json.dumps({'UserID':user_info['UserID'],'Auth':user_info['Auth']})) print(req.json()) # 获取课程列表 req = session.get("https://www.yuketang.cn/v2/api/web/courses/list?identity=2") print(json.loads(req.content))长江雨课堂,荷花雨课堂等一样只需要改个前缀即可
2025年12月03日
8 阅读
1 评论
0 点赞
2025-11-13
通过ai进行某大学洗澡软件sign值分析
前言什么是sign值?可以理解为检验,每一个数据包中有sign值就意味着可以被检验,当我们一旦篡改数据,校验值不正确,则会失败。准备工作需要有任意抓包软件并且配置好,然后就是app分析软件(JEB,jadx,mt管理器,或者其他的都可)开始打开抓包软件这里发现密码和sign都被加密了随便改请求数据发现都提示重复请求逆向破解app先看是否被加固,运气不错,并没有被加固,省下了很多工夫全局搜素sign,发现七千多个,根本找不完,限制包名还有1300多个,还是太多了我们换种方法根据之前的逆向其他案例,然后我就自己搜了一下请求里面的timestamp,也算是撞上了正确答案了当然用ai分析也是这几个关键值看了一下,这个最像,点进去看了一下,果然,这几个关键值都在,应该就是这个没错了让ai分析一下这段代码可以看出来sign是怎么生成的了格式为「时间戳 \nrequestid\n 请求体 JSON\n」而且是rsa加密生成 signai 也说了用 RSAUtils.sign 这个方法进行的加密,跳转过去看看,可以发现已经有了rsa私钥并且将签名结果进行 Base64 编码但是发现登录的密码也有加密,搜索password发现有个encrypt函数,点进去看看,发现也是rsa加密并且也已经给了密钥至此sign已经分析完毕,接下来就是写加密函数了进行加密请求让ai写一个rsa加密,分别进行加密sign和password进行请求最后发现也是成功了
2025年11月13日
14 阅读
0 评论
0 点赞
2025-01-19
青龙面板安装教程
教程开始:1. 前置准备需提前在服务器安装 Docker 环境,Docker 安装教程可参考官方文档或网络公开教程,完成后再进行以下操作。2. Docker拉取青龙镜像进行安装以下代码什么什么都不用动直接复制到服务器终端粘贴运行!旧版青龙面板拉库连接docker pull whyour/qinglong:2.11.3 //旧版 2.11.3为指定的版本docker run -dit \ -v $PWD/ql/config:/ql/config \ -v $PWD/ql/log:/ql/log \ -v $PWD/ql/db:/ql/db \ -v $PWD/ql/scripts:/ql/scripts \ -p 5700:5700 \ --name qinglong \ --hostname qinglong \ --restart always \ whyour/qinglong:2.11.3新版青龙面板拉库连接docker pull whyour/qinglong:latest //新版 latest为最新版本docker run -dit \ -v $PWD/ql/config:/ql/config \ -v $PWD/ql/log:/ql/log \ -v $PWD/ql/db:/ql/db \ -v $PWD/ql/scripts:/ql/scripts \ -p 5700:5700 \ --name qinglong \ --hostname qinglong \ --restart always \ whyour/qinglong:latest进入青龙面板地址http://ip地址:5700多开青龙指令sudo docker run -dit \ -v $PWD/ql2/config:/ql/config \ -v $PWD/ql2/log:/ql/log \ -v $PWD/ql2/db:/ql/db \ -p 15700:5700 \ --name qinglong2 \ --hostname qinglong2 \ --restart always \ whyour/qinglong:latest多开说明:通过修改目录(ql2)和端口(15700)区分不同面板,访问地址为http://服务器IP:15700
2025年01月19日
31 阅读
0 评论
1 点赞