
查看源代码,发现<!-- 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都不一样 就不发了。