一、XSS是什么
XSS(Cross Site Scripting,跨站脚本攻击),是指恶意攻击者往web页面里插入恶意script代码,当用户浏览该页面时,嵌入其中web里面的script代码会被执行,从而达到恶意攻击用户的目的。
xss漏洞通常是通过php的输出函数将javascript代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。
常见的输出函数有: echo、printf、print、 print_r、 sprintf 、die、 var-dump 、var_export
二、XSS漏洞挖掘
常用绕过方式:
-
普通注入: <script>alert('XSS')</script> 或者 <script>alert(document.cookie)</script>
-
大小写绕过: <sCript>alert(document.cookie)</scRipt> 或者 <scRipt>alert('lady_killer9')</sCript>
-
双写绕过: <scr<script>ipt>alert( document.cookie )</scr<script>ipt> 或者 <scr<script>ipt>aleralertt(document.cookie)</scr<script>ipt>
-
html标签绕过 : <img src=x οnerrοr=alert('XSS');> 或者 <A HREF= http://192.168.11.135:81/phpinfo.php >link</A> 或者 <img src=x:alert(alt) οnerrοr=eval(src) alt=xss>
-
闭合标签绕过 : > </option></select><img src=x:alert(alt) οnerrοr=eval(src) alt=xss>
-
闭合+html标签绕过 : ></option></select><img src=x:alert(alt) οnerrοr=eval(src) alt=xss>
三、跨站脚本攻击XSS分类
-
反射型XSS:<非持久化> 攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。
-
存储型XSS:<持久化> 代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行,这种XSS非常危险,容易造成蠕虫,大量盗窃cookie(虽然还有种DOM型XSS,但是也还是包括在存储型XSS内)。存储型XSS不用考虑绕过浏览器的过滤问题,屏蔽性也要好很多。 。
-
DOM型XSS:基于文档对象模型Document Objeet Model,DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有很多对象,其中一些是用户可以操纵的,如uRI ,location,refelTer等。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。
3.1、反射型XSS示例
XssReflex.php:
变量 $XssReflex 获取 get 方式传递的变量名为 input 的变量值(值为一个字符串),然后直接通过echo()函数输出,注意这中间并未对用户输入进行任何过滤
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="input">
<input type="submit">
</form>
<br>
<?php
$XssReflex = $_GET['input'];
echo 'output:<br>'.$XssReflex;
?>
</body>
</html>
将其放在
/var/www/html/XSS/目录下,启动apache服务:
service apache2 restart
我们输入
<script>alert('xss')</script>
:
3.2、存储型XSS示例
XssStorage.php:
这个页面采用POST提交数据,生成、读取文本模拟数据库,提交数据之后页面会将数据写入sql.txt,再打开页面时会读取sql.txt中内容并显示在网页上,实现了存储型xss攻击模拟。
<span style="font-size:18px;"><meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<html>
<head>
<title>XssStorage</title>
</head>
<body>
<h2>Message Board<h2>
<br>
<form action="XssStorage.php" method="post">
Message:<textarea id='Mid' name="desc"></textarea>
<br>
<br>
Subuser:<input type="text" name="user"/>
<br>
<input type="submit" value="submit" onclick='loction="XssStorage.php"'/>
</form>
<?php
if(isset($_POST['user'])&&isset($_POST['desc'])){
$log=fopen("sql.txt","a");
fwrite($log,$_POST['user']."\r\n");
fwrite($log,$_POST['desc']."\r\n");
fclose($log);
}
if(file_exists("sql.txt")) {
$read= fopen("sql.txt",'r');
while(!feof($read)) {
echo fgets($read)."</br>";
}
fclose($read);
}
?>
</body>
</html></span>
将其放在/var/www/html/XSS/目录下,同时在该目录下创建一个sql.txt文件,因为apache配置的用户和用户组为www-data,所以需要chown www-data:www-data sql.txt,不然apache日志(/var/log/apache2)会报错:Permission denied in。
启动apache服务:
service apache2 restart
当我们在Message中输入
<script>alert('xss')</script>时,页面成功弹窗:
并且我们重启浏览器之后再加载该页面,页面依然会弹窗,这是因为恶意代码已经写入数据库中,每当有人访问该页面时,恶意代码就会被加载执行!
3.3、CTF中XSS示例
cd ByteCTF2021-Final-SEO/Dockerfile
docker-compose up -d
web服务:
http://192.168.11.135:80
使用w3af扫描后的结果如下:
四、防御 XSS 攻击
做好过滤,如何过滤
1、输入检查
在测试 XSS 时,经常需要输入一些特殊字符,所以在一开始直接做好输入检查有利于减少攻击的可能性。在协助业务修复漏洞的时候,经常推荐的方法就是
白名单限制,比如参数是个整数值,那直接限制死即可,若不符合就抛异常。不要单纯只想着过滤替换特殊字符,这很容易就被绕过了。
如果白名单范围不好确定,我就会采用黑名单的方式,把常用的 XSS payload 特殊字符或字符串做检测,比如
<script>、javascript:、<、>、'、"、&、#。
但是黑名单这种方式,有时结合业务场景,以及浏览器特性,就有可能找到绕过方法。
还有一定不要单纯只在客户端上做过滤,还要结合服务端做限制。若只是客户端上做过滤,那么抓包后修改数据重发就绕过了。
2、输出检查
跨站漏洞的触发关键点就在于输出的位置,所以对输出进行检查尤为重要。我们要根据不同的位置采取不同的 XSS 防御方案。
3、Httponly Cookie
如果你在
Cookie 中设置了 HttpOnly 属性,那 JavaScript 脚本将无法读取到 Cookie,这样就能防止通过 XSS 窃取 Cookie,在一定程度上能够减少 XSS 的攻击范围。
通过google浏览器安装EditThisCookie这个插件可以查看cookie,可以看下百度的加了HttpOnly
4、Content Security Policy
内容安全策略(Content Security Policy,
CSP)也是减少 XSS 攻击的一种方式 ,
是浏览器提供一种防御机制。它采用的是
白名单机制,告诉浏览器可以加载和执行哪些外部资源,这样就能防止被一些第三方恶意脚本注入执行。
开启 CSP 有两种方式:
(1)通过 HTTP 头信息的 Content-Security-Policy 的字段:
Content-Security-Policy: script-src 'self'; object-src 'none';style-src cdn.example.org third-party.org; child-src https:
(2)通过网页的标签设置:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; object-src 'none'; style-src cdn.example.org third-party.org; child-src https:">
五、参考
跨站脚本漏洞(XSS)基础讲解 - 简书 (jianshu.com)