前几天有个朋友和我抱怨小米的超级课程表(是叫这个?)不能很好的识别湖南大学的课程表,正好我也觉得湖大微生活受限于微信小程序,功能不足,所以我打算趁着十一假期研究一下湖南大学的教务系统,看看能不能整出什么花活。
目前正在做的是一个PC/Android的跨平台课程表,用Qt和Boost。将来我看看能不能趁着选课系统开放的时候研究一下怎么选课,毕竟湖大的选课系统实在是太那啥了,每次十二点半开放,一点才选的上去,只能捡漏。
话不多说,我们开始吧!这里我介绍一下从湖大教务系统获取课表的步骤,需要发送和接受的http包,和需要保存/发送的cookie等信息。
下面提供的信息仅供学习用途,如果您想从湖南大学的教务系统/个人门户获取信息,请通过正常途径获取!
先讲一下我是怎么得到请求课表的步骤的。
我们单刀直入,打开抓包软件,从“我的选课-课表查看”栏打开课表。待课表显示后,检查所有的Content-Type为application/json的返回包,发现有一个包包含了课表。找到请求这个包的request包。
这个包是POST包,Content-Type也是application/json。
我们检查一下这个包的具体内容,发现有作用的有这几项:
TOKENCookie,包含authcode和SESSION包体我的包体是这样的: 显然,这个包体用来请求特定学期的课表。
松了口气,搞定包体没有困难,我们来看看TOKEN和cookie怎么来的。
在点击“课表查看”到课表显示之间抓取的http包中,查找值为TOKEN的值和SESSION的值的字符串,发现第一个包含TOKEN和SESSION的请求的包是一个GET请求。这证明TOKEN和SESSION在登陆的过程中已经生成。
于是我们抓取开始登录个人门户到教务系统完全加载之间的http包。
注意,这里登录个人门户使用的是https://pt.hnu.edu.cn/zfca?yhlx=student&login=0122579031373493685&url=login.aspx,是pt.hnu.edu.cn提供的可以直接重定向到教务系统的登录窗口。
我们在所有的包中搜索SESSION的值,发现第一个包含SESSION的值是一个Response包,这个包通过Set-Cookie设定了token、authcode和SESSION 这几个值恰好就是我们请求课表所需要的cookie和TOKEN。
找到请求这个包的request包。这个包是一个POST,请求的uri是/Njw2017/index.html,Content-Type是application/x-www-form-urlencoded。
让我们看看它的包体…… 嗯,包含了学号、密码、不晓得的s_ticket……
等一下,这个好像是明文的http包??虽然我们的个人门户登录入口受SSL保护,但是登录后再把学号密码用明文发一下真的行吗?
好了,分析了这个非常危险的POST包,咱们看看s_ticket怎么拿到吧。
我刚才也提到,我们的登录窗口受SSL保护,我提供的url也是https起头,那我们就分析一下https包。
搜索“s_ticket”,发现第一个包含这个字符串的包是一个Response,其中的起重定向作用的location字符串指示了s_ticket,我们寻找请求到这个包的request。
这个request是一个受SSL保护的POST包,Content-Type是application/x-www-form-urlencoded,有用的值是uri、cookie和它的包体。uri包含了一个jsessionid,cookie包含了一个JSESSIONID,包体包含了一个表单数据,表单数据中有用的是学号、密码、lt、_eventId和submit1。_eventId固定为"submit",submit固定为“登录”的百分号编码形式。jsessionid和JSESSIONID不同。
我们先看看lt怎么来:
经查找,发现lt实际上是登陆页面其中一个name为lt的控件的value。这个页面由一个GET包请求而来,这个GET包需要JSESSIONID。
然后看看JSESSIONID怎么来:
我们发现,在点击登录后,含JSESSION的包是一个request包,所以我们清除所有的cookie,分析从输入url之前到进入教务系统后的所有http和https包。发现第一个含JSESSIONID的包同时也是包含登陆页面的包,请求这个包的request包是一个GET包,不含任何可能变化的值。
那jsessionid呢?
我们发现,如果在加载登陆页面前没有任何cookie,那么jsessionid就和JSESSIONID一致。
大功告成!已经发现了完整的请求课表的步骤!
我们总结一下:
SSL 发一个GET包,uri为/zfca/login?yhlx=student&login=0122579031373493685&url=login.aspx HTTP/1.1
SSL 从返回包中获得JSESSIONID和lt
SSL 发一个POST包,使用了jsessionid、JSESSIONID、lt、submit1、_eventId、学号、密码
SSL 从返回包的location获得s_ticket
发一个POST包,使用了学号、密码、s_ticket
从返回的包中获得token、SESSION
发一个POST包,使用TOKEN,SESSION,authcode,包体为一个json,包含了请求的学期等信息
分析返回的json
想偷懒、不想碰SSL可以用Qt的qWebEngineView控件,用js填写并发送表单,获取cookies等。
以上就是我总结的请求湖大课表的信息,希望能帮助到各位。
接下来我会继续这个Qt+Boost课程表的小项目,完成后我会把这个项目简要的介绍给大家,分享我封装的一些“脚手架”。
我这里还有一些其他的小项目,包括已经完成的明日方舟自动刷图软件,正在开发的可编程配置文件和一个小的http server。时机成熟我也会把这些分享给大家。
个人B站号:@染色XYX