前言
每次查成绩都要点来点去很麻烦,特别是期末这段时间,着实有丶不太方便。
所以写了一个一条命令查成绩的小工具;
注意:更换了新的教务系统,这份代码已经失效了。
轻信了的同学莫对俺下手【/互联网暴力】
完整代码可以在
Github:https://github.com/hausa-han/HAUST_auto_get_score
Gitee(访问较快):https://gitee.com/hausa/HAUST_auto_get_score
找到。
分析与开发过程
从对教务系统的第一次访问开始抓包分析:
请求方式是GET,获得了一个SessionId,此后每一次请求都需要SessionId,因此需要模拟这一过程,将cookie中的SessionId保存下来:
1 | import requests |
运行:
之后在网页上进行登录操作,并对登录时的包进行抓包,可以看到:
所有的POST参数中,__VIEWSTATE
和__VIEWSTATEGENERATOR
参数是固定的;Sel_Type
参数是用户类型,即STU;txt_sdsdfdsfryuiighgdf
参数是学号;很明显sdfdfdhgwerewt
参数即是加密后的密码,其他参数均为空。接下来来分析密码的加密过程。
进行JS调试:
在Sources栏,展开直到发现一个叫md5.js
的文件,md5是一种加密方式。看名字,猜测是加密密码的脚本文件,在md5函数处打断点,开始动态分析。
在输入密码时中断,不断跟进函数调用过程(F10),发现这样一段代码:
1 | var s=md5(yhm+md5(obj.value).substring(0,30).toUpperCase()+schoolcode).substring(0,30).toUpperCase(); |
可以看到,下面一行对sdfdfdhgwerewt
参数的值进行了设置,值为上面加密过程得出的结果。分析可知,上面一句对密码的加密过程为:第一次MD5加密:用户输入的密码的md5的32位大写,取其前30位,然后将:学号、第一次加密结果、学校编码拼接到一起进行第二次md5加密,并取结果的32位大写的前30位。
我们用python模拟这样的加密过程,并将结果与这里的结果对照:
1 | import hashlib |
是一致的,所以加密过程解决。
之后将加密后的参数与其他所有参数拼接到一起,进行一次login尝试:
(在这里卡了好久,最后发现这里有一个小坑,这个包之前有两个完全一样的请求发出,但是返回的__VIEWSTATE
不一样,就这里,耗了至少5个小时)
P.S.这里是部分代码,完整代码参考上面的仓库地址。
登录后,即可用相同的方法对获取成绩的过程进行分析和模拟,并最终调整,写出最终程序。
程序运行效果:
第一次使用需要输入学号和密码,若教务系统正常运行,则会在当前目录生成一个score.jfif图片文件,其中即为成绩:
从第二次使用开始,会自动读取加密存储的账号密码,2~4秒内实现查成绩操作:
因为教务系统过一段时间后就会清除已登录的cookie(主要是我懒。。),所以没有实现Logout,有兴趣的小伙伴可以来实现一下,加强程序的安全性。
有问题欢迎在下方评论嗷~~