Python学习记录(十二):乌云漏洞搜索爬虫&多线程
PyxYuYu opened this issue · 1 comments
PyxYuYu commented
The best accessory a girl can own is confidence.
0x01 Wooyun
- 任意文件遍历/下载
- 利用
shadan
搜索,寻找统一管理系统的网站,查看源代码,/Picture?imagePath=
很明显的下载漏洞,下载网站源码
- 利用
0x02 Wooyun爬虫
- 乌云搜索爬虫
- 需求分析:
- 根据输入关键词搜索漏洞
- 最后输出保存为
html
形式 - 多线程
- 命令行参数
- 实现步骤:
url
页面解析- 采用
urllib2
模块,添加User-Agent
用户代理
- 采用
User-Agent
采用random
模块实现随机的功能P.s.
random
模块 常用函数random.random()
用于生成一个0到1的随机浮点数: 0 <= n < 1.0random.randint(a, b)
用于生成一个指定范围内的整数,其中 a 是下限,b 是上限,生成的随机数n: a <= n <= brandom.randrange([start], stop[, step])
从指定范围内,按指定基数递增的集合中获取一个随机数 如random.randrange(10, 100, 2)
就是相当于[10, 12, 14, 16, ..., 96, 98] 序列中随机获取一个,等同于random.choice(range(10, 100, 2))
random.choice(sequence)
list
tuple
字符串
都属于sequence
random.shuffle(x[, random])
用于将一个列表中的元素打乱random.sample(sequence, k )
从指定序列中获取随机长度的片段
urlopen
涉及到timeout
问题,假如网络出现问题,程序会卡死在read()
方法中,只要设置timeout
就会抛出异常,所以需要添加一个异常处理,(如果需要对产生异常的url重新获取的话,可以用while
循环,不过有可能还是会出现time out
)- 异常处理
try...except...else
没有检测到异常的时候,则执行else
语句,else
不能单独和try
使用finally
无论是否检测到异常,都会执行finally
语句- 如果没有
except
,那么执行完try
finally
,然后重新引发这个异常
- 如果没有
- 如果需要截获多个异常,可以一个
except
语句带多个异常,也可以多个except
语句 - 一个
except
语句,异常类实例就是第一个出现错误的异常(的详细原因),后面的异常就不会执行了,如果是多个except
语句,那么截获的异常类之间应该具有继承关系,子类在前面,否则父类会直接截获子类的异常,放在后面的子类就不会被执行,因为在异常处理中,出现异常时,Python
将停止try
中的语句进行,将异常传递给except
进行匹配,如果找到,就执行except
后面的处理,处理完成后继续处理try
后面的语句,如此进行反复操作 - 如果只是调用了
except
语句,不接任何的Exception
,将会导致上面的异常错误被覆盖掉,所以在使用异常处理的时候,最好清楚指定可能出现的异常类型并进行针对性处理 raise
允许程序抛出自定义异常,用于描述Python
中未定义的异常,必须继承Exception类,命名以Error
结尾,如果在if
语句中,通过判断,如果判断成功抛出一个异常,可以用raise Exception(自定义的异常输出信息)
的方法简便的代替try except
url
网址全部放入到一个队列中保存for
循环中,range
和xrange
的区别range
返回一个列表xrange
返回一个生成器,生成器是一个可迭代的对象- 需要循环一个较大的数据时,
xrange
比range
好,因为xrange
每次迭代后,数据对象会被回收,占用的内存空间会空闲出来重复利用,内存不会暴涨,而range
创建了一个巨大的数字列表,需要提供较大的存储空间
for
循环最后的页面无法放入队列中,所以需要在最后单独放入最后的页面到队列url
页面分析,寻找关键字- 分析可以用
BeautifulSoup
模块,提取漏洞标题和漏洞链接find_all
中参数href
、title
,href
后面可以接re.compile()
来正则匹配出符合的带url
的Tag
,而因为乌云的页面上,会出现两个相同的url
,所以继续用title
来过滤掉其中一个
- 关键字寻找则去匹配漏洞标题
- 首先因为
BeautifulSoup
模块找到的Tag.string
是Unicode
类型,所以如果传入的是中文字符,需要带前缀u
,代表是Unicode
,但是如果是自己指定的话,那么只能用unicode()
方法来转换成Unicode
类型,这里传入的都是utf-8
类型 P.s.
前缀r
代表这写字符串是普通字符raw
,也就是转义的\
,在这里也会失效,在正则表达式中,首先满足正则,然后满足转义,也就是说如果需要匹配\
,那么正则的话,就是\\
来匹配,但是匹配时候,每个\
又需要转义,所以就是\\\\
,如果加上r
,就不需要再次地转义,只要满足正则就可以了,所以加上前缀r
很重要- 多个关键字的话,需要用
|
分割开,关键字传入后,先转换成Unicode
,然后用split()
分割成一个列表,逐个匹配
- 首先因为
- 多线程分析关键字
- 每个子线程都去参与搜集
url
分析关键字漏洞 - 线程的参数在
__init__
中定义 - 注意点:尽量少用给同一个变量自己覆盖自己,尤其是字符串类型
- 比如
url = url + str(i)
后面再用这个url
加上应该加的东西的话,其实url
已经改变了
- 比如
- 每个子线程都去参与搜集
- 命令行参数
- 设定线程数,设定搜索关键字,设定起始页面,设定终止页面
- 利用
argparse
模块
print
输出函数有限制,有一些特殊的unicode
字符不能输出到cmd
中,会报错UnicodeEncodeError: 'gbk' codec can't encode character u'\u30fb' in position 4: illegal multibyte sequence
而cmd
默认是gbk
,假如encode('gbk')
还是不行,那就用gb18030
(包括了gbk
),encode('gb18030')
- 如果编码仍然有错误,
cmd
无法正确显示编码,那么只有改变标准输出的默认编码 添加一句sys.stdout = io.TextIOWrapper (sys.stdout.buffer,encoding='gb18030')
- 如果编码仍然有错误,
- 需求分析:
0x03 一天总结
- 如何显示搜索的进度,这一点还需要继续研究
- 多线程、命令行都已经实现,保存为html文件明天完成
fxffanxiaofeng commented
11222