Web漏洞之XSS

您所在的位置:网站首页 xss漏洞的危害 Web漏洞之XSS

Web漏洞之XSS

2023-03-13 08:48| 来源: 网络整理| 查看: 265

目录XSS跨站脚本攻击一、基础知识1、原理2、分类3、常用技术点(1)html字符实体绕过(2)html事件绕过(3)大小写混合绕过(Level 6)(4)双写绕过(Level 7)(5)编码绕过(Level 8)(6)http头部绕过(7)空格绕过(8)ng-include绕过(9)单、双引号绕过(10)http-only绕过二、XSS-labs靶场过关记录(都是反射型XSS)Level 1(签到)Level 2(字符实体htmlspecialchars)Level 3(html事件)Level 4(同上)Level 5(html事件,自写标签)Level 6(大小写绕过)Level 7(双写绕过)Level 8(编码绕过)Level 9(编码plus)Level 10(参数突破)Level 11(Referer字段)Level 12(User-Agent字段)Level 13(Cookie字段)Level 14(iframe,exif)Level 15(ng-include)Level 16(img标签)Level 17(swf文件)Level 18(同上)Level 19—Level 20(flash xss)三、pikachu靶场的XSS漏洞过关记录反射型XSS(get)反射型XSS(post)存储型XSS四、XSS平台五、XSS攻击工具XSS Strike(1)下载地址(2)安装使用:(3)用法 (部分搜寻的资料用于自学,如有侵犯,联系可删! ———— by 611)

XSS跨站脚本攻击

XSS是跨站脚本攻击(Cross-Site Scripting),由于如果简称为CSS会和重叠样式表产生歧义,所以该漏洞称为XSS。

一、基础知识 1、原理

​ XSS跨站脚本攻击是利用网页开发时web应用程序对用户输入过滤不足导致将恶意代码注入到网页中,使用户浏览器加载并执行恶意代码,通常是JavaScript类型,也包括java、vbs、flash、html等。用户浏览被XSS注入过的网页,浏览器就会解析这段代码,就被攻击了。(因为浏览器当中有JavaScript解析器,浏览器不会判断代码是否恶意,只要符合语法规则,就直接解析了。)

所以核心就是:让网页执行我们注入的恶意js代码。

2、分类

(1)反射型:通过URL触发XSS攻击,构造一个带有伪造用户输入信息的链接,用户点击之后被攻击。

(2)存储型:恶意代码被存储到服务器的数据库里,比如我们在论坛发帖、留言板等过程中嵌入了 XSS 攻击代码,当我们发布的帖子被用户浏览访问时就可以触发 XSS 代码,这种伤害是持续性的,因为恶意代码被存到了数据库里,所以访问一次就会触发一次。

(3)DOM型:与反射型类似,但是直接针对前端的。

什么是DOM?

​ 简单来说DOM文档就是一份XML文档,当有了DOM标准之后,DOM便将前端html代码化为一个树状结构,方便程序和脚本能够轻松的动态访问和更新这个树状结构的内容、结构以及样式,且不需要经过服务端,所以DOM型xss在js前端自己就可以完成数据的输入输出,不与服务器产生交互。

image-20230227105909884

也就是我们所输入的信息仅限于在前端处理,前端可能把这个值传给了某个标签的元素。

(4)DOM型和反射型的区别

​ 反射型XSS是通过将恶意脚本注入到URL参数、表单或其他用户可控输入的位置来实现的。然后,当用户访问带有这些恶意脚本的URL或提交带有这些恶意脚本的表单时,这些脚本会被浏览器执行,从而导致攻击者能够获取用户的敏感信息或执行其他恶意行为。反射型XSS通常需要攻击者诱导受害者点击一个带有恶意链接的URL,才能触发攻击。

​ DOM型XSS则是由于网站使用了客户端脚本(如JavaScript)动态修改了页面的内容,但未对用户输入进行充分的验证和过滤,导致攻击者能够注入恶意脚本,使其在浏览器中执行。DOM型XSS攻击不需要向服务器提交恶意数据,而是直接利用网站的客户端脚本漏洞,攻击者可以利用这些漏洞来篡改网页内容、窃取用户信息等。

​ 因此,反射型XSS和DOM型XSS的主要区别在于攻击者注入恶意脚本的位置不同,反射型XSS是在服务器返回给浏览器的响应中注入恶意脚本,而DOM型XSS是在浏览器中客户端脚本执行期间注入恶意脚本。

3、常用技术点

绕过姿势大全:XSS过滤绕过速查表

常用标签:

简单构造标签:

alert(1)

更好用的标签:

更好用的参数:

onmouseover=alert(1)

注意:把alert()中的内容换成document.cookie就能获取cookie。

(1)html字符实体绕过

​ 在html中,某些字符是预留的,比如< >等,html中是不能写大于号小于号的,因为浏览器会误认为他们是标签,如果想要正确地显示预留字符,必须在html源代码中使用字符实体。比如,如果想显示小于号,就必须写成或者<

htmlspecialchars(str)函数:将字符转换成字符实体。

​ 这样就会导致有的为了防止XSS攻击,会将输入的字符串中的特殊字符转换成字符实体,使得js代码中的标签符号被转换,代码就无法执行,比如Level 2。

​ 此时可以搜寻一下该参数还有哪里能出现,但是没对其进行转换的。

(2)html事件绕过

​ html事件就是浏览器或者用户做的某个事件,事件发生时,会执行什么样的操作,通常用于< input>、< select>、< a>等标签中。html事件包括:网页加载完成、按钮被点击、输入字段被修改等等,这些事件一旦被触发,就可以设置执行一些操作。所以我们就可以在相应的标签里加个事件,事件发生的操作就是我们注入的js代码,这样一旦事件触发,js脚本就会被执行。(比如level 3、level 4、level 5)

​ 常见的html事件如下:

事件 描述 标签 onclick 鼠标点击即触发 < input>、< a>、< select> onfocus 获得焦点时触发(就是确定光标位置时),可以是鼠标也可以是Tab < input>、< a>、< select> onerror 图片、视频、音频加载错误时触发 < img> onmouseover 鼠标移动到指定的对象时触发

以onfocus为例,onfocus事件在对象获得焦点时发生,简单来说就是光标移动过去,会发生什么事件。

举例:鼠标点击这个框,会触发背景色变为黄色的事件。

image-20221121191858956

image-20221121191936510

伪协议:

​ 与html事件组合的就是javascript的伪协议,比标签更方便,即:将恶意Js代码不再写成< script > alert(1) < /script >,而是使用伪协议的形式:javascript:alert(1) ,将恶意代码注入其中。

注意:

伪协议必须与动作相关联。伪协议表示的是在触发指定动作的时候执行的代码,所以要写入动作里,不能是单独写一句伪协议,无法执行。比如下面第一个图就无法注入成功,因为把伪协议单独写了,没将其放入动作里。

image-20230224112625723

image-20230224112717148

写完伪协议必须加个空格。否则有可能与后面的代码连接上,导致识别不出来是伪协议。

​ 不写空格时:

image-20230224113641729

​ 写了空格后:

image-20230224113548698

只要伪协议生效,后面是什么,注释、闭合,可以无关紧要。 (3)大小写混合绕过(Level 6) onclick ————> ONcLIk javascript ————> JavaScRIpt (4)双写绕过(Level 7) href ————> hrhrefef (如果按顺序过滤一次,就把中间的href留下了) javascript ————> javascri script pt (把中间的script过滤掉,但是两边组合在一起还是成功) (5)编码绕过(Level 8)

在诸多措施无法绕过的时候,可以对js代码进行Unicode编码,然后再注入,即可成功。

image-20221121205322819

原理分析:

Unicode与utf-8的关系

​ Unicode:计算机专家想把全世界的语言文字都能够在计算机中显示出来。而全世界的文字是非常多的,也不可能一个地方一个标准,比如1在亚洲表示中文"我"字,在非洲表示另外一种文字,这是不现实的,所以这个时候就有了一个统一的标准——Unicode,在这套标准下,同一个文字在任何一个地方的编号都是固定不变的。

但是毕竟计算机只认识0和1,这些编号(字符集)是需要转换成二进制来存储的(字节序列),那么为了高效且节省空间,就有了不同的存储方式,比如:utf-32、utf-16、utf-8等,utf-32就是把字符所对应的编号直接转换成二进制,然而有的文字在unicode中甚至用到了4个字节的长度,这样是非常浪费空间的,因此就诞生了改进版。

​ utf-8:utf-8是可变字节的,编号小的用的字节就少,编号大的用的字节就多。使用的字节个数从 1 到 4 个不等。

也就是说,utf-8、utf-16、utf-32都只是unicode的一种实现而已,是字符实际存储在内存中的样子而已。

对于html,客户端、服务器的编码解码过程

​ 假设现在这样一个过程:客户端发送数据,向服务器请求一个Html。(比如http://127.0.0.1/login.html)

Web服务器会接收http请求,把请求头解析出来,获取到客户端发送的数据。如果请求体是html数据,Web服务器会在目录中找到相应的html,然后将文本中的内容按照字符集编码(Unicode)转换成字节序列(utf-8),然后Web服务器会根据Http请求头中的 Accept-Encoding 指定的压缩方式(gzip、deflate等)进行压缩,将压缩后的字节序列发送给客户端。

​ Web 浏览器会接收到服务器返回的字节序列后,根据 HTTP 响应头中的 Content-Encoding 指定的压缩方式进行解压缩,得到原始的字节序列。然后,Web 浏览器会根据 HTTP 响应头中的 Content-Type 指定的字符集编码进行转换,将字节序列转换成相应的字符集编码,并将 HTML 文档的各个元素解析成 DOM 树结构。

​ 反过来过程也一样。

​ 因此,我们可以在传递数据的时候,就将其进行Unicode编码后再传递,相当于我们把一部分数据替他们提前编码了,这样既不影响文本内容(因为他们会解码),又可以绕过一些转义符或函数。

​ 除了用Unicode编码外,hex、Ascii、八进制等也都可以尝试。

(6)http头部绕过

​ 如果Http头部的信息在页面中有回显,那么就有可能在Http头部信息处存在XSS漏洞,比如,下图的网站回显了User-Agent的信息,我们就可以尝试抓包更改User-Agent的信,改成恶意js代码,就有可能触发。

image-20230225201316819

Referer字段绕过(Level 11) User-Agent字段绕过(Level 12) Cookie(level 13) (7)空格绕过

可以用/代替空格,或者采用编码。

(8)ng-include绕过

ng-include是Angular js中的东西(Angular js是一个javascript的框架),其作用相当于php中的include函数。

ng-include指令用于包含外部的html文件,值得注意的有如下几点:

ng-include,如果单纯指定地址,必须要加引号。 ng-include,加载外部html,script标签中的内容不执行。 ng-inculde,加载外部html中含有style标签样式可以识别。

所以如果某个网页用了ng-include,那么就可以填入一个包含恶意代码的html,让其去调用,从而引发恶意解析。

(9)单、双引号绕过 如果是html标签,我们可以不用引号。 如果是js中,我们可以用反引号代替单双引号。 编码绕过 (10)http-only绕过 什么是http-only?

​ http-only是一项浏览器专门为Cookie提供的属性,一旦Cookie设置了Http-Only属性(浏览器设置),那么就表示Cookie只能被http请求所携带,通过js脚本(document.cookie)是无法读取到Cookie信息的,这样就算存在XSS攻击,也可以有效地防止Cookie的内容被窃取,增加Cookie的安全性。

​ 需要注意的是:为了降低跨站点脚本攻击带来的损害,通常需要将HTTP-only Cookie和其他技术组合使用。如果单独使用的话,它无法全面抵御跨站点脚本攻击,也就是说,即使设置了http-onlt,我们也有方法获取Cookie。

如何绕过http-only?

​ 登录后台有两种方式:Cookie或账号密码。所以虽然没有办法读取Cookie,但是却可以直接获取账号密码,关于账号密码分为以下两种情况:网站保存账号密码;网站没保存账号密码。

保存账号密码:浏览器记录,直接读取用户浏览器即可。

未保存账号密码:需要用户自己输入,利用表单劫持。要求有输入框。(表单劫持就是让用户给XSS平台也提交一份表单信息,发一份账号密码)

​ 实现思路:构造一个与被攻击网站页面相同的钓鱼网站(F12,复制源码),然后将这个钓鱼网站作为XSS触发时的弹出页面,用户一旦触发XSS,就会弹出这个钓鱼网页,在相应的输入框输入信息,提交到我们的XSS后台。提交后真正的网站页面显示出来,而用户可能只会以为是登录失效或者没登录上去,重新输入信息发给真正的网站,但我们早在之前就已经劫持到了用户的表单信息。

二、XSS-labs靶场过关记录(都是反射型XSS)

过关方法:https://blog.csdn.net/wo41ge/article/details/107459332

过关标准:javascript代码成功执行(界面会弹出“完成的不错”,意味着过关了)

Level 1(签到)

1、观察发现URL中的参数name的值在界面进行了回显。

image-20221121175040684

2、考虑将name参数值写成js语句,执行成功,过关。

alert(1)

image-20221121175344738

image-20221121175357800

Level 2(字符实体htmlspecialchars)

1、在url或搜索框里输入js语句发现都无法执行。

image-20221121181319648

2、查看网页源代码发现, < h2>标签中对输入字符串中的大于号和小于号进行了字符实体的转义,因此应该是使用了htmlspecialchars函数。

image-20221121181447631

3、仔细观察发现input标签中的value处没有进行处理,所以根据提示信息进行符号闭合,即可通关。

"> alert(1)

image-20221121181804463

Level 3(html事件)

1、观察发现value都被处理了。

image-20221121193927300

2、可以在Input标签里写一个Html事件,让其执行js代码。(不用标签写,用javascript的伪协议写)

' Onclick=javascript:alert(1) >// 注意:>前面必须有个空格,要不然就不行 或者不用闭合也行,因为伪协议不闭合也可以执行,但是也得加个空格,要不然识别不出来。 ' Onclick=javascript:alert(1) (末尾加空格)

不写空格就不行的原因:如果不写空格,javascript:alert(1)直接跟转义符连在一起了,没法生效;写了空格之后,二者就分开了,伪协议就可以生效。

不写空格时:

image-20230224110823018

写了空格后:image-20230224110737547

3、将其写入后,需要点击搜索框,触发事件才能完成js代码的执行操作。

image-20221121200022615

image-20221121200037658

Level 4(同上)

方法一:跟level 3相同,只不过闭合号变成了双引号。

" onclick=javascript:alert(1) >//

image-20221121200343384

Level 5(html事件,自写标签)

1、像前两关一样,写html事件发现不成功,查看网页源代码发现input标签中对html事件进行了过滤,防止利用带有on字符的事件来触发恶意代码。

image-20221121201240715

2、换一个标签,新写一个a标签的,即可注入成功。

" > xss 也可以不闭合。 " > 被过滤掉了,所以用伪协议和html事件。但是如果把html事件写到标签里的最后一个位置,就必须要用>来闭合标签,再把后面的东西给注释掉,但是>被过滤掉了,所以没办法闭合。(下面是错误写法)

http://127.0.0.1/xss-labs/level10.php?keyword=11&t_sort=" onclick=javascript:alert(1) > // (错误写法)

image-20221122144016423

4、因此把这个事件写到标签的中间,让其后面有东西可接,这样就可以直接用原来代码里自带的>来闭合。另外,如果用onclick事件,就需要能触发,所以为了闭合引号,也为了有触发的东西,在Input标签里加个type=“text 有了文本框之后,鼠标一点击就可以触发事件,执行js代码。

http://127.0.0.1/xss-labs/level10.php?keyword=11 & t_sort=" onclick=javascript:alert(1) type="text

image-20221122143840081

5、闯关成功

image-20221122143920363

Level 11(Referer字段)

1、按照上一关的方法,发现这关有四个input标签,但是这关对t_sort中的值加了字符实体转义,所以该关卡无法再用上一关的方法搞。

image-20221122150843529

2、抓包发现http头部没有refer字段,加个refer字段后,发现refer的值居然出现在了t_ref的值中。

image-20221122151419312

3、在refer中构造恶意代码

referer:" onclick=javascript:alert(1) type="text

4、修改完成后,在bp的Proxy模块,点击Foward放包到浏览器,点击文本框即可通关成功。

image-20221122152456684

image-20221122152528399

Level 12(User-Agent字段)

1、与上关原理一样,只不过换成了User-Agent字段。

User-Agent:" onclick=javascript:alert(1) type="text

image-20221122153132510

image-20221122153154459

Level 13(Cookie字段)

1、同理,换成Cookie字段

Cookie: user=" onclick=javascript:alert(1) type="text

image-20221122153621868

image-20221122153631154

Level 14(iframe,exif) Level 15(ng-include)

1、界面简单,查看网页源代码也信息较少,所以只能查看服务器代码。

image-20221122155057125

2、发现有个get参数src,因此URL里输入参数,观察代码变化。

image-20221122155216273

3、发现传到了span标签里的class属性里,尝试闭合,但是字符被转义,所以只能利用ng-include的特点来上传,ng-include可以包含一个html文件,那么就意味着可以让其包含一个有恶意代码的html文件,那就可以用已经通过的关卡作为src,让其包含其中。用level 1的恶意URL尝试:

?src='level1.php?name=alert(1)' (错误)

4、发现不好用,因为 < 被转成了字符实体,所以要换种level 1里的恶意代码,因为上个代码在level 1里可以过关,但是这关有过滤。新写一个input标签,里面加html事件,则可成功。

?src='level1.php?name=


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3