长沙理工大学教务管理系统模拟登陆

  • 准备
    • 浏览器抓包设置
    • 开始抓包
    • 开始数据包分析
      • 登陆界面包
      • 加密算法包
      • 验证码包
      • 登陆包
  • 代码实现
    • 密码加密
    • 验证码加密
    • 获取新的Cookie和必要的参数
    • 获取验证码
    • 开始模拟登陆
    • 判断是否登陆成功
  • 进一步应用
    • 获取成绩
    • 简单测试
  • 一点建议

准备

浏览器抓包设置

按F12开启浏览器抓包。

选择Network选项,并记得选上Preserve log选项,否则页面一旦跳转,之前抓的包就会消失。

开始抓包

通过对首页进行刷新抓包,我抓到了以下数据包。

通过对数据包的逐个观察,我选出了首页数据包里的三个关键包。

一个是登陆界面的数据包,里面包含了完整的登陆Form表

根据登陆界面的代码分析得出表单的上传还需要一些加密方法,“加密算法数据包

一个是验证码的数据包。

随后我们再对登陆过程进行抓包。一般登陆表都是采用POST的方式上传。(此时如果没有选上Preserve log选项,将观察不到登陆数据包)
由下图可知服务器的请求地址(Requesst URL)和请求方式(Request Method)

登陆数据包携带的数据(From Data)

开始数据包分析

在上面我们抓了四个数据包,分别是登陆界面包,加密算法包,验证码包,登陆包。现在进行详细分析。

登陆界面包

登陆界面包的请求地址请求方式

请求头

请求头里重要的参数有CookieRefererUser-Agent,其它参数可加可不加。
我们的最终目标就是要获取一个已登陆的Cookie
Referer是一个服务器需要验证的参数,如果没有,服务器将返回“系统出错”等。
User-Agent是为了降低被后台识别为爬虫的几率。

加密算法包

根据登陆界面代码里的具体加密方法调用逻辑来使用。

验证码包

请求地址请求方式

请求头

登陆包

请求地址请求方式,可以注意到登陆包和登陆界面包的请求地址是一样的,但请求方式不同

请求头

Form Data

结合登陆界面的代码分析可得下表

参数名 参数值来源
__VIEWSTATE 登陆界面代码中匹配,会变化
__VIEWSTATEGENERATOR 登陆界面代码中匹配,会变化
pcInfo 直接复制包数据即可
txt_mm_expression 字符串空值""
txt_mm_length 字符串空值""
txt_mm_userzh 字符串空值""
typeName 点击From Data旁的view URL encoded可得值"%D1%A7%C9%FA" ,使用gb2312进行UrlDecode解码可得知该值实际为"学生"
dsdsdsdsdxcxdfgfg 加密后的密码,具体加密方式可以在登陆界面代码中看到,使用的加密算法在首页抓包中的md5.js中
fgfggfdgtyuuyyuuckjg 加密后的验证码,具体加密方式可以在登陆界面代码中看到,使用的加密算法在首页抓包中的md5.js中
Sel_Type 可以从登陆界面代码的登录表得知有多个值可选,一般为STU
txt_asmcdefsddsd 学号
txt_pewerwedsdfsdff 字符串空值""
txt_psasas 同typeName可得值为“请输入密码”
txt_sdertfgsadscxcadsads 字符串空值""

代码实现

接下来是具体的代码实现,我选择使用Java和Jsoup来构造。模拟登陆实质是模拟数据包发送接收和处理,使用哪种语言看个人爱好。

    public static Map<String, String> cookies = null;//用来存放Cookiepublic static final String validateCodeUrl = "http://xk.csust.edu.cn/sys/ValidateCode.aspx";//验证码请求地址public static final String pcinfo = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36undefined5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 SN:NULL";public static final String loginPanelUrl = "http://xk.csust.edu.cn/_data/login_home.aspx";//登陆界面请求地址public static Map<String, String> datas = new HashMap<String, String>();//要Post的数据

密码加密

    public static String getPassword(String username, String password) {ScriptEngineManager manager = new ScriptEngineManager();//Java自带可以解析Js文件的类ScriptEngine engine = manager.getEngineByName("javascript");try {File file = new File("E:/jee-2019-032/work-space/hhh/src/hhh/md5.js");// 读取jsFileReader fileReader = new FileReader(file);// 执行指定脚本engine.eval(fileReader);if (engine instanceof Invocable) {Invocable in = (Invocable) engine;return (in.invokeFunction("md5", username+ in.invokeFunction("md5", password).toString().substring(0, 30).toUpperCase() + "10536").toString().substring(0, 30));}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return null;}

加密逻辑来自登陆界面的代码

    function chkpwd(obj) {if (obj.value != '') {var s = md5(document.all.txt_asmcdefsddsd.value + md5(obj.value).substring(0, 30).toUpperCase() + '10536').substring(0, 30).toUpperCase();//具体加密逻辑document.all.dsdsdsdsdxcxdfgfg.value = s;} else {document.all.dsdsdsdsdxcxdfgfg.value = obj.value;}chkLxstr(obj.value);}

验证码加密

 public static String getValidateCode(String validateCode) {ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine engine = manager.getEngineByName("javascript");try {File file = new File("E:/jee-2019-032/work-space/hhh/src/hhh/md5.js");// 读取jsFileReader fileReader = new FileReader(file);// 执行指定脚本engine.eval(fileReader);if (engine instanceof Invocable) {Invocable in = (Invocable) engine;return in.invokeFunction("md5",in.invokeFunction("md5", validateCode.toUpperCase()).toString().substring(0, 30) + "10536").toString().substring(0, 30).toUpperCase();}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return null;}

加密逻辑来自登陆界面代码

     function chkyzm(obj) {if (obj.value != '') {var s = md5(md5(obj.value.toUpperCase()).substring(0, 30).toUpperCase() + '10536').substring(0, 30).toUpperCase();//加密具体逻辑document.all.fgfggfdgtyuuyyuuckjg.value = s;} else {document.all.fgfggfdgtyuuyyuuckjg.value = obj.value.toUpperCase();}}

获取新的Cookie和必要的参数

    Connection con2 = Jsoup.connect(loginPanelUrl);con2.header("Referer", "http://xk.csust.edu.cn/home.aspx");con2.header("Upgrade-Insecure-Requests", "1");//不知道具体作用,为防止出错,带上为妙con2.header("User-Agent", pcinfo);Response rs2 = con2.ignoreContentType(true).execute();//没携带Cookie进行访问,服务器会返回新的Cookiecookies = rs2.cookies();//获取新的Cookies!!!!!!!!!!!!Document d2 = Jsoup.parse(rs2.body());Element logonEelemt = d2.getElementById("Logon");//登陆界面代码的Form表单的Id是:Logonfor (Element e : logonEelemt.getAllElements()) {if (e.attr("name").equals("__VIEWSTATE")) {//获取__VIEWSTATEdatas.put("__VIEWSTATE", e.val());}if (e.attr("name").equals("__VIEWSTATEGENERATOR")) {//获取__VIEWSTATEGENERATORdatas.put("__VIEWSTATEGENERATOR", e.val());}}datas.put("txt_asmcdefsddsd", "201716080227");// 学号datas.put("dsdsdsdsdxcxdfgfg", getPassword("201716080227", "a8657090"));// getPassword方法获得加密后的密码datas.put("Sel_Type", "STU");datas.put("pcInfo", pcinfo);datas.put("typeName", "学生");datas.put("txt_psasas", "请输入密码");datas.put("txt_mm_expression", "");datas.put("txt_mm_length", "");datas.put("txt_mm_userzh", "");datas.put("txt_pewerwedsdfsdff", "");datas.put("txt_sdertfgsadscxcadsads", "");

通过上面的代码,登陆POST的表单数据便只差加密后的验证码了。

获取验证码

         Connection connection = Jsoup.connect(validateCodeUrl);connection.header("Referer","http://xk.csust.edu.cn/_data/login_home.aspx");connection.header("User-Agent", pcinfo);Response res = connection.ignoreContentType(true).cookies(cookies).execute();//必须带上cookies,否则验证码图片将和登陆cookie不匹配return res.bodyAsBytes();//将验证码图片转化为byte[]方便在GUI代码上展示

开始模拟登陆

 public static boolean startLogin(String validate) {try {// 登陆datas.put("fgfggfdgtyuuyyuuckjg", getValidateCode(validate));// 获取加密后的验证码Connection connect = Jsoup.connect("http://xk.csust.edu.cn/_data/login_home.aspx");connect.header("Referer", "http://xk.csust.edu.cn/_data/login_home.aspx");connect.header("Upgrade-Insecure-Requests", "1");connect.header("User-Agent", pcinfo);Response login = connect.ignoreContentType(true).data(datas).method(Method.POST).cookies(cookies).execute();boolean success = isLogin(login.body());//判断登陆是否成功return success;} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return false;}

判断是否登陆成功

POST登陆表单,服务器会返回结果代码。结果代码里包括但不限于“系统错误”、“验证码错误”以及“账号或密码错误”等字段。于是判断结果中包含了哪些字段便成了判断是否登陆成功的方法之一。

    public static boolean isLogin(String body) {if(body.contains("正在加载")) return true;else return false;}

进一步应用

至此,我们已经的得到了登录后的Cookie,使用该Cookie可以进行一些功能开发,比如课程查询、成绩查询或者抢课脚本等功能的开发。

获取成绩

通过抓包得到获取成绩的链接,POST后会返回成绩图和一些其他数据。这里只需要成绩图。

    public static String postGradeSearchOrder() {Connection connection = Jsoup.connect("http://xk.csust.edu.cn/xscj/Stu_MyScore_rpt.aspx");connection.header("Referer", "http://xk.csust.edu.cn/xscj/Stu_MyScore.aspx");connection.header("Upgrade-Insecure-Requests", "1");connection.header("User-Agent",pcinfo);Map<String, String> dates = new HashMap<String, String>();dates.put("sel_xn", "2018");//学年 2018-2019dates.put("sel_xq", "1");//第一学期:0        第二学期:1   dates.put("SJ", "0");    //原始成绩:0        有效成绩:1dates.put("SelXNXQ", "2");//入学以来:0   学年:1  学期:2dates.put("zfx_flag", "0");//主修:0   辅修:1dates.put("btn_search", "检索");dates.put("zxf", "0");//hiddentry {Response response = connection.ignoreContentType(true).data(dates).method(Method.POST).cookies(cookies).execute();Document document = Jsoup.parse(response.body());Element element = document.getElementsByTag("img").first();//返回的代码里包含了成绩图链接return element.attr("src");//返回成绩图片的链接} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return null;}

得到图片链接后进行进一步获取

    public static byte[] getGradeImage(String path) {Connection connection = Jsoup.connect(path);connection.header("Referer","http://xk.csust.edu.cn/xscj/Stu_MyScore_rpt.aspx");connection.header("User-Agent",pcinfo);try {Response response = connection.cookies(cookies).method(Method.GET).ignoreContentType(true).execute();return response.bodyAsBytes();//转换为byte[]方便GUI显示} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}return null;}

简单测试

使用Java Swing进行简单测试。

登陆界面,账号密码暂时内置。

登陆成功

成功获取到成绩图,没进行适配,因为只是测试。

一点建议

在进行模拟登陆的过程中,我发现一旦程序出现BUG非常难以发现,因为服务器只会一直返回系统出错。所以,如果你一直失败,要重点检查请求头参数和表单数据。

长沙理工大学教务管理系统模拟登陆相关推荐

  1. java获取教务系统成绩,Java httpClient 正方教务管理系统模拟登陆,爬取学生成绩和培养计划...

    噜噜噜,附上代码~~~ 不过说句老实话,ACM是真的比写这个有意思多了,吸吸吸~~ package jwgl; import java.io.IOException; import website.l ...

  2. 涉密计算机与涉密网络管理制度,长沙理工大学网络涉密保密管理制度

    第一条.为了加强计算机信息网络的保密管理,确保国家秘密的安全,根据国家保密法规和计算机信息网络保密管理的有关规定,结合实际,特制定本规定. 第二条.使用涉密网的人员必须遵守国家保密法规和计算机信息网络 ...

  3. 长沙理工大学教学区校园网登陆

    CSUST_network_auto_login 长沙理工校园网登陆,用于长沙理工大学校园网登陆 长沙理工大学 校园网免账号自动登陆 使用了魔仙堡魔法,可以让同学们在连接学校内csust-bg公用Wi ...

  4. 涉密计算机及网络保密管理制度,长沙理工大学涉密计算机保密管理制度

    第一条.为加强涉密计算机的保密管理,确保国家秘密的安全,根据国家有关保密法规和湖南省国家保密局的要求,制定本规定. 第二条.本规定适用于采集.存储.处理.传递.使用和销毁国家秘密信息的计算机(台式和便 ...

  5. 教务管理及教材订购系统设计文档

    教务管理及教材订购系统设计文档 目录 一.概述 1.1 开发背景 1.2 使用技术 1.3运行环境 1.4 设计目标 1.4.1权限管理 1.4.2信息管理 1.4.3选课管理 1.4.4 成绩管理 ...

  6. 长沙理工大学计算机网络试题,长沙理工大学考试试卷(计算机网络)要点.docx

    长沙理工大学考试试卷 ???????????????????????????????????????? 卷 号1 教研室(或教 ) 名易建 教研室主任 名蔡碧野 ??????????????????? ...

  7. 长沙理工大学计算机电路b试题,长沙理工大学考试试卷(计算机网络)

    长沙理工大学考试试卷----------------------------------------试卷编号 1 拟题教研室(或教师)签名易建勋教研室主任签名蔡碧野------------------ ...

  8. C#毕业设计——基于C#+asp.net+sqlserver的教务管理平台设计与实现(毕业论文+程序源码)——教务管理平台

    基于C#+asp.net+sqlserver的教务管理平台设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的教务管理平台设计与实现,文章末尾附有本毕 ...

  9. 长沙理工大学计算机科学与技术专业排名,2019长沙理工大学专业排名

    长沙理工大学是国家"中西部高校基础能力建设工程"高校.截止到目前为止,长沙理工大学重点专业共有10个专业,其中国家品牌专业7个,省部重点专业3个.在长沙理工大学众多的优秀专业中,称 ...

最新文章

  1. 用C语言解“超速判断”题
  2. Android中build target,minSdkVersion,targetSdkVersion,maxSdkVersion概念区分
  3. 一个openMP编程处理图像的示例
  4. 即时聊天IM之二 openfire 整合现有系统用户
  5. html5 扩展属性,HTML5属性的介绍和扩展.doc
  6. 栈溢出脚本_漏洞练习之网络编程与堆栈溢出技术
  7. SpringBoot配置文件加密
  8. WebRTC 学习之 WebRTC 简介
  9. 1.2.3 TCP/PI参考模型(应用层、传输层、网际层、网络接口层)、五层参考模型(应用层、传输层、网络层、数据链路层、物理层)、OSI与TCP/IP参考模型比较(转载)
  10. VMware15.0安装CentOS7
  11. element el-autocomplete组件 自定义传参的解决方法
  12. 公务员可以做哪些合法正规的兼职
  13. PMP培训内容有哪些?
  14. 基于Linux利用PPP实现4G模块联网
  15. ARINC485和RS485的区别
  16. Arno,第一个NFV开源平台
  17. 数据,源码防泄密解决方案
  18. [读书总结]大数据时代
  19. linux下文件损坏怎么删除 No such file or directory
  20. 【LWIP】初学STM32+LWIP+网络遇到的基础问题记录

热门文章

  1. 软件设计师(结构化开发)
  2. 转载: React Native 采用Fetch方式发送跨域POST请求
  3. str[]与*str的区别
  4. Linux:httpd服务(二)
  5. 不留痕迹的清除部分history历史命令记录
  6. 开关电源001--时间常数
  7. 27岁技术总监,收入太高,心头慌得一比。。。
  8. 5. VBA消息框(MsgBox)
  9. python入门2——基础语法2——字符串详解
  10. 玩 High API 系列之:实现钉钉Ding功能