-
Notifications
You must be signed in to change notification settings - Fork 99
Description
Success often depends upon knowing how long it will take to succeed.
###### 0x00 行首
#!/usr/bin/env python
脚本语言的第一行目的就是指出这个文件中的代码用什么解释器去执行。
#!/usr/bin/env python
和#!/usr/bin/python
的区别:
后者直接调用/usr/bin
下的python
,而前者首先回到env
设置里查找python
的安装路径,再调用
env
就是环境设置
###### 0x01 [扫描器的伪代码](http://www.freebuf.com/news/special/60758.html):
#导入socket,sys模块,如果是web服务那么还需要导入httplib,urllib等模块
<import modules>
#设置ip/端口
#调用脚本: ./script.py <RHOST> <RPORT>
RHOST = sys.argv[1]
RPORT = sys.argv[2]
#定义你的测试数据,并且设置测试数据范围值
buffer = '\x41'*50
#使用循环来连接服务并且发送测试数据
while True:
try:
# 发送测试数据
# 直到递增到50
buffer = buffer + '\x41'*50
except:
print "Buffer Length: "+len(buffer)
print "Can't connect to service...check debugger for potential crash"
###### 0x02 urllib模块
urllib.urlopen(url[,data[,proxies]])
打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作。
data
: 表示用post
的方式提交到url
的数据
proxies
: 用于设置代理
urlopen
返回对象提供的方法:
read()
,readline()
,readlines()
,fileno()
,close()
: 这些方法的使用方式和文件对象完全一样
info()
: 返回一个httplib.HTTPMessage
对象,表示远程服务器返回的头信息,和headers
一样,响应头
getcode
: 返回Http
状态码。如果是http
请求,200请求成功完成,404网址未找到
geturl
: 返回请求的url
#!/usr/bin/env python
# coding=utf-8
import urllib
url = 'http://www.baidu.com'
response = urllib.urlopen(url)
request = response.readline()
print request
- `urllib.urlretrieve(url[,filename[,reporthook[,data]]])`
urlretrieve
方法将url
定位到的html
文件下载到你本地的硬盘中。
如果不指定filename
,则会存为临时文件。
reporthook
是一个回调函数,当连接上服务器、以及相应的数据块传输完毕时会触发该回调,可以利用这个回调函数来显示当前的下载进度。
data
指post
到服务器的数据,默认是get
,
data
必须是application/x-www-form-urlencoded
格式。
urlretrieve()
返回一个二元组(filename,mine_hdrs)
。
#!/usr/bin/env python
# coding=utf-8
import urllib
def callbackfunc(blocknum, blocksize, totalsize):
'''回调函数
@blocknum:已下载的数据块数量
@blocksize:数据块大小
@totalsize:远程文件的大小
'''
percent = 100 * blocknum * blocksize / totalsize
if percent > 100:
percent = 100
# %% 代表 % 的转义
print '%.2f%%' % percent
url = 'http://www.baidu.com'
# \\ 代表 \ 转义 根目标,.\\ 代表 .\ 当前目标
local = '\\baidu.html'
urllib.urlretrieve(url, local, callbackfunc)
- `urllib.urlcleanup()`
清除由于
urllib.urlretrieve()
所产生的缓存
- `urllib.quote(url)` 和 `urllib.quote_plus(url)`
将
url
数据获取之后,并将其编码,从而适用于url
字符串中,使其能被打印和被web
服务器接受。
urllib.quote('http://www.baidu.com')
urllib.quote_plus('http://www.baidu.com')
- `urllib.unquote(url)` 和 `urllib.unquote_plus(url)`
解码和上面相反
- `urllib.urlencode(query)`
将
url
中的键值对以连接符&
划分
与urlopen
结合可以实现post
和get
方法
#!/usr/bin/env python
# coding=utf-8
'''GET方法
'''
import urllib
params = urllib.urlencode({'spam':1, 'eggs':2, 'bacon':0})
f = urllib.urlopen('http://www.baidu.com/query?%s' % params)
print f.read()
#!/usr/bin/env python
# coding=utf-8
'''POST方法
'''
import urllib
params = urllib.urlencode({'spam':1, 'eggs':2, 'bacon':0})
f = urllib.urlopen('http://www.baidu.com/query', params)
print f.read()
###### 0x03 urllib2模块
urllib2
模块定义的函数和类用来获取URL
(主要是HTTP
的),提供一些复制的接口用于处理基本认证,重定向,
Cookies
等
- `urllib2.urlopen(url[,data][,timeout])`
传
url
时候,用法同urllib
里的urlopen
。
url
参数可以是一个字符串url
或者是一个Request
对象。
data
可以是指定的发给服务器的一条字符串类型的数据,当data
参数提供时,HTTP
的请求会由POST
替代GET
。data
是一个标准application/x-www-form-urlencoded
格式的缓存
timeout
,阻塞操作以秒为单位,如尝试连接(如果没有指定,使用设置的全局默认timeout
值),实际上这仅适用于HTTP
,HTTPS
,FTP
。
#!/usr/bin/env python
# coding=utf-8
import urllib2
url = 'http://www.baidu.com'
response = urllib2.urlopen(url)
page = response.read()
- `urllib2.Request(url[,data][,headers][,origin_req_host][,unverifiable])`
Request
类是一个抽象的URL
请求。
data
同上,因为数据标准是'application/x-www-form-urlencoded'格式,所以向一个URL
发送数据时,这些数据需要被以标准的格式编码(encode
),即调用urllib.urlencode()
,然后作为一个数据参数传送给Request
对象。
#!/usr/bin/env python
# coding=utf-8
import urllib
import urllib2
url = 'http://www.baidu.com'
values = {'name':'aa', 'location':'dd', 'language':'ff'}
data = urilib.urlencode(value)
req = urllib2.Requset(url, data)
response = urllib2.urlopen(req)
page = response.read()
headers
是字典类型,头字典可以作为参数在request
时直接传入,也可以把每个键和值作为参数调用add_header()
方法来添加。作为辨别浏览器身份的User-Agent
,header
是经常被用来伪装的。
#!/usr/bin/env python
# coding=utf-8
import urllib
import urllib2
url = 'http://www.baidu.com'
user_agent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0'
value = {'name':'aa', 'location':'dd', 'language':'ff'}
headers = {'User-Agent':user_agent}
data = urllib.urlencode(value)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
page = response.read()
标准的
headers
组成是(Content-Length
,Content-Type
,Host
),只有在Request
对象调用urlopen()
或者OpenerDirector.open()
时加入。
#!/usr/bin/env python
# coding=utf-8
import urllib2
req = urllib2.Request('http://www.baidu.com')
#Request对象调用add_header(key, val)方法附加header
req.add_header('Referer', 'http://www.saaa.com')
response = urllib2.urlopen(req)
OpenerDirector
对象为每一个Request
自动加上一个User-Agent header
。
urllib2.build_opener()
会返回一个OpenerDirector
对象。
#!/usr/bin/env python
# coding=utf-8
import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-Agent', 'Mozilla/5.0')]
opener.open('http://www.baidu.com')
- `urllib2.install_opener(opener)` 和 `urllib2.build_opener([handler,...])`
install_opener
和build_opener
这两个方法通常在一起使用,有时候也用build_opener
单独使用来获得OpenerDirector
对象。
install_opener
实例化会得到OpenerDirector
对象,用来赋予全局变量opener
。如果想用这个opener
来调用urlopen
,那么就必须实例化得到OpenerDirector
,这样就可以简单的调用OpenerDirector.open()
来代替urlopen()
。
build_opener
实例化也会得到OpenerDirector
对象,其中参数handlers
可以被BaseHandler
或他的子类实例化。子类中可以通过以下实例化:ProxyHandler
(如果检测代理设置用)扫描代理会用到,UnknownHandler
,HTTPHandler
,HTTPDefaultErrorHandler
,HTTPRedirectHandler
,FTPHandler
,FileHandler
,HTTPErrorProcessor
。
#!/usr/bin/env python
# coding=utf-8
import urllib2
req = urllib2.Request('http://www.baidu.com')
opener = urllib2.build_opener()
urllib2.install_opener(opener)
f = opener.open(req)
如上使用
urllib2.install_opener()
设置urllib2
的全局opener
。这样后面的使用会很方便,但不能做更细粒度的控制,比如想在程序中使用两个不同的Proxy
设置等。比较好的做法是不使用install_opener
去更改全局的设置,而只是直接调用opener
的open
方法代替全局的urlopen
方法。
关于Opener
和Handler
之间的关系,当获取一个URL
时,可以使用一个opener
(一个urllib2.OpenerDirector
实例对象,可以由build_opener
实例化生成)。正常情况下程序一直通过urlopen
使用默认的opener
(也就是说当使用urlopen
方法时,是在隐式的使用默认的opener
对象),但也可以创建自定义的openers
(通过操作handlers
创建的opener
实例)。所有的重活和麻烦都交给这些handlers
来做。每一个handler
知道如何以一种特定的协议(http
,ftp
等等)打开url
,或者如何处理打开url
发生的HTTP
重定向,或者包含的HTTPCookie
。创建openers
时如果想要安装特别的handlers
来实现获取url
(如获取一个处理cookie
的opener
,或者一个不处理重定向的opener
)的话,先实例一个OpenerDirector
对象,然后多次调用.add_handler(some_handler_instance)
来创建一个opener
。或者可以用build_opener
,这是一个很方便的创建opener
对象的函数,它只有一个函数调用 。build_opener
默认会加入许多handlers
,它提供了一个快速的方法添加更多东西和使默认的handler
失效。
install_opener
如上所述也能用于创建一个opener
对象,但是这个对象是(全局)默认的opener
。这意味着调用urlopen
将会用到你刚创建的opener
。也就是说上面的代码可以等同于下面这段。这段代码最终还是使用的默认opener
。一般情况下我们用build_opener
为的是生成自定义opener
,没有必要调用install_opener
,除非是为了方便。
#!/usr/bin/env python
# coding=utf-8
import urllib2
req = urllib2.Request('http://www.baidu.com')
#创建opener对象
opener=urllib2.build_opener()
#定义全局默认opener
urllib2.install_opener(opener)
#urlopen使用默认opener,但是install_opener
#已经把opener设为全局默认了,这里便是使用上面的建立的opener
f = urllib2.urlopen(req)
###### 0x04 异常处理
当调用
urllib2.urlopen
的时候不会总是这么顺利,就像浏览器打开url
时有时也会报错,所以就需要有应对异常的处理。说到异常,先来了解返回的response
对象的几个常用的方法:
geturl()
— 返回检索的URL
资源,这个是返回的真正url
,通常是用来鉴定是否重定向的
info()
— 返回页面的原信息就像一个字段的对象, 如headers
,它以mimetools.Message
实例为格式(可以参考HTTP Headers
说明)。
getcode()
— 返回响应的HTTP
状态代码,运行下面代码可以得到code=200
当不能处理一个response
时,urlopen
抛出一个URLError
(对于python APIs
,内建异常如,ValueError
,TypeError
等也会被抛出。)
HTTPError
是HTTP URL
在特别的情况下被抛出的URLError
的一个子类。下面就详细说说URLError
和HTTPError
。
URLError
——handlers
当运行出现问题时(通常是因为没有网络连接也就是没有路由到指定的服务器,或在指定的服务器不存在)
HTTPError
——HTTPError
是URLError
的子类。每个来自服务器HTTP
的response
都包含status code
. 有时status code
不能处理这个request
. 默认的处理程序将处理这些异常的responses
。例如,urllib2
发现response
的URL
与你请求的URL
不同时也就是发生了重定向时,会自动处理。对于不能处理的请求,urlopen
将抛出 - - -HTTPError
异常. 典型的错误包含‘404’ (没有找到页面), ‘403’ (禁止请求),‘401’ (需要验证)等。它包含2个重要的属性reason
和code
。
程序对于重定向时是默认处理的。