XSS注入原理以及一些绕过姿势

介绍

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注入原理以及一些绕过姿势_第1张图片

XSS的注入

所有能被XSS注入的地方,都有一个共同的特点:存在允许用户输入的地方,且未对用户的输入进行检查或者检查机制不够完备。这样就极有可能产生XSS注入。
一般注入手法是先关闭外围的标签,再插入我们注入的内容,如

<div>
	user input
div>

可以用

div><script>[XSS]script><div>

的手法进行注入,此时,代码就会变成以下这种形式

<div>div>
	<script>[XSS]script>
<div>div>

在页面加载的时候就会把我们的恶意代码给加载出来
同理,在注释标签以及其他各种HTML的属性值中也可以进行注入。

XSS的注入与一些绕过

接下来,我们构造一个简单的 XSS 注入,再看看一些绕过手法。
我们使用 PHPStudy,快速搭建一个Web环境

前端代码:

<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注入原理以及一些绕过姿势_第2张图片
点击提交后会在页面上打出输入的文字
XSS注入原理以及一些绕过姿势_第3张图片
接下来我们尝试注入,直接输入
结果如下(在最新版本 chrome 下不成功,估计是直接ban掉了 XSS 的注入,我换到 edge 下成功了)
XSS注入原理以及一些绕过姿势_第4张图片


接下来我们来分析一下防御与绕过
一般来说,我们可以通过一些函数将 XSS 的某些关键字符过滤,如 preg_replace(),来防止注入。但是攻防是不断发展的,有防御,自然就有绕过,下面整理一下一些防御与绕过的姿势。

过滤引号 ‘’ 或 “”


	$text=$_POST["test"];
	if($text!=null){
	$text=preg_replace("/'/","",$text);    //过滤'
	$text=preg_replace("/\"/","",$text);   //过滤"
	echo $text; 
}
?>

当引号被过滤时,我们的字符串就无法被输出了,这时可以用 “/[string]/”来代替,这样就可以将字符串内容打出来
比如:

绕过前:我们注入的内容无法被输出
XSS注入原理以及一些绕过姿势_第5张图片
XSS注入原理以及一些绕过姿势_第6张图片

绕过后:将想要输出的字符串打印弹框成功
XSS注入原理以及一些绕过姿势_第7张图片

过滤script标签


	$text=$_POST["test"];
	if($text!=null){
	$text=preg_replace("/
	echo $text;
}
?>

当 script 标签被过滤时,我们的 JavaScript 代码就无法被解析,但是这种只是过滤死了 script 小写形式,我们还是可以用大小写混淆的方法进行注入。
比如:

绕过前:我们的 JavaScript 代码内容被直接输出了
XSS注入原理以及一些绕过姿势_第8张图片
绕过后:
XSS注入原理以及一些绕过姿势_第9张图片

过滤script标签(不区分大小写)


	$text=$_POST["test"];
	if($text!=null){
	$text=preg_replace("/
	echo $text;
}
?>

加上i之后,过滤范围变成了不区分大小写,此时,可以使用嵌套的script标签进行绕过
比如:ipt>alert(/haha/)ipt>

绕过前:我们的js代码内容被直接输出了
XSS注入原理以及一些绕过姿势_第10张图片
绕过后:
XSS注入原理以及一些绕过姿势_第11张图片

过滤script标签(不区分大小写,过滤script及其之间的所有内容)


	$text=$_POST["test"];
	if($text!=null){
	$text=preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $text); //过滤了

在 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 信息了

总结

以上就是我找到的一些绕过技巧。到这里我想说两句,针对不同的情况,绕过的手段是不同的,具体情况还是得具体分析。只要是人写出来的代码,总会有一定的漏洞,绕过与修补就是系统安全性不断提高的一个过程,只要不断学习,总会发现代码中可以被绕过的地方。

你可能感兴趣的:(web安全,xss,web)