0x00 背景

XSS漏洞也叫跨站脚本攻击,是Web漏洞中最常见的漏洞,原理与SQL注入相似,通过来自外部的输入直接在浏览器端触发。XSS漏洞通常被入侵者用来窃取Cookie等,本文以代码审计的形式研究XSS攻击原理、挖掘形式、防御方案及缺陷。

0x01 XSS攻击原理

我们看下面一段代码:

 <?php

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

通过上面的代码我们可以轻松看出,用户输入的变量name没有经过任何处理直接输出到了页面上,如果我们在name变量的输入框中输入

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

第六行代码就变成了

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

这样我们的浏览器上就会弹出一个内容为/xss/的窗口。这就是XSS的基本原理。

0x02 XSS漏洞的挖掘形式

根据上文的原理介绍,在挖掘XSS漏洞的时候,我们需要找的是可以传输到输出函数的参数,我们常用的输出函数有print、printf、print_r、echo、sprintf、die、var_dump、var_export,所以我们只需要搜索这些函数,追踪其变量即可。

XSS的挖掘也可以重点关注相关的业务,例如论坛、博客、图片引用、资料修改等,Web程序在保证业务正常运行的前提下很难面面俱到地进行防御,在挖掘的时候我们也可以通读这些业务的代码寻找XSS漏洞。

反射型XSS

反射型XSS如同0x01中所呈现的代码,用户发出一个带有XSS攻击的请求,服务器端接受请求后进行处理并把带有XSS的代码发送给了浏览器,浏览器解析带有XSS的代码,这就造成了XSS攻击,整个过程如同一次反射,因此命名反射型XSS。

反射型XSS的挖掘利用扫描器进行黑盒测试基本可以直接发现,原理是向Web服务器提交尖括号等XSS常用符号,检查返回的HTML页面里是否还有特殊字符即可。在代码审计中我们需要找输出函数中的参数,然后回溯参数观察过滤情况。

存储型XSS

存储型XSS顾名思义,是将带有XSS攻击的代码存储起来,每次Web程序读取到这段代码的时候就会触发一次攻击。因此存储型XSS的利用难度更低、危害更大(很多SRC不收录反射型XSS)。一个最常见的带有存储型XSS漏洞的代码如下:

 <?php

 if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] ); // Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : "")); // Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' ); //mysql_close();
}

根据这段代码我们可以看出,用户向页面提交变量mtxMessage和txtName,然后Web程序未经任何过滤就将这两个变量存储到数据库,每次用户访问这个页面的时候都会从数据库提取代码造成攻击。

与挖掘反射型XSS漏洞一样,我们也是要寻找带有参数并且未经过滤的输出函数,并对这些参数进行全局追踪。

0x03 防御方案及缺陷

XSS漏洞的防御比较复杂,在不同的业务情境下需要考虑不同的情况,以下介绍几种常见的防御方式。

黑白名单

与SQL注入防御一样,黑名单是最低效的防御方案,一个典型的黑名单案例如下

 <?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函数将变量name中的<script>标签置换为空。在这里我们有两种绕过方式

1.采用大小写绕过(<ScRiPt>)或者采用双写绕过(<scr<script>ipt>);

2.采用除<script>标签外的其他标签,例如<img>标签等实现XSS攻击。

而白名单就是一种相对可靠一些的过滤方式,我们可以采用正则进行事件匹配,如果匹配到规则内的事件直接进行拦截,而不采用替换为空的方式。

特殊字符转码为HTML实体

这种防御方案是目前最流行的XSS防御方案之一,这些特殊字符集包括:尖括号、单引号、双引号、反斜杠、&等。案例如下:

 <?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();
?>

在这个案例中,采用了htmlspecialchars函数,把预定义的字符&、”、 ’、<、>转换为 HTML 实体,防止浏览器将其作为HTML元素。虽然看起来这样处理XSS就能万事大吉,但在htmlspecial函数中有个大坑需要格外注意!该函数的用法如下:

htmlspecialchars(string,flags,character-set,double_encode)

我们注意第二个参数flags。这个参数对引号的编码规则如下:

#可用的引号类型:

ENT_COMPAT #- 默认。仅编码双引号。
ENT_QUOTES #- 编码双引号和单引号。
ENT_NOQUOTES #- 不编码任何引号。

注意!flags参数默认状态值编码双引号!这个默认参数在实际开发中非常容易被忽略,我们看下面这个案例:

<?php
$name = $_GET["name"];
$name = htmlspecialchars($name);
?> <input type='text' value='<?php echo $name?>'>

如果我们提交:/test.php?name=1' onmouseover='javascript:alter(1)

单引号无法被转码成HTML实体,依然会造成反射型XSS漏洞。

代码审计中的XSS的更多相关文章

  1. 代码审计中的XSS反射型漏洞

    XSS反射型漏洞 一 XSS漏洞总共分三总 XSS反射型漏洞,XSS保存型漏洞,基于DOM的XSS漏洞 这次主要分享XSS反射型漏洞 基本原理:就是通过给别人发送带有恶意脚本代码参数的URL,当URL ...

  2. PHP通用的XSS攻击过滤函数,Discuz系统中 防止XSS漏洞攻击,过滤HTML危险标签属性的PHP函数

    XSS攻击在最近很是流行,往往在某段代码里一不小心就会被人放上XSS攻击的代码,看到国外有人写上了函数,咱也偷偷懒,悄悄的贴上来... 原文如下: The goal of this function ...

  3. Laravel5中防止XSS跨站攻击的方法

    本文实例讲述了Laravel5中防止XSS跨站攻击的方法.分享给大家供大家参考,具体如下: Laravel 5本身没有这个能力来防止xss跨站攻击了,但是这它可以使用Purifier 扩展包集成 HT ...

  4. 代码审计中的SQL注入

    0x00 背景 SQL注入是一种常见Web漏洞,所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.本文以代码审计的形式研 ...

  5. 通过代码审计找出网站中的XSS漏洞实战(三)

    一.背景 笔者此前录制了一套XSS的视频教程,在漏洞案例一节中讲解手工挖掘.工具挖掘.代码审计三部分内容,准备将内容用文章的形式再次写一此,前两篇已经写完,内容有一些关联性,其中手工XSS挖掘篇地址为 ...

  6. PHP代码审计中你不知道的牛叉技术点

    一.前言 php代码审计如字面意思,对php源代码进行审查,理解代码的逻辑,发现其中的安全漏洞.如审计代码中是否存在sql注入,则检查代码中sql语句到数据库的传输 和调用过程. 入门php代码审计实 ...

  7. Python代码审计中一些需要重点关注的项

    SQL注入: 如果是常规没有进行预编译,或者直接使用原生的进行拼凑,那么在view的时候就需要多去观察了 [PythonSQL预编译]https://www.cnblogs.com/sevck/p/6 ...

  8. 通过Web安全工具Burp suite找出网站中的XSS漏洞实战(二)

    一.背景 笔者6月份在慕课网录制视频教程XSS跨站漏洞 加强Web安全,里面需要讲到很多实战案例,在漏洞挖掘案例中分为了手工挖掘.工具挖掘.代码审计三部分内容,手工挖掘篇参考地址为快速找出网站中可能存 ...

  9. 代码审计中的CSRF

    0x00 背景 CSRF漏洞中文名为“跨站请求伪造”,英文别名为“one-click-attack”.从字面上我们就可以看出,这是一种劫持其他用户进行非法请求的攻击方式,主要用于越权操作,与XSS相比 ...

随机推荐

  1. 谈IO中的阻塞和非阻塞,同步和异步及三种IO模型

    什么是同步和异步? 烧水,我们都是通过热水壶来烧水的.在很久之前,科技还没有这么发达的时候,如果我们要烧水,需要把水壶放到火炉上,我们通过观察水壶内的水的沸腾程度来判断水有没有烧开.随着科技的发展,现 ...

  2. c#中的Task异步编程

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/index翻译 1. 引入 Task异步 ...

  3. .NET 软件下面win10自动启动配置

    1.设置所有用户登录都能启动,打开文件夹 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 2.给要启动的应用程序创建快捷方式, ...

  4. CSS3新特性—过渡、转换

    过渡 转换 2D转换 2D转换包括四个方面:位移,缩放,旋转,倾斜 位移[让元素移动位置] transform: translate(100px,100px); 备注: 1. 如果只设置一个值,那么代 ...

  5. 干货 | AI人脸识别之人脸搜索

    本文档将利用京东云AI SDK来实践人脸识别中的人脸搜索功能,主要涉及到分组创建/删除.分组列表获取.人脸创建/删除.人脸搜索,本次实操的最终效果是:创建一个人脸库,拿一张图片在人脸库中搜索出相似度最 ...

  6. Cisco连接失败问题处理

    连接公司的VPN时软件一直安装不上,试了几种方法,在此总结. 原文链接:http://www.itsystemadmin.com/error-27850-unable-to-manage-networ ...

  7. ubuntu下git的使用

    1.安装git sudo apt-get install git sudo apt-get install git-core 2.配置git lzb@lzb:~$ git config --globa ...

  8. Python登录TP-Link路由器换ip脚本

    有些时候我们需要更换IP(你懂得),网络下载的拨号软件大部分是需要电脑直接链接调制解调器(猫),对于局域网用户来说就比较麻烦了,下面我们用python来实现登录路由器自动切换ip的功能 # -*- c ...

  9. c语言中用简单方法对多维数组进行初始化

    例:int array[4][3] = {1,2,3,4,5,6,7,8,9,10,11,12}; 说明:a.由4*3可知,本二维数组包含12个元素,因此初始化时array[0][0] = 1 ,ar ...

  10. netty 百度网盘 密码

    netty基础 https://pan.baidu.com/s/1v_ME49LIef1Kwga8z2QbDw?spm=a1z09.2.0.0.680b2e8d5LI8S0   zb7u mina n ...