介绍
XSS——跨站脚本攻击。通过这个攻击手段,攻击者可以将恶意的 JavaScript 代码插入存在 XSS 漏洞的 Web 页面中,当用户浏览带有恶意代码的页面时,这些恶意代码会被触发,从而达到攻击的目的。可以说,XSS 是针对用户层面的攻击。
XSS的分类
通常,我们把 XSS 分为三个类型,即 存储型,反射型与DOM型。不同的类型原理各有差异,而且注入的点也不同。
存储型
存储型的 XSS,最大的特点是可持久化,因为在过滤条件差的情况下,存储型的 XSS 的恶意代码会直接被保存在服务器端的数据库中。而这个恶意代码被服务器读出输出到用户端的Web页面时,恶意代码会执行,从而达到攻击的目的。可以说存储型 XSS 是影响范围最大的 XSS。通常出现在评论、文章发表等可由用户输入,并随着服务器读出的地方,容易造成蠕虫,盗窃cookie等严重影响。
攻击流程大概是这样的:
攻击者在正常服务器中注入XSS代码,且被服务器储存在了数据库中 用户在网站登录状态下,访问了恶意服务器,且浏览了存在恶意脚本的页面 正常服务器将页面信息与XSS脚本一同返回 客户端解析了页面信息与XSS脚本代码,这时脚本代码会被执行,甚至会向攻击者的恶意服务器主动发起请求 此时,攻击者就可以从自己的恶意服务器中读取用户数据
反射型
非持久化,且需要使用钓鱼等手段欺骗用户点击恶意链接才能触发恶意代码。一般反射型 XSS 会出现在搜索页面,且大多数是用来获取用户的 cookie 信息的。虽然影响范围最大的是存储型的 XSS,但是现在针对存储型 XSS 的防御非常完备,所以在利用上,反射型的利用率还是比存储型高些。
攻击流程大概是这样的:
攻击者发送带有XSS恶意的脚本链接给客户(该链接是正常服务器存在注入点的链接,且带着我们注入的内容) 客户点击了恶意链接并访问了正常服务器 服务器将XSS与页面信息返回客户端 客户端解析后请求恶意服务器 攻击者读取用户信息
DOM型
DOM 型的 XSS 注入与反射型原理类似,只不过 DOM 型的 XSS 注入不需要经过后端代码处理,而是在前端 JavaScript 调用 DOM 元素时可能产生的漏洞,可能触发 DOM 型 XSS 的 JavaScript 代码:
document.referer 返回跳转或打开到当前页面的页面的URI window.name 可设置或返回存放窗口的名称的一个字符串 location 可以设置窗口跳转或者返回当前窗口的地址 innerHTML 内嵌HTML代码 documen.write 页面内写入字符
综上存储型的 XSS 危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和 DOM 型的 XSS 则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。
XSS的危害

XSS的注入
<div> user input
div>
可以用
div><script>[XSS]
script><div>
的手法进行注入,此时,代码就会变成以下这种形式
<div>
div> <script>[XSS]
script> <div>
div>
XSS的注入与一些绕过
前端代码:
<html> <head lang="en"> <meta charset="UTF-8"> <title>XSS测试
title>
head> <body> <form action="xss.php" method="post"> 你试试: <input type="text" name="test" /> <br/> <input type="submit" value="提交">
form>
body>
html>
后端代码:
$text=$_POST["test"]; echo $text; ?>
接下来我们来分析一下防御与绕过
一般来说,我们可以通过一些函数将 XSS 的某些关键字符过滤,如 preg_replace(),来防止注入。但是攻防是不断发展的,有防御,自然就有绕过,下面整理一下一些防御与绕过的姿势。
过滤引号 ‘’ 或 “”
$text=$_POST["test"]; if($text!=null){
$text=preg_replace("/'/","",$text); //过滤' $text=preg_replace("/\"/","",$text); //过滤" echo $text; } ?>
过滤script标签
$text=$_POST["test"]; if($text!=null){
$text=preg_replace("/,"",$text); //过滤 $text=preg_replace("/<\/script>/","",$text); //过滤 echo $text; } ?>
过滤script标签(不区分大小写)
$text=$_POST["test"]; if($text!=null){
$text=preg_replace("/,"",$text); //过滤 $text=preg_replace("/<\/script>/i","",$text); //过滤 echo $text; } ?>
过滤script标签(不区分大小写,过滤script及其之间的所有内容)
$text=$_POST["test"]; if($text!=null){
$text=preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $text); //过滤了
服务器端代码存在 url 解码的情况
$text=$_POST["test"]; if($text!=null){
$text=preg_replace("/
,"<",$text); //将
<转化为html实体< span="">
$text
=
preg_replace
(
"/>/"
,
">"
,
$text
)
;
//将>转化为html实体
$text
=
urldecode
(
$text
)
;
echo
$text
;
}
?
>
转化为html实体<>
其他XSS注入标签
之前的演示中使用的都是 标签,但是能利用 XSS 的恶意脚本中可使用的标签远远不止 标签。
下面列举其中某些常见的 XSS 注入方式
真实场景中遇到的 XSS 注入语句远不止这么点,这里不多赘述
使用某些标签的on方法
使用html实体编码绕过变形
使用 src 的方式在script标签中使用 Data URI scheme 直接嵌入文本
在 iframe 标签中使用 Data URI scheme 直接嵌入 BASE64 编码后的文本
使用html实体编码 BASE64 编码之后的 Data URI scheme
XSS的防御
对于 XSS,总体的防御思路大概是:
对用户的输入(和URL参数)进行过滤,对输出进行html编码。
也就是对用户提交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。
对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的 XSS 攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝 XSS 攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。
对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行。
在PHP中通常使用 htmlspecialchars 函数对用户输入的name参数进行html编码,将其转换为html实体。这个方法可以直接将‘<’,‘>’等与 XSS 有关的内容进行实体化,可以阻挡绝大多数 XSS 的攻击。
我们还可以服务端设置会话 Cookie 的 HTTP Only 属性,这样,客户端的 JavaScript 脚本就不能获取 Cookie 信息了
总结
以上就是我找到的一些绕过技巧。到这里我想说两句,针对不同的情况,绕过的手段是不同的,具体情况还是得具体分析。只要是人写出来的代码,总会有一定的漏洞,绕过与修补就是系统安全性不断提高的一个过程,只要不断学习,总会发现代码中可以被绕过的地方。
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229002.html原文链接:https://javaforall.net
