无题
flask
1.debug——PIN
考点:最新版本werkzeugd下的flask_pin码的求值
Flask debug pin的安全问题详细分析参考看https://xz.aliyun.com/t/2553,且大佬也给出了利用脚本。需要重点关注的也就是6个参数
username 启动这个Flask的用户
modname 一般默认flask.app
getattr(app, ‘name’, getattr(app.class, ‘name‘)) 一般默认flask.app为Flask
getattr(mod, ‘file’, None)为flask目录下的一个app.py的绝对路径,可在报错页面看到
str(uuid.getnode()) 则是网卡mac地址的十进制表达式
get_machine_id() 系统id
由于pin码构建需要这6个参数,但不同环境下,参数会有变化,除了默认不变的参数,其他参数我们可以这样获得:
username
可以从/etc/passwd或者/proc/self/environ环境变量中读取
网卡地址
读取这两个地址:/sys/class/net/eth0/address或/sys/class/net/ens33/address
getattr(mod, ‘file’, None)
flask目录下的一个app.py的绝对路径,这个值可以在报错页面看到。但有个坑,python3是app.py,python2中是app.pyc
machine_id()
linux的id一般存放在/etc/machine-id或/proc/sys/kernel/random/boot_i
windows读取注册表中的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography
对于docker机则读取读取/proc/self/cgroup获取get_machine_id()(docker后面那段字符串):
但是注意的是Flask下的werzeug版本在在2020年1月5号就发生了更新,代码发生了变化,因此要再读取到machine_id()的值的话需要先读取/etc/machine-id,再读取/proc/self/cgroup,并将第一个获取到的值与第二个获取到的id值进行拼接
详细文章说明:https://cloud.tencent.com/developer/article/1657739
当然如果指定了Werkzeug版本就可以避免该情况
Flask==1.0.2
Werkzeug==0.14.1
就可以像网上很多文章所写的一样可以正常构造了。至于对于我们这道题就只能是拼接出machine_id了。最终POC如下:
1 | import hashlib |
至于这6个参数这样获得:
1)首先通过dirsearch探测到存在file目录
访问后给出提示
2)尝试任意文件读取,很明显只有一个root用户具有登录权限,所以它很明显就是启动这个Flask的用户。
3)而从首页的debug报错页面又可以得到flask目录下的一个app.py的绝对路径
4)/file?filename=/sys/class/net/eth0/address 读取第五个参数
但这个值得注意的是需要将冒号去掉,然后转为十进制
5)/file?filename=/etc/machine-id获得的值与/file?filename=/proc/self/cgroup获得的容器id进行拼接,结果:6a7b652f3677464382b49ac8dc35ba0f4c56263c62231cb4bcc1223c454dd50a3176463b7342f00dc64795372edd9a7f
运行结果
回到首页
单击这个图标输入我们得到的pin码就可以进入控制终端了,通过popen进行执行命令。
Flag:flag{873894c49201cd995ee2c52e6270630d}
补充:
非预期:
任意文件读取环境变量,可以直接读取到flag。