记一次xss绕过
记一次xss之旅
事情的起因是我做完了那个xssme的小闯关 里面有些原理我也不是很懂 QAQ
我的js水平很差 js就没怎么好好用心学 最近在学thinkphp js画贪吃蛇代码不是太懂
然后就想起了之前渗透的表白墙网站 正好当靶场练练手
这次站长给我发了一个远古版本表白墙源码 基本功能就是把数据写入一个txt文件 然后php读取文件
然后再把数据展示出来 全程都没有用到数据库 你说厉不厉害 反正像我我这种废物都不会开发的 (最多是看懂别人写的代码
大概就长这个样子 哈哈 是不是很古老
既然是留言板 那我们就看看有没有什么xss攻击的地方
先来看看文件的基本功能
index.php代码如下(也就是表白墙的主页
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表白墙</title>
<script>
alert("表白网站后期会更新美化,当前版本不够漂亮但能正常使用,后期会做处理,本表白网站数据将会永久保存!有需要删除某数据的可以联系邮箱:xxxxxxx@qq.com");
window.onload=function() {
var llq=document.documentElement.clientHeight;
var nr=document.getElementById("nr");
var bbq=document.getElementsByClassName("bbq");
var wxhn=document.getElementsByClassName("wxhn");
var bbqnrbt=document.getElementsByClassName("bbqnrbt");
nr.style.height=llq+"px";
for(var i=0;i<bbq.length;i++){
bbq[i].s=i;
bbq[i].onclick=function(){
alert(bbqnrbt[this.s].innerText+"\n"+wxhn[this.s].innerHTML);
}
}
}
</script>
</head>
<body>
<div class="bt">
<div style="height: 100%;
margin-left:5px;
float: left;
border-radius:100%;
width: 120px;
background-image: url('http://q1.qlogo.cn/g?b=qq&nk=3152680200&s=640');
background-size:100% 100%;
background-color: #000000;">
</div>
<div style="height: 100%;float: left;width: 500px;">
<h1 style="width:100%;line-height: 120px;color: #000000; text-shadow:3px 3px 3px red; font-size: 45px;"align="center">樱花表白墙</h1>
</div>
<div style="height: 100%;float: left;width: 170px;">
<h1 class="tx" onclick="yqlj();">我要表白</h1>
</div>
<script>
function yqlj(){
alert("请不要输入\"<\",\">\"这样的违规字符!!!");
window.location.href="http://www.sakura.gold/wz/bbq/fb.html";
}
</script>
</div>
<div id="nr">
<div class="bbqt"></div>
<!-- <xmp></xmp> 可以在里面写代码 -->
<?php $tj=file_get_contents("bb.txt");echo $tj; ?>
</div>
</body>
</html>
我们点击我要表白就来到这个页面 也就是fb.html
然后就是后端判断的核心代码了 bbq.php
首先是接受4个传参
<?php
header("Content-Type: text/html; charset=UTF-8");
$mz=$_POST['mz'];
$nr=$_POST['nr'];
$ljdz=$_POST['lj'];
$wmz=$_POST['wmz'];
然后看看是怎么过滤的
function xxs($cnm){
$html=$cnm;
$hqzfdx=strlen($html); //获取字符串的长度
$zfdx=strpos($html,"<"); //获取<在字符串的位置 从零开始计数
$jqzf=substr($html,$zfdx,$zfdx-$hqzfdx+1); //截取非法字符串"<"
/*
这里截取字符串的方法也很有意思 一般我会想到用正则匹配
substr(string,start,length)
这里$zfdx-$hqzfdx其实就是该字符串在倒过来数的位置 也就是负数 只不过和start重合 需要截取一个字符串长度
所以要+1
*/
if($jqzf=="<") {
return "YES";
}else{
$html=$cnm;
$hqzfdx=strlen($html);
$zfdx=strpos($html,">");
$jqzf=substr($html,$zfdx,$zfdx-$hqzfdx+1);
if($jqzf==">"){
return "YES";
}else{
return "NO";
}
}
}
那么很明显就是过滤了<> 目前我还没有想到方法绕过
然后就是对非法字符和字符长度进行了限制
if(strlen($nr)>165){
echo '<meta charset="UTF-8"><script>alert("内容过长,超过了165个字节,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(strlen($wmz)>40){
echo '<meta charset="UTF-8"><script>alert("你的名字过长,超过了40个字节,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(strlen($mz)>40){
echo '<meta charset="UTF-8"><script>alert("对方的名字过长,超过了40个字节,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(strlen($ljdz)>225){
echo '<meta charset="UTF-8"><script>alert("链接过长,超过了225个字节,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}else{
if(xxs($mz)=="YES"){
echo '<meta charset="UTF-8"><script>alert("违规字符,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(xxs($nr)=="YES"){
echo '<meta charset="UTF-8"><script>alert("违规字符,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(xxs($ljdz)=="YES"){
echo '<meta charset="UTF-8"><script>alert("违规字符,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}elseif(xxs($wmz)=="YES"){
echo '<meta charset="UTF-8"><script>alert("违规字符,发布失败!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}else{
if($ljdz==""){
$ljdz="bbq.jpg";
}
if ($mz==''){echo '<meta charset="UTF-8">请写上Ta的名字!';}
elseif($nr==''){echo '<meta charset="UTF-8">请写上表白内容!';}
else{
$tj=file_get_contents("bb.txt");
$bbq = fopen("bb.txt", "w+");
fwrite($bbq,'<div class="bbq"><div class="tp" style="background-image: url('.$ljdz.');"><sapn class="bbqnrbt">TO : '.$mz.'    </sapn></div><h1 class="wxhn">'.$nr.'---'.$wmz."---".date("Y.m.d").'</h1></div>'."\r".$tj);
fclose($bbq);
echo '<meta charset="UTF-8"><script>alert("发布成功!");location.replace("http://www.sakura.gold/wz/bbq/");</script>';
}
}
}
?>
那么抓住重点 看看他是怎么输出的
<div class="bbq">
<div class="tp" style="background-image: url('.$ljdz.');">
<sapn class="bbqnrbt">TO : '.$mz.'    </sapn>
</div>
<h1 class="wxhn">'.$nr.'---'.$wmz."---".date("Y.m.d").'</h1>
</div>'."\r".$tj);
那就可以看到 这里$ljdz 图片地址是我们可以利用构造的 因为div自带<>标签
那么我们就在这里闭合标签
<div class="tp" style="background-image: url('.$ljdz.');">
用括号闭合 然后再在后面构造我们的攻击语句 然后再用//注释掉后面的 );"
是不是很熟悉 和sql注入一样的套路
<div class="tp" style="background-image: url(1.jpg)" onmousemove=alert("div")//);">
最后也是成功弹窗了2333333333333333333333333333
最后也是给出修复建议 过滤等于号 感觉这样就限制了大部分的xss代码
不过由于我水平有限 可能也有办法突破 反正我现在想不到
function xss($cnm)
{
$html = $cnm;
$hqzfdx = strlen($html); //获取字符串的长度
$zfdx = strpos($html, "<"); //获取<在字符串的位置 从零开始计数
$jqzf = substr($html, $zfdx, $zfdx - $hqzfdx + 1); //截取非法字符串"<"
if ($jqzf == "<") {
return "YES";
} else {
$html = $cnm;
$hqzfdx = strlen($html);
$zfdx = strpos($html, ">");
$jqzf = substr($html, $zfdx, $zfdx - $hqzfdx + 1);
if ($jqzf == ">") {
return "YES";
} else {
$html = $cnm;
$hqzfdx = strlen($html);
$zfdx = strpos($html, "=");
$jqzf = substr($html, $zfdx, $zfdx - $hqzfdx + 1);
if ($jqzf == "=") {
return "YES";
} else {
return "NO";
}
}
}
}
其实用正则匹配写会更加简单美观一点 这里就符合开发者风格了233333333333333333333
文章目录
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭