python库的学习

前言

python,最好的脚本语言,学就完了。

Requests库

之前写盲注脚本的时候就用过Requests库了,许多web题也都需要用上这个库。Requests支持cookie、文件上传、自动确定相应内容编码、自动编码等等,因此十分好用。

发送请求

最简单最常用的方法,http协议中有多种请求方法,我们都可以用requests库中的函数来发送对应请求:

1
2
3
4
r = requests.get('https://www.baidu.com') #发送GET请求
r = requests.post('https://www.baidu.com',data = {'username':'mrl64','password':'123hahaha'}) #发送POST请求
r = requests.head('https://www.baidu.com') #发送HEAD请求
……

获取请求头/响应头

这里用GET举例,感觉直接用bp更快就是了,不过python可以获取指定单一请求头,有时候还是会用到的,POST请求同理。

获取请求头:

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.request.headers
print(flag)


{'User-Agent': 'python-requests/2.26.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

获取请求头某一属性:

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.request.headers['User-Agent'] #不区分大小写
print(flag)


python-requests/2.26.0

获取响应头:

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.headers
print(flag)


{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Sat, 15 Jan 2022 11:50:24 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:24:46 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}

获取响应头某一属性:

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.headers['Date'] #不区分大小写
print(flag)


Sat, 15 Jan 2022 11:51:41 GMT

获取内容

本质上和上面那部分大差不差,直接获取html,Requests会自动解码来自服务器的内容,大多数unicode字符集都能被正确编码:

1
2
3
4
5
6
7
8
9
10
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.text
print(flag)


<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type……

我们也可以通过encoding属性来查看编码:

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.encoding
print(flag)


ISO-8859-1

获取字节对象

无论响应是文本还是二进制内容,我们都可以用content属性获得bytes对象,Requests 会自动为你解码 gzip 和 deflate 传输编码的响应数据。

1
2
3
4
5
6
7
8
9
import requests

url = 'https://www.baidu.com'
r = requests.get(url)
flag = r.content
print(flag)


b'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type……

传递参数

使用dict类型变量传递参数,这也是在写脚本时非常常用的一个方法。如果要传递GET请求的参数,我们使用params进行传递:

1
2
3
4
5
6
7
8
9
10
import requests

url = "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/"
param = {"id": "1"}
r = requests.get(url, params=param)
flag = r.url
print(flag)


http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/?id=1

当然,我们更常用到的是POST请求发送参数或者对请求头进行注入等等,这时候我们应该使用data headers cookie等等进行参数传递:

1
2
3
4
5
6
7
8
9
10
11
12
import requests

url = "https://www.baidu.com"
head = {
"X-Forwarded-For": "127.0.0.1"
}
r = requests.get(url, headers=head)
flag = r.request.headers['X-Forwarded-For']
print(flag)


127.0.0.1

传递cookie参数也可以通过这种方式。

传递json参数

这点单拎出来讲,因为一般我们post参数,都是直接post,没管post的数据的类型,此时其默认类型为application/x-www-form-urlencoded。但是如果我们需要传递json格式的数据时就需要进行数据类型指定,当然json是可以直接使用json参数传递的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
import json

url="https://www.baidu.com"
data={'a'=123}
head = {'Content-Type': 'application/json'};
r = requests.post(url=, headers=head, data=json.dumps(data))

或者

import requests

data = {
'a': 123
}
response = requests.post(url='url', json=data)

Session保持请求

写dvwa盲注时就用到了session,Session()能在多次请求中保持一些参数,最常用的一般是拿来保持cookie。同样会话对象可以通过GET或POST方法发送请求,我们以POST方法为例:

1
2
3
4
5
6
7
8
9
import.requests

s = request.Session()
url = "http://127.0.0.1/DVWA/vulnerabilities/sqli_blind/"
head = {'Cookie':'security=low;PHPSESSID=c2fad3pjoio31n2i15243jrb2n'}
data = {
'id':'1'
}
r = s.post(url,data=data,headers=head)

任何你传递给请求方法的字典都会与已设置会话层数据合并。方法层的参数覆盖会话的参数。

不过需要注意,就算使用了会话,方法级别的参数也不会被跨请求保持,如下面这个例子,只有第一个请求发送了cookie:

1
2
3
4
5
6
7
8
9
s = requests.Session()

r = s.get('http://httpbin.org/cookies', cookies={'from-my': 'browser'})
print(r.text)
# '{"cookies": {"from-my": "browser"}}'

r = s.get('http://httpbin.org/cookies')
print(r.text)
# '{"cookies": {}}'

base64库

base64加解密

base64.bxxencode接受一个字节数组bytes用于加密,返回一个bytes存储加密之后的内容。
例如:

1
2
s = "mrl64"
t = base64.b64encode(s.encode('UTF-8'))

base64.bxxdecode接受一个存放着密文的bytes,返回一个bytes存放着解密后的内容。
例如:

1
2
s = 'bXJsNjQ='
t = base64.b64decode(s)

同时支持base64、base32、base16加解密。

url编码

由于标准的Base64编码后可能出现字符+和/,在URL中就不能直接作为参数,所以又有一种”url safe”的base64编码,其实就是把字符+和/分别变成-和_。

1
2
3
4
5
6
7
8
9
10
11
12
13
import base64

s = 'mrl64'

t = base64.urlsafe_b64encode(s.encode('UTF-8'))
print(t)

t = base64.urlsafe_b64decode(t)
print(t)


b'bXJsNjQ='
b'mrl64'

具体可以参考下面这篇博客:
Python标准库base64用法简介

Pillow

这个库相当于是PIL的plus版,支持Python3.x,同时兼容原来PIL的功能。这个库主要用来处理图像。

Pillow库安装成功后,导包时要用PIL来导入,而不能用pillow或Pillow。

1
2
import PIL
from PIL import Image

由于是misc方面的内容,而且我也就稍微学了下,就不多叙述了。具体的参考下面这篇博客:
Python Pillow(PIL)库的用法介绍

这里留一个二进制转化二维码脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import PIL from Image
MAX = 25#定义二维码的长款
pic = Image.new("RGB",(MAX, MAX))#创建一个图片
str = ""
i=0
for y in range (0,MAX):
for x in range (0,MAX):
if(str[i] == '1'):
pic.putpixel([x,y],(0, 0, 0)) #填充像素[坐标],(r,g,b)元组值
else:
pic.putpixel([x,y],(255,255,255))
i = i+1
pic.show() #显示图像
pic.save("flag.png") #保存图像

如果给的数据不是二进制字符串而是rgb的值,可以将for循环中的内容稍作改变:

1
2
3
4
5
6
for i in range(0, x):
for j in range(0, y):
line = file.readline() #获取一行的rgb值
rgb = line.split(", ") #分离rgb,文本中逗号后面有空格
im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2]))) #将rgb转化为像素

总结

python库是python作为脚本语言如此强大的底气所在,这里记录了3个基础的库,在之后我们也会接触学习更多新内容的。