简单分析我学校教务系统登录功能实现

2,016次阅读
2条评论

共计 3881 个字符,预计需要花费 10 分钟才能阅读完成。

首次分析

首先按照正常流程进行,抓包查看登录提交的数据。

Header 如下

POST http://jwgl.ayit.edu.cn/cas/logon.action HTTP/1.1
Host: jwgl.ayit.edu.cn
Connection: keep-alive
Content-Length: 1124
Accept: text/plain, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Origin: http://jwgl.ayit.edu.cn
Referer: http://jwgl.ayit.edu.cn/cas/login.action
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=3A9F6F4B8DD59938CB4E13F79E944D3C

提交的数据内容如下

params=QzMyMDQwRTc1QjA1MDRBRjk5QTgyRUZEMDlBQjVGMTZEODlDMEIyQ0E5MkRFRDAzMDJGRjY2QjhFREMzMkZENDMzQUFEQzMzODE2NzJENjA3MDMyRjAyRkY1QTk1OEQwMTc1NzQ2OTExQTdDODdDNjdFREU5NTlCNEU5Q0NBNjAzRTY0MTQ4REIzQkM0QTY2NEFGRkI4QjRFNDg4MkQzMUYxMzBDMkEwMEM3MDA3MjU5NUEwMjUwQkFBNjQ2QjVEOUQ5RUY2QTA4MkNCQ0ZDQjdDMkQ4OTE5NDEzREM2NjE3MkM2M0ExNTFFQUY0QzMzRjZCOEQ4QjQwRkZCQTY4M0M1NzZCNzY0Q0I5Q0VFMzQ2QjQ4N0U5MjRFM0VCODcyMTVGQ0U4RTI5OUNBOTdCRDMyRUUzQTIxNzY4MEY4ODRFNzI0Q0FGODk2MTRFREE2OTM5RkJFRUNBODAxRTYyNzgwNkU5RUM2MEFDRjMxNDVFMDI1RjI4QTI3MTY2RjU0ODE2RDc2MkNDMzEzMDM3MjgxQTlDRDA4QTA5NjhDQzM4NDJGOEEzMTA1Njc0MzI5ODRFM0I5MTREMjQ3NkZEOTlEMzE4NjEwMTg4MjJGNTU0REMwMDYyQ0NEMDI3QkQ3NDdFNjM0QTA4NjQ1OTU4NjE2OEU0RENDMEE3NzRGOEFDNkY0OUVGM0ZERDM4RjgyNThBRUUwOEMxRjhDMDlCMzI2RERFNTI2N0FGNDk2NTBCQ0I5MkNFMzdBQTk4RUE3NDU0QTY5NjhENTRDMjJGRjgyRDJGRjNDRDY0NjkxMzM5NkU3QjI5ODhFRkMwRDdGRTJCNUU4RjYwQzQxMkMxRUZCOUU0MEU3Q0ZDQzIxNjAwNEZGNTJBQzZGMUMzRTk0QzIwQTgwNUU3MDMwRDAzNjNGN0U1QjIyNTA2REEzM0ZFMzg0ODQyMkU2M0MyOUJFNjhBMjY0OUFFRENENThBNkRGMUYzNEYzQzU5NUE2MEY2REM2QkM2RDNGRThERTQwOTJFMDI0QzQxQkY4MTcwRA==&token=a5ac4f2525e4860adb84cefc967368e8&timestamp=2020-07-06 23:52:37

共提交了 3 个参数,分别是加密后的 params,token 和明文字符串 timestamp

返回值如下

{"message":"验证码有误!","result":null,"status":"401"}

由于前端的特性,所有的加密肯定是在 JS 内实现,所以接下来我来逐条进行分析。

token 分析

因为 params 是个加密字段,解密需要一定时间,timastamp 是明文不用管,我就先从 token 入手。

查看 html 结构,这是登录按钮

%title插图%num

可见点击按钮后执行 doLogon()方法,通过在可能的 JS 里搜索方法名,最终发现该方法出现在 LoginExt.js 中,如下图

%title插图%num非常开心,JS 没有混淆和压缩,全部以明文展示。

通过查看函数结构,很容易可发现 token 的位置

var token = j$("#yhmm").val();

可见 token 的值就是用户密码的值,但这显然是错误的因为我们抓包显示 token 是一个类似于加密后的值

下断调试后发现,在调用 getEncParams 这个方法后 token 就变成加密后的值了,同时这个方法也是生成整个登录表单的核心方法!至此感觉分析预计会很快结束。

%title插图%num

getEncParams 方法分析

既然找到了核心方法,那只需要看看这个方法里都是什么就好了,通过 F11 单步进入方法,发现我进入了一个新的文件里。

%title插图%num

而很巧的是,这个 SetKingoEncypt.jsp 在刷新首页时会加载

%title插图%num

接下来就非常好办了,通过查看方法可知,token 是将之前组装好的 params 和现在的时间(注意是时间而不是时间戳)都进行 md5 加密后再进行 md5 加密,所以为什么我首次分析时觉得 token 就是个 md5 加密后的值。

%title插图%num

 

总结

至此,整个登录流程就已经分析完毕。整个登录流程可以总结为:

  1. 获取输入的用户名,密码,token(和密码相同),验证码(id 为 randnumber 的元素值)
  2. 校验用户名和密码是否合法① –> kutil.isPasswordPolicy()方法
  3. 获取 txt_mm_expression、txt_mm_length、txt_mm_userzh 的值 ②
  4. 初次加密 password
  5. 拼接 p_username 和 p_password
  6. 对用户名进行编码 ③
  7. 拼接 params ④
  8. 对 params 进行加密 –> getEncParams()方法
  9. 封装完毕,发包登录

可见登录流程是多么复杂,但复杂之余并不困难,按照流程走就可以。

对于青果的加密函数(SetKingoEncypt.jsp),在实际使用时其实无需重写,只需要加载和调用即可。当然若语言不通则可能需要重写加密函数。

关于这个加密函数如何自己写一份,我会在下一篇文章内说明。

到这里对登录功能的分析就结束了。

 

附录

①用户名和密码校验方法函数

/**
  * 检测密码是否符合密码策略
  * 1、用户密码不能与登陆帐号一致。* 2、用户密码必须为 6 位或 6 位以上字符长度,并且包含有字符和数字。* return 1- 符合; 0- 不符合
  */
  my.isPasswordPolicy = function(username, password){if (password == "" || password == null || username == password){return "0" ;}
    var passwordlen = new String(password).length ;
    if (passwordlen < 6){return "0" ;}
    /* 2019.2.16 因密码复杂度要求可以设置不需要包括字母和数字而去掉
    var letter = new String(password).replace(/[^A-Za-z]/g, ""); // 保留字母
    var letterlen = letter.length ;
    if (letterlen == passwordlen) {return "0";}
    var digit = new String(password).replace(/[^0-9]/g, ""); // 保留数字
    var digitlen = digit.length ;
    if (digitlen == passwordlen) {return "0";}
    */
    return "1" ;
  }

②3 个 txt 值的来源%title插图%num

③在编码用户名时用到了一个 SessionID,其出处是

%title插图%num这个值是直接服务端渲染直接写死在网页内,所以可以直接调用_sessionid 来获取

④params 拼接方法以及拼接后的值示例

拼接方法:

var params = p_username+"="+username+"&"+p_password+"="+password+"&randnumber="+randnumber+"&isPasswordPolicy="+passwordPolicy+
               "&txt_mm_expression="+txt_mm_expression+"&txt_mm_length="+txt_mm_length+"&txt_mm_userzh="+txt_mm_userzh;

示例值:

"_u1234=dGVzdDs7M0E5RjZGNEI4REQ1OTkzOENCNEUxM0Y3OUU5NDREM0M=&_p1234=5ec82405514679333a2c7ab58dd2b980&randnumber=1234&isPasswordPolicy=0&txt_mm_expression=4&txt_mm_length=4&txt_mm_userzh=1"

 

正文完
 
紫旭
版权声明:本站原创文章,由 紫旭 2020-07-07发表,共计3881字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(2条评论)
紫旭 博主
2020-07-16 21:10:33 回复

 iPhone  Safari
浅墨 评论达人 LV.1
2020-12-02 17:35:14 回复

很好

 Android  Chrome  中国上海上海市电信