这题的三种方法都是姿势盲区。。。。第三种方法只给个介绍。。因为好像复现的话不能成功,但是学习学习这种方法的思想。
我做题目的时候一直以为这题应该是SQL注入。。。在登录那里被卡了好久。。最后发现屁用都没有。。
首先!我们先注册一个再登录,在change password那里查看源码,可以看到有提示:
但是我并没有看到。。。这题也深深的教会了我,虽然页面可能有点多,源码还是要好好看看。。自己以后一定要注意这个,f12看源码的时候一定要仔细而且看全,一定不要漏掉了某个页面。 我们进入这个github,把文件下载下来,发现是flask模板。 然后就引入我们的第一种解法,flask session的伪造。因为flask的session是在客户端的,因此可以尝试进行伪造。破解不难,但是伪造需要密钥。正好密钥就在我们下载的文件夹里: 密钥是ckj123。因此可以进行伪造。 首先是解密,解密脚本如下:
#!/usr/bin/env python3 import sys import zlib from base64 import b64decode from flask.sessions import session_json_serializer from itsdangerous import base64_decode def decryption(payload): payload, sig = payload.rsplit(b'.', 1) payload, timestamp = payload.rsplit(b'.', 1) decompress = False if payload.startswith(b'.'): payload = payload[1:] decompress = True try: payload = base64_decode(payload) except Exception as e: raise Exception('Could not base64 decode the payload because of ' 'an exception') if decompress: try: payload = zlib.decompress(payload) except Exception as e: raise Exception('Could not zlib decompress the payload before ' 'decoding the payload') return session_json_serializer.loads(payload) if __name__ == '__main__': print(decryption(sys.argv[1].encode()))把name改成admin,再进行加密。加密的脚本这样获取:
git clone https://github.com/noraj/flask-session-cookie-manager然后进行加密: 再利用伪造的session,成功登录admin账号:
说实话真的是知识盲区。。。能想出来的大师傅真的是太强了叭。。
首先注意: 更改密码的里面有这样一句代码:
name = strlower(session['name'])注意strlower:
def strlower(username): username = nodeprep.prepare(username) return username这个nodeprep.prepare存在漏洞。我们还会发现,login的时候又strlower一次。这个本来是转小写的,但是如果我们注册的用户名是这个: ᴬᴰᴹᴵᴺ login的时候会经过一次strlower会编程ADMIN,在change password的时候会变成admin。因此可以更改admin的密码,从而完成登录。
具体可查Unicode字符表
ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘʀꜱᴛᴜᴠᴡʏᴢ
只能说太巧妙了。。。ORZ ORZ ORZ ORZ ORZ
原理如下: 这个主要就是因为再session赋值的时候都是直接进行赋值,而并没有进行验证,也就是说,比如我们随便注册个用户123,然后进程1再使用用户123重复的进行登录,改密码操作,进程2重复进行注销登录,同时用admin用户和进程2修改的密码进行登录,然后某个时刻进程1刚好要修改密码,进程2恰好要登录,就将进程2 admin的session给了进程1,从而改掉了admin的密码
具体可以参考下面的文章: 一题三解之2018HCTF&admin