首页
文章分类
逆向网安
中英演讲
杂类教程
学习笔记
前端开发
汇编
数据库
.NET
服务器
Python
Java
PHP
Git
生活记录
读书笔记
作品发布
网上邻居
留言板
欣赏小姐姐
关于我
Search
登录
1
超星学习通小助手【观看视频+测验+考试】-10/18已停止维护
3,805 阅读
2
Js解密学习通视频秒过请求
1,601 阅读
3
学习强国部署查看docker容器输出和编写脚本清理输出
1,404 阅读
4
学习通学号登录简析
728 阅读
5
学习通签到QQ Bot开发及服务器部署(koishi+go-cqhttp)
434 阅读
Search
标签搜索
Laravel
前端
JavaScript
PHP
抓包
csharp
Fiddler
Vue
selenium
TypeScript
docker
Python
Java
爬虫
winform
安卓逆向
ubuntu
SpringBoot
Web逆向
Git
Hygge
累计撰写
44
篇文章
累计收到
323
条评论
首页
栏目
逆向网安
中英演讲
杂类教程
学习笔记
前端开发
汇编
数据库
.NET
服务器
Python
Java
PHP
Git
生活记录
读书笔记
作品发布
页面
网上邻居
留言板
欣赏小姐姐
关于我
用户登录
搜索到
2
篇与
的结果
2022-10-29
学习通学号登录简析
抓包分析序号参数名描述1fid学校ID2uname加密后的学号3password加密后的密码4numcode验证码除了这几个参数是变动的外,其他的都可以保持原样。判断一下学号和密码的加密特征0QgUbMUJj2usHikiqtb8HQ==22个字符加上两个等号 大概可能为..AES加密直接搜索请求的路径:/unitlogin,定位到login.js文件向上翻找一下// 对学号和密码进行加密 if(t == "true"){ let transferKey = "u2oh6Vu^HWe4_AES"; password = encryptByAES(password, transferKey); uname = encryptByAES(uname, transferKey); } // 使用的加密方法 function encryptByAES(message, key){ let CBCOptions = { iv: CryptoJS.enc.Utf8.parse(key), mode:CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }; let aeskey = CryptoJS.enc.Utf8.parse(key); let secretData = CryptoJS.enc.Utf8.parse(message); let encrypted = CryptoJS.AES.encrypt( secretData, aeskey, CBCOptions ); return CryptoJS.enc.Base64.stringify(encrypted.ciphertext); }这里就很明显了学号和密码的加密方式都是采用 AES 加密加密模式为CBCkey为:u2oh6Vu^HWe4_AESchsarp中复现请求体处理,需要对学号和密码加密后的文本进行URL编码:string requestBody = $"pid=-1&fid={schoolId}&uname={HttpUtility.UrlEncode(AESHelper.AesEncrypt(sn))}&numcode={verify}&password={HttpUtility.UrlEncode(AESHelper.AesEncrypt(password))}&refer=http%253A%252F%252Fi.chaoxing.com&t=true&hidecompletephone=0&doubleFactorLogin=0&independentId=0";AES加密工具类:using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace OnlineCourseToolKit.Utils { /// <summary> /// AES加密解密 助手类 /// CBC加密模式 /// </summary> public class AESHelper { /// <summary> /// 默认密钥-长度32位 /// </summary> private const string Key = "u2oh6Vu^HWe4_AES"; /// <summary> /// 默认向量-长度16位 /// </summary> private const string Iv = "u2oh6Vu^HWe4_AES"; /// <summary> /// AES加密 /// </summary> /// <param name="str">需要加密字符串</param> /// <returns>加密后字符串</returns> public static string AesEncrypt(string str) { return Encrypt(str, Key); } /// <summary> /// AES解密 /// </summary> /// <param name="str">需要解密字符串</param> /// <returns>解密后字符串</returns> public static string AesDecrypt(string str) { return Decrypt(str, Key); } /// <summary> /// AES 加密 /// </summary> /// <param name="str">明文(待加密)</param> /// <param name="key">密文</param> /// <returns></returns> private static string Encrypt(string str, string key) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = Encoding.UTF8.GetBytes(str); RijndaelManaged rm = new RijndaelManaged { Key = Encoding.UTF8.GetBytes(key), Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, IV = Encoding.UTF8.GetBytes(Iv) }; ICryptoTransform cTransform = rm.CreateEncryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// <summary> /// AES 解密 /// </summary> /// <param name="str">明文(待解密)</param> /// <param name="key">密文</param> /// <returns></returns> private static string Decrypt(string str, string key) { if (string.IsNullOrEmpty(str)) return null; Byte[] toEncryptArray = Convert.FromBase64String(str); RijndaelManaged rm = new RijndaelManaged { Key = Encoding.UTF8.GetBytes(key), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7, IV = Encoding.UTF8.GetBytes(Iv) }; ICryptoTransform cTransform = rm.CreateDecryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Encoding.UTF8.GetString(resultArray); } } }
2022年10月29日
728 阅读
3 评论
2 点赞
2022-08-28
Js解密学习通视频秒过请求
前言之前在github找到一个python selenium刷视频和做测验的源码,挂服务器上问题太多了,最近闲下来破解一下网络请求版的刷视频和做测验。效果图:学习通担心的主要是秒过视频会造成学习时长过短的情况,为此没有使用秒过 而是持续请求模拟真实进度,虽然和selenium版的时长差不多,但是更稳定和便捷。视频时长都是完整的有计算的。视频播放解密先抓到记录视频播放的请求GET 请求参数全在URL里,rt,isdrag,_t 这几个参数没什么作用,不发送也可以获得响应除了enc外的参数都可以在其他请求中获得,本文重点分析enc首先找切入点,这个请求的构造是由播放器产生的,就会存在参数拼接的情况。我选择参数名isdrag全局搜索(当然要选特殊的啦,越特殊重复的结果就越少)_0x473cb3 = [_0x16dd5d[_0x5d818d(0x242)], '/', _0x16dd5d[_0x5d818d(0x1ee)], _0x5d818d(0x44c), _0x16dd5d[_0x5d818d(0x3af)], _0x5d818d(0x26d), _0x1d0594, _0x5d818d(0x396), _0x16dd5d[_0x5d818d(0x2e2)], _0x5d818d(0x20e), _0x8e40c2, _0x5d818d(0x437), _0x16dd5d['objectId'], _0x5d818d(0x36a), _0x16dd5d[_0x5d818d(0x20c)], _0x5d818d(0x3b1), _0x16dd5d[_0x5d818d(0x3ba)], _0x5d818d(0x1ca), _0x16dd5d[_0x5d818d(0x3bd)], '&isdrag=', _0x9aa55, '&view=pc', _0x5d818d(0x1ef), md5(_0x5dcd20), _0x5d818d(0x1ff), _0x16dd5d['rt'], _0x5d818d(0x2d3), _0x5d818d(0x2ab), new Date()[_0x5d818d(0x1d6)]()][_0x5d818d(0x3d8)]('');按照对应位置的话更直观一点'&isdrag=', _0x9aa55, '&view=pc', _0x5d818d(0x1ef), md5(_0x5dcd20), '&isdrag=', 3 , '&view=pc', '&enc', md5(_0x5dcd20), // enc = f60c04f7cf2820976479ba3758b7d142, // 32位,典型的md5加密,所以enc=md5(_0x5dcd20)继续查看_0x5dcd20var _0x5dcd20 = Ext[_0x5d818d(0x2a0)][_0x5d818d(0x3ae)](_0x56986f, _0x16dd5d[_0x5d818d(0x3af)], _0x16dd5d[_0x5d818d(0x3bd)], _0x16dd5d[_0x5d818d(0x3ba)] || '', _0x16dd5d[_0x5d818d(0x246)], _0x3a88e3, _0x5d818d(0x24b), _0x16dd5d[_0x5d818d(0x2e2)] * 0x3e8, _0x8e40c2) // 分析: Ext的二维对象里面是一个方法 小括号后面全是参数打个断点看一下在511行停下后转去控制台打印一下坐标和索引分别是什么String format [{0}][{1}][{2}][{3}][{4}][{5}][{6}][{7}] 59831731 199369846 154762960473479 85bf18fc7d1a0e4707c8b4c771580a53 0 d_yHJ!$pdA~5 767000 0_767 // 这里就很明显了,_0x5dcd20就是将一些参数填充到这个字符串的占位符中 // 如下: Ext[_0x5d818d(0x2a0)][_0x5d818d(0x3ae)](_0x56986f, _0x16dd5d[_0x5d818d(0x3af)], _0x16dd5d[_0x5d818d(0x3bd)], _0x16dd5d[_0x5d818d(0x3ba)] || '', _0x16dd5d[_0x5d818d(0x246)], _0x3a88e3, _0x5d818d(0x24b), _0x16dd5d[_0x5d818d(0x2e2)] * 0x3e8, _0x8e40c2) '[59831731][199369846][154762960473479][85bf18fc7d1a0e4707c8b4c771580a53][0][d_yHJ!$pdA~5][767000][0_767]'这个字符串中的参数,有些是固定不变的,会变动的是取这个_0x16dd5d数组的成员,基本都是可以在其他请求中取到的,没有加密信息。对这个字符串进行md5加密就可以得到enc解决无限debugger我们在对一些网站进行JS逆向分析过程中,很有可能会遇到网站禁止开发人员使用F12进行网页调试,如果你打开就会遇到无限debugger的这个情况,当我们遇到这种情况,我们该如何进行避免无限debugger弹出呢?解决方法:可以直接在控制台输入以下代码,可以有效的跳过无限debugger(Chrome浏览器)Function.prototype.constructor = function(){}核心代码while (currentProgress <= video_info.duration) { string enc = $"[{CurrentCourse.ClassId}][{vav.defaults.userid}][{point.jobid}][{point.objectId}][{currentProgress}000][d_yHJ!$pdA~5][{video_info.duration}000][0_{video_info.duration}]"; enc = GetMD5(enc);// 32位md5加密 string requestBody = $"clazzId={CurrentCourse.ClassId}&playingTime={currentProgress}&duration={video_info.duration}" + $"&clipTime=0_{video_info.duration}&objectId={vav.attachments[0].property.objectid}&otherInfo={vav.attachments[0].otherInfo}" + $"&courseId={CurrentCourse.CourseId}&jobid={vav.attachments[0].property.jobid}&userid={vav.defaults.userid}&view=pc&enc={enc}&dtype=Video"; // 跳过视频 VideoProgressVo jumpVideoResponse = await ($"https://mooc1.chaoxing.com/multimedia/log/a/{vav.defaults.cpi}/{video_info.dtoken}?{requestBody}") .WithHeader("Referer", "https://mooc1.chaoxing.com/ananas/modules/video/index.html") .WithHeader("User-Agent", "apifox/1.0.0 (https://www.apifox.cn)") .WithHeader("Content-Type", "application/json") .WithCookies(Cookies) .GetJsonAsync<VideoProgressVo>(); Log($"当前进度值:{currentProgress},总长度:{video_info.duration},状态:{jumpVideoResponse.isPassed}"); if (!jumpVideoResponse.isPassed) { if(currentProgress + 60 > video_info.duration) { currentProgress = video_info.duration; }else if(currentProgress == video_info.duration) { currentProgress += 1; }else { currentProgress += 60; } }else { Log("该视频已完成"); currentProgress = video_info.duration + 1; } await Task.Delay(60 * 1000); }引用1.JS调试的时候遇到无限debugger怎么办? : https://blog.csdn.net/qq_19309473/article/details/120573903
2022年08月28日
1,601 阅读
4 评论
3 点赞