Web安全领域的探索之反射型xss漏洞原理

695 阅读1分钟

我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!

反射型XSS

DVWA Reflected XSS (Low)

  • 输入什么就返回什么,服务器没有对输入内容进行过滤
  • <script>alert(1)</script>           // 弹窗
    
  • <script>alert(document.cookie)</script>  // 弹窗显示**cookie**
    
  • cookie发送到我们的服务器上
  • 编写php脚本用于接收cookie
  • 构造语句发送cookie
  • 结合CSRF

源码

<?php// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
​
    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] );
​
    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}
​
// Generate Anti-CSRF token
generateSessionToken();
​
?> 

演示

1.我们先输入一个666来看看会发生什么情况

屏幕截图 2020-12-13 173535

2.我们发现它将我们输入的666显示到了页面上

屏幕截图 2020-12-13 173816

3.我们尝试将xss的payload放进去,让它弹个1
<script>alert(1)</script>

屏幕截图 2020-12-13 174333

4.成功弹窗,说明此处存在反射型xss漏洞

屏幕截图 2020-12-13 174409

5.至于为什么是反射型的,观察url

http://127.0.0.1/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert%281%29%3C%2Fscript%3E#

这里有个name参数,反射型的定义就是反映在响应里而不存储在服务端,这里name的值即我们构造的xss语句在链接中,不存储于服务端,所以为反射型

反射型最经典的例子就是包含xss语句的链接

存储型最经典的就是在留言板出插入xss语句

6.用开发者工具检查一下可以看到,我们构造的语句没有显示到页面上,而是被浏览器当做js语句解析了

DVWA Reflected XSS (Medium)

  • <script>替换为空字符,可以使用双写绕过即<scr<script>ipt>,或者大
  • 小写混淆绕过即<ScriPt>

源码

<?phpheader ("X-XSS-Protection: 0");
​
// 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>";
}
​
?>

演示

1.我们直接用<script>alert(1)</script>来看看发生什么

屏幕截图 2020-12-13 182940

2、发现alert(1)显示在页面上,说明没有解析成功,我们打开开发者工具审查一下元素

屏幕截图 2020-12-13 184118

3、我们可以看到,我们的script标签都被过滤了,我们可以试想一下,一对script被过滤,如果在里面再插入一个script标签会不会正好过滤一个还剩下一个呢,我们构造payload
<scr<script>ipt>alert(1)</script>

屏幕截图 2020-12-13 184603

4、成功弹窗,说明可行,我们可以再试想如果它没有过滤严格,我们是否可以通过大小写混淆方式过滤呢,我们构造payload
<scrIpT>alert(1)</sCriPt>

屏幕截图 2020-12-13 184829

5、再次成功弹窗,说明大小写混淆也可以绕过

DVWA Reflected XSS (High)

  • 使用preg_replace( )**函数利用正则表达式以不区分大小写的方式替换<script>
  • 使用html标签的事件绕过
  • onload事件,当元素被加载时调用
  • img标签的onerror,当图片加载错误时调用

源码

<?phpheader ("X-XSS-Protection: 0");
​
// 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>";
}
​
?> 

演示

1、我们还是先用script标签来试一下

屏幕截图 2020-12-13 185309

2、发现无法弹窗,我们审查一下元素,发现被都过滤了,只剩下一个尖括号了,我们再尝试一下大小写和双写看看能否绕过

屏幕截图 2020-12-13 185638

3、发现都是同样的结果,这样看来是对script标签进行过滤,我们尝试换个标签,我们构造payload
<img src=1 onerror="alert(1)" />    // 图片标签, src后面本来应该跟图片的地址,我们这里写1是一个不存在的地址,这样会发生错误就是执行后面的onerror属性的语句

屏幕截图 2020-12-13 185934

4、发现成功弹窗,说明此payload可行.

DVWA Reflected XSS (Impossible)

  • 使用htmlspecialchars函数把预定义的字符&<、>转换为HTML实体,防止浏览器将其作为HTML元素。

源码

<?php// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
​
    // Get input
    $name = htmlspecialchars( $_GET[ 'name' ] );
​
    // Feedback for end user
    echo "<pre>Hello ${name}</pre>";
}
​
// Generate Anti-CSRF token
generateSessionToken();
​
?> 

修复方案

  • Impossible级别
  • 使用htmlspecialchars函数把预定义的字符&<>转换为HTML实体,防止浏览器将其作为HTML元素。