CTF学习笔记——跨站脚本攻击

跨站脚本攻击

简介:

​ XSS (Cross Site Scripting),即跨站脚本攻击,是一种常见于 Web 应用中的计算机安全漏洞。恶意攻击者往 Web 页面里嵌入恶意的客户端脚本,当用户浏览此网页时,脚本就会在用户的浏览器上执行,进而达到攻击者的目的。比如获取用户的 Cookie、导航到恶意网站、携带木马等。借助安全圈里面非常有名的一句话:*所有的输入都是有害的。*这句话把 XSS 漏洞的本质体现的淋漓尽致。大部分的 XSS 漏洞都是由于没有处理好用户的输入,导致恶意脚本在浏览器中执行。任何输入提交数据的地方都有可能存在 XSS。

分类:

按漏洞成因:

  1. 反射型
  2. 存储型
  3. DOM型

按输出位置:

  1. 输出在HTML属性中
  2. 输出在 CSS代码中
  3. 输出在JavaScript 中

反射型

反射型XSS也被称为非持久性XSS,是现在最容易出现的一种XSS漏洞。当用户访问一个带有XSS代码的URL请求时,服务器端接收数据后处理,然后把带有XSS代码的数据发送到浏览器,浏览器解析这段带有XSS代码的数据后,最终造成XSS漏洞。这个过程就像一次反射,故称为反射型XSS。

非持久型XSS漏洞实际上大多数攻击数据是包含在URL中的,类似这样的:
http://www.xxxxx.com/test.asp?hi=[code]。需要用户的浏览器访问到这个URL恶意代码才执行,攻击者一般会把URL发给用户让用户通过浏览器去访问。不过URL里面带有稀奇古怪的代码确实有点奇怪,为了掩人耳目,攻击者可以发一个看起来没问题的URL,再通过那个页面跳转到恶意的URL,甚至也可以让一个域名转向到恶意URL,把那个域名发给用户。
原型代码:

<?php
echo 'your input:' - $_GET[ 'input ' ];
?>

客户端输入的 input值未经任何过滤便直接输出,所以攻击者可以提交:http:/ /example.com/xss.php?input=<script>alert ( /xss/)</script>来进行攻击。

存储型

存储型XSS又被称为持久性XSS,存储型XSS是最危险的一种跨站脚本。允许用户存储数据的Web应用程序都可能会出现存储型XSS漏洞,当攻击者提交一段XSS代码后,被服务器端接收并存储,当攻击者再次访问某个页面时,这段XSS代码被程序读出来响应给浏览器,造成XSS跨站攻击,比如我在某个论坛发帖的时候,论坛没有对传入的HTML作处理,那么我就可以发一个帖子内容包含<script>[code]</script>的帖子,然后就守株待兔地等着来看帖子的人执行恶意脚本了。持久型XSS漏洞是把恶意脚本存储到了数据库,访问页面的时候完全没有预兆,这就是存储型XSS。

存储型XSS与反射型XSS、DOM型XSS相比,具有更高的隐蔽性,危害性也更大。它们之间最大的区别在于反射型XSS与DOM型XSS执行都必须依靠用户手动去触发,而存储型XSS却不需要用户手动去触发

DOM型

DOM的全称为Document Object Model,即文档对象模型,DOM通常用于代表HTML、XHTML和XML中的对象。使用DOM可以允许程序和脚本动态地访问和更新文档的内容、结构和样式。
通过JavaScript可以重构整个HTML页面,而要重构页面或者页面中的某个对象,JavaScript就需要知道HTML文档中所有元素的“位置”。而DOM为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。根据DOM规定,HTML文档中的每个成分都是一个节点。基于DOM型的XSS是不需要与服务器端交互的,它只发生在客户端处理数据阶段。

输出在HTML中

原型如下:

<input name="user" value="ii your input }}”/>

XSS 攻击Payload输出在HTML属性中时,攻击者需要在闭合相应的HTML属性后注人新属性,或者在闭合标签后直接注入新标签,如输入:

" onclick="alert ( /xxs/)就闭合了value属性,并且加入新的属性onclick。

或者输入:

"><script>alert(/xss/ )</script>这样就直接闭合了input标签而且注入了新的标签。

输出在CSS代码中

原型如下:

<style type="text/css">
body {
    
    
    color:  your input ;
}
</style>

XSS攻击Payload输出在 CSS代码中时,攻击者需要闭合相应的CSS代码,如输入:

#000 ; background-image: ur1( 'javascript:alert ( /xss/) ')闭合前面的color属性,注入 background-image属性

输出在JavaScript中

原型如下:

<script>
var name='{
    
    { your input }}';
</ script>

XSS攻击Payload输出在Javascript代码中时,攻击者需要闭合相应的Javascript代码,如输入:

'+alert(/xss/)+'闭合前面的单引号,注入攻击代码,就变成了

<script>
var name=' '+alert ( / xss/)+'';
</ script>

XSS的特性

XSS的核心:获取别人的cookie来登陆别人的账号。
要展开XSS攻击,需要在目标网站上触发指定的JS语句。攻击者主要通过以下三种触发方式展开攻击:
1、标签法(又叫XML法) ,比如:

<script>alert(1)</script>

2、伪协议法,比如:

<a href=Javascript:alert(1)>123</a>
3、事件法,比如:

</img src=# onerror=alert(1) />

常用的on事件有:

onerror
onload
onfocus
oninput

防护和绕过

1.特定标签过滤

部分开发者认为过滤掉危险标签(如script、iframe等)就会导致无法执行脚本,但其实任何一种标签,无论是否合法,都可以构造出XSS代码,比如如下代码:

<not_real_tag onclick="alert(/xss/) ">click me</not_real_tag>如果输出点在HTML标签的属性中或在Javascript代码中,那么攻击者可以简单地闭合、拼接属性或Javascript 代码而不需要引入任何新标签就可以执行XSS代码。
同时,HTML5也带来了部分新标签,容易被开发者忽略,如video标签。总而言之很多标签都可以构造出攻击代码。

2.事件过滤

很多时候,开发者会过滤掉许多HTML标签的事件属性,这时需要对所有可利用的事件属性进行遍历,测试一下开发者是否有所遗漏。常用的事件属性如下,测试时可使用Burp或自行编写脚本进行Fuzz:

3.敏感关键字(字符)过滤

(1)字符串拼接混淆

关键字过滤大部分是针对敏感变量或函数而进行的,如cookie、eval等,这部分的过滤可通过字符串拼接、编码解码等方法进行绕过。
例如:windowp['alert'](/xss/)就可以变成windowp['al'+'ert'](/xss/)因为里面是个字符串的形式。

我们还可以利用base64编码,btoa函数可以将字符串编码为Base64字符串,atob函数可以将Base64字符串还原,比如:

window[ atob ( "Ywxl"+"cnQ=" )](/xss/)就相当于windowp['alert'](/xss/)

(2)编码解码

基于字符串的代码混淆不仅可以通过字符串拼接的方式来实现,还可以通过各种编码、解码来实现。XSS漏洞中常用的编码方式包括:

  • HTML进制编码:十进制(a)、十六进制(a)
  • CSS进制编码:兼容HTML 中的进制表现形式,十进制、十六进制
  • Javascript进制编码:八进制(\141)、十六进制(\x61 )、Unicode编码(\u61 ),ASCII (String.
  • fromCharCode(97))
  • URL编码:%61
  • JSFuck编码

这里值得一提的是JSFuck编码,它可以只使用“[O!+”6个字符来编写Javascript程序,在某些场景下具有奇效。

(3)location.*、window.name

既然开发者会对输入的敏感关键字进行过滤,那么可以将XSS代码放置于其他不被浏览器提交至服务端的部分,如 location.*、window.name等处,location.*的构造如下:

http://example.com/xss.php?input=<input onfocus=outerHTML=decodeURI(location.hash)>#<img src=x onerror=alert( /xss/)>

window.name的构造页面如下:

<iframe src="http://example . com/xss.php?input=83Cinput%20onfocus=location=windowname%3E"name="javascript:alert (/xss/) "></iframe>

利用location对象结合字符串编码可以绕过很多基于关键字的过滤。也有一部分关键字过滤是针对敏感符号的过滤,如括号、空格、小数点等。

(4)过滤“.”
在JavaScript中,可以使用with 关键字设置变量的作用域,利用此特性可以绕过对“.”的过滤,如:
with(document )alert ( cookie ) ;

(5)过滤“(”
在JavaScript中,可以通过绑定错误处理函数,使用throw关键字传递参数绕过对“()”的过滤,如:
window.onerror=alert; throw 1;

(6)过滤空格
在标签属性间可使用换行符0x09、0x10、0x12、0x13、OxOa等字符代替空格绕过过滤,如:

http://example.com/xss.php?input=<img%0asrc=x80aonerror=alert ( /xss/)>

在标签名称和第一个属性间也可以使用“/”代替空格,如:

<input/onfocus=alert(/xss/)>

( 7 )svg 标签
svg内部的标签和语句遵循的规则是直接继承自xml而不是html,区别在于svg内部的script标签中可以允许存在一部分进制或编码后的字符(比如实体编码)
http://example.com/xss . php?input=1"><svg><script>alert%26823x28;1号26%23x29</script></svg>

4.字符集编码导致的绕过

pikachu靶场练习

反射型xss(get)

界面展示:

image-20220828231344743

这里我们看到界面是一个输入框,并且输入的内容会在url上显示,说明是GET请求的传参。我们可以直接在url上攻击。我们尝试简单的让它弹出框框试试,输入<script>alert("123")</script>

但是这我们注意到,这个输入框有长度限制,不能直接输入上面那一大串,于是我们对长度进行绕过。

image-20220828231650630

这里提供以下几种方式:

  1. 直接在url中传参数,?message=<script>alert("123")</script>&submit=submit&submit=submit
  2. F12调出控制台,使用左上角的选择器,找到框框那里,可以看到maxlength=20的代码,双击选中把这个20改了再试以下就行。这里的修改只能生效一回合,刷新后就需要重新修改了。
  3. 使用burpsuite抓包,再进行传参。在我们使用这种方式传参后,可以在返回包里直接找到我们传入的语句,原模原样,由此也可以判断出有xss漏洞。
  4. image-20220828232949292

反射型xss(post)

这一关先要用admin账号登录再进行操作。也就是给咱体验体验

image-20220828233514903

如果要获得cookie,那么就输入payload:<script>alert(document.cookie)</script>

这样就得到了admin的cookie

存储型xss

本关页面有一个留言板,输payload:<script>alert(document.cookie)</script>就能弹出cookie。并且可以看到留言表中有一条数据了(虽然该数据不显示,但是有删除按钮)。

image-20220829115500292

并且我们也能在抓包的返回包中找到我们输入的代码。

并且存储型xss还会导致一个额外的结果,就是当我们使用其他浏览器中来到本关页面,也出现了同样的弹框。说明存储型XSS能危害所有访问受影响页面的用户。

DOM型xss

这一关就考验到了简单的绕过技巧,这题你只要F12 打开查看源码就能发现它把源码都给你了
image-20220829133754749

也告诉你绕过方法了,事实上一般的ctf题如何绕过要靠你自己去试。

DOM型xss-x

这俩题差不多,只不过设定了要想触发你输入的东西,必须点击下面的超链接。也就是说代码藏在了a标签里面

image-20220829134123832

xss盲打

这题要告诉我们的是,当我们在前端没有发现自己注入的代码执行时,有可能在后台执行了。本关我们登录后台,在前端注入payload再刷新后台就会发现,我们的后端页面弹出了框框。查看代码发现我们输入的内容确确实实传输到了后台页面里面。

image-20220829134842386

xss之过滤

这题考验简单的过滤,因为我们发现注入<script>alert("123")</script>后直接被过滤掉了,那我们换做事件触发方式使用<img src="#" οnerrοr=alert(document.cookie)>就可以正常注入了

xss之htmlspecialchars

这一关会发现注入的内容完全输出到了页面里面,并且变成一个超链接,因此考虑到这里有一个a标签。因此本关我们只需要闭合a标签的属性再使用onclick触发就行了。

image-20220829140424587

但是这关尝试了闭合a标签发现不行,原因是过滤了尖括号,但是由于没过滤掉单引号所以我们可以闭合标签属性。

xss之href输出

这一题发现左右尖括号和单引号都被html编码了,因此我们选择伪协议触发法,使用payload:

javascript:alert(document.cookie)

image-20220829140944471

xss之js输出

这题将我们输入的内容放到了<script>标签内了,并且没有被编码。于是我们闭合该字段,再直接写入script代码就行了。输入payload:';alert(123);//

image-20220829141212965

猜你喜欢

转载自blog.csdn.net/xuanyulevel6/article/details/126584026