查看源代码,发现<!-- you are not admin -->
提示要以管理员身份登陆
尝试注册管理员账号,提示The username has been registered
于是尝试随便注册一个账号,发现注册成功,并能够登陆
根据页面提示,猜测是通过更改admin账号的密码获取flag
于是进入change password界面,读取源码
发现提示<!-- https://github.com/woadsl1234/hctf_flask/ -->
进入之后是这个网页的源码,通过观察发现代码中重新定义并使用了strlow函数
并且运用了nodeprep.prepare函数
百度之后发现这个函数存在unicode欺骗漏洞,会将ᴬ转换成A,再将A转换成a
于是注册ᴬdmin账号,进行登陆并改密码,就获取了管理员密码
最后登陆得到flag
此题还有其他解法,一题多解
访问页面,发现有注册登录。注册账户,进行登录。
登陆后为欢迎页面,发现有几个页面,浏览查看。
浏览每个页面的源码。
index
页面源码发现,提示
1 | <!-- you are not admin --> |
flag
应该在管理员页面中。
在change
页面,发现:
1 | <!-- https://github.com/woadsl1234/hctf_flask/ --> |
发现后台代码。
进行代码审计,存在数据库文件user.sql
,在里面发现admin
的信息,
1 | INSERT INTO `user` (`id`, `email`, `password_hash`, `username`) VALUES |
admin
账户的id
为1
。在之后实验中,发现其实没有对用户id
进行验证。
在模板文件index.html
,发现输出flag
的条件,
1 | {% if current_user.is_authenticated and session['name'] == 'admin' %} |
current_user.is_authenticated
是flask_login
中的用户管理的方法,同时还校验session
中的name
是否是admin
。
flask
把session
存在客户端的,而且只经过base64
编码和用密钥签名,所以只要知道key
就可以伪造session
。
但伪造session
还需要知道key
。在config.py
中发现了key
:
1 | SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123' |
整体思路是伪造session
,只要伪造了session
就可以获得flag
,但看到还有更改密码的功能,我们还可以通过伪造session
修改admin
的密码,进行登录。
关于falsk
的session
的解码和编码可以通过https://github.com/noraj/flask-session-cookie-manager
的脚本来实现,python2
和python3
有些差别,要选择对应的脚本。
现在伪造session
,模拟管理员登录。
这种方法我没成功,不知道什么原因。
不过我发现了另外一种方法,命令执行,在登录时候输入单引号',会跳转到报错页面,点击右上角的console,可以执行命令,然后就是慢慢找到flag了。
由于每次创建环境的flag都不一样 就不发了。