教务管理系统一些研究

自从我们学校换了教务管理系统之后,我觉得我可以学习一波爬取我们学校的教务管理系统。经过时断时续的一个月学习,我觉得可以写完整的模拟登录。

1、准备工作  

爬取网站首先要对网站进行详细认真的调查了解。这里我首先查看网站的源代码,首先是这一段代码:`<div class="dl_hidden dl_box1"><tableborder="0"width="320px"><tr><tdclass="trclass">用户名:</td><td><inputtype="text"id="userAccount"maxlength="32"value=""style=" width:250px;"class="input"/><inputtype="hidden"id="view"name="view"/></td></tr><tr><tdclass="trclass">密码:</td><td><inputtype="password"id="userPassword"value=""maxlength="32"style="width:250px;"class="input"/><inputname="useDogCode"id="useDogCode"type="hidden"/><inputname="encoded"id="encoded"type="hidden"/></td></tr><tr><tdclass="trclass">验证码:</td><tdstyle=""><inputtype="text"name="RANDOMCODE"id="RANDOMCODE"maxlength="6"class="input"style="width:70px;display:block;float: left;"/><imgsrc="/verifycode.servlet"id="SafeCodeImg"οnclick="ReShowCode()"width="65"height="28px"style="display:block;float: right;padding-right:100px;"/></td></tr><tr><tdcolspan="2"align="right"style="padding-top: 10px;"><ahref="/smsPwd/enterxh.jsp"target="_blank"style="color: blue;">忘记密码</a>&nbsp;&nbsp;&nbsp;<input type="submit" id="btnSubmit" class="button" οnmοuseοver="$(this).attr('class','buttonover')" οnmοuseοut='$(this).attr("class","button")' title="点击登录" value="登 录"/></td>`在这一段代码中,我们可以捕捉到以下信息:页面会捕获用户输入的userAccount和userPassword信息,同时还需要用户输入验证码进行身份确认(吐槽一句,我觉得我们学校新的管理系统做的比原来的安全多了)。但是注意,页面并不是直接用Post方法提交到服务器端的。我们继续往下查看代码。我注意到代码里定义了一个方法如下:`function onSubmint(){ var strUrl="/Logon.do?method=logon&flag=sess"; $.ajax( { url:strUrl,type:"post",cache:false,dataType:"text",success:function(dataStr) { if(dataStr=="no"){ return false; }else{ var scode=dataStr.split("#")[0]; var sxh=dataStr.split("#")[1]; var code=document.getElementById("userAccount").value+"%%%"+document.getElementById("userPassword").value; var encoded=""; for(var i=0;i<code.length;i++){ if(i<20){ encoded=encoded+code.substring(i,i+1)+scode.substring(0,parseInt(sxh.substring(i,i+1))); scode = scode.substring(parseInt(sxh.substring(i,i+1)),scode.length); }else{ encoded=encoded+code.substring(i,code.length); i=code.length; } } document.getElementById("encoded").value=encoded;document.getElementById("frm").submit(); } },error:function() { alert("计算异常!");}});return false;`由此可见,网页并不是直接Post表单数据,而是进行加密运算:首先向服务器端请求一个随机字符串,这个随机字符串有一个特征:就是一串字符接一个#符号再连接一串数字。然后在JS代码中和用户名、密码进行加密运算。这里主要是换位加密,具体过程在代码里可见,后面我也需要进行Python改写。在页面代码中提取出所有相关的网址如下: # 验证码网址http://xxx.cn/verifycode.servlet**# 获取加密随机字符串http://xxx/Logon.do?method=logon&flag=sess****# 提交网址http://xxx/Logon.do?method=logon**这些网址在后面步骤很重要,所以先记录下来。然后根据页面ajax代码和wireshark捕包观察发给提交网址http://xxx/Logon.do?method=logon的数据包中的数据表单表项。可以发现提交给服务器的数据项主要为:view:1,useDogCode:"",encoded:"",RANDOMCODE:"这些就是后面我们在模拟登录的时候需要构造提交的数据。其中,view恒为1,useDogCode为空(我表示不能理解useDogCode是不是有程序员写代码时的怨气,为啥叫useDog),encoded就是用户名、密码、返回的随机数混淆编码后的字符串,RANDOMCODE就是图片验证码的值。

2、编写代码

import requestsimport os**# 验证码网址http://xxxx/verifycode.servlet*# 获取加密随机字符串http://xxx/Logon.do?method=logon&flag=sesssession = requests.session()url = "http://xxx/Logon.do?method=logon"def safe_int(num): try: return int(num) except ValueError: result = [] for c in num: if not ('0' <= c <= '9'): break result.append(c) if len(result) == 0: return 0 return int(''.join(result))*# 获取验证码*imgUrl = "http://xxx/verifycode.servlet"imgresponse = session.get(imgUrl, stream=True)session.cookies['pgv_pvi'] = '6853033984'print(session.cookies)image = imgresponse.contentDstDir = os.getcwd()+"\\"print("保存验证码到:"+DstDir+"code.jpg"+"\n")try: with open(DstDir+"code.jpg" ,"wb") as jpg: jpg.write(image)except IOError: print("IO Error\n")finally: jpg.closeverifycode = input("验证码")codeUrl = "http://xxx/Logon.do?method=logon&flag=sess"coderesponse = session.get(codeUrl, stream=True)bcode = coderesponse.contentprint(bcode)scode = bcode.split(b'#')[0].decode(encoding='utf-8')print(scode)sxh = bcode.split(b'#')[1].decode(encoding='utf-8')print(sxh)code = "MDkwNjE0MDExMQ==%%%aGFuanVuOTYwNTE0"#用户名和密码的编码encoded=""i=0while i<len(code): if i < 20: encoded = encoded+code[i:i+1]+scode[0:int(sxh[i:i+1])] scode = scode[int(sxh[i:i+1]):len(scode)] i=i+1 else: encoded = encoded+code[i:len(code)] i = len(code)print(encoded)*# 输入数据view:1,useDogCode:"",encoded:"",RANDOMCODE:*data = {"view":1, "useDogCode":"", "encoded=": encoded, "RANDOMCODE=": verifycode,}*# 数据包头*headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36", "Referer":"http://xxxx/Logon.do?method=logon",}response = session.post(url, data=data, headers=headers)print(response.content.decode('utf-8'))print("成功进入")

3、分析总结

经过了很长时间才成功暴力破解了我的一个同学的密码,效率真的很低参数序列有时候会和浏览器发的包不一样,你可以改成固定的序列,“view:1&useDogcode:&encoded":"编码的值"。手动输入验证码的问题,这个可以通过使用tesseract智能识别引擎来解决,这个我就不说了。网页中JS加密代码直接改写成python的就可以了。这里我还把网页的js代码截取下来,用同一个初始值和Python的对比,结果一直一样,应该没错。以后继续加油!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值