转自:Baidu Security LabXteam http://xteam.baidu.com/?p=177

漏洞概述

本次漏洞出现两个使用不同方式截断来实现的存储型xss,一种为特殊字符截断,一种为数据库字段长度截断,该漏洞导致攻击者可获取用户 cookie以及模拟浏览器正常操作,并且当管理员访问到注入的payload时,结合wordpress后台功能甚至可以getshell。

漏洞分析

1.字符截断
通过官网介绍“The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. ”,mysql在使用utf8的时候,一个字符的大小的上限为3字节,而当出现四个字节的字符时,是需要用使用utf8mb4编码,不使用的话,会将不识 别的四字节的字符连同后面的字符串一同舍弃。示例如下,使用特殊字符
UPDATE `wp_comments` SET `comment_content` = 'stefanie特殊字符555555555555555 ' WHERE `wp_comments`.`comment_ID` =12;
执行结果,可以看出,后面的55555555已经被截断,并未插入数据库。
UTF-8编码在对于不同的字符区域,编码所占用的字节数各不相同,当然我们重点关注占用4字节的范围
通过刚刚对于官网的说明的理解,mysql utf-8编码对于占用四个字节的字符无法识别,那么这一部分占用字节编码的区域,插入数据库时可以与符号产生同样的效果,在该范围中随机进行测试发现,均产生截断效果,如等,如需完整验证猜想,可对针对图中范围进行FUZZ。
当mysql数据库的编码为utf-8mb4或者latin1时,是不存在该问题的,因为这两种字符集对该类字符可以进行正常识别,不会产生截 断效果,另外,当mysql开启strict mode时候,会更加严格地处理,确保在数据有效存储之前进行阻止,也就不会产生该问题。
2 超过长度截断
mysql type=TEXT时,TEXT的最大长度为64kb,当发生数据库的插入操作时,则会将大于64KB的部分抛弃,只插入前64KB,此时也造成了一种截断。
而wordpress保存评论的字段的type正是TEXT
3 漏洞利用
wordpress中,对于匿名评论内容中的标签以及属性,会按照白名单进行过滤,如下所示。
\wp411\wp-includes\kses.php 419行
$allowedtags = array(
'a' => array(
'href' => true,
'title' => true,
),
'abbr' => array(
'title' => true,
),
'acronym' => array(
'title' => true,
),
'b' => array(),
'blockquote' => array(
'cite' => true,
),
'cite' => array(),
'code' => array(),
'del' => array(
'datetime' => true,
),
'em' => array(),
'i' => array(),
'q' => array(
'cite' => true,
),
'strike' => array(),
'strong' => array(),
);
wordpress只会允许白名单中的标签出现,而在每个以标签名作为数组名的数组中,保存的是该标签下所允许出现的属性。
正常情况是不允许类似于onmouseover之类的属性出现的,我们使用poc进行测试
 <abbr title=”123 onmouseover=alert(1) 特殊字符”>
在IE下面提交评论后可以发现,成功弹窗,代码如下图
可以看出,在poc中,onmouseover是在双引号内作为title属性的值出现的,而当特殊字符起到了截断的作用之后,该条评论的内容在数据库中保存如下
其中左边的双引号在输出的时候,会被替换,而另外一个包裹onmouseover的双引号被截断未存入数据库,此时的onmouseover成功变成了一个未在白名单允许范围之内的事件,并且被成功解析。
而用超过固定长度来构造截断与此同理。
<abbr title=”123 onmouseover=alert(1) 此处增加无用字符至64KB “>

此时则成功将右边的双引号和尖括号截断,导致其并未进入数据库,如下图所示

漏洞利用

 
Klikki Oy团队给出了兼容多种浏览器的POC,chrome,IE,firefox测试成功
sssss<a title=’x onmouseover=alert(unescape(/hello%20world/.source))

style=position:absolute;left:0;top:0;width:5000px;height:5000px 此处用特殊字符或者长度截断均可’></a>

结合此poc,引用外部js,利用wordpress管理员在后台编辑模板的功能,可进行自动化的getshell,之前爆出wordpress xss时已有人发出,此处不再赘述

漏洞影响范围

特殊字符截断影响版本:WordPress < 4.1.2 (需要mysql使用utf8字符集且strict mode关闭)
超过长度截断影响版本:WordPress < =4.2
此次漏洞利用的为mysql的特性,其他使用mysql的cms可能也会出现类似问题。

拦截建议

waf对两种xss拦截,建议如下:
1 字符截断:针对评论请求中带有图中范围内的字符,予以拦截
2 长度截断: 评论请求超过64KB予以拦截
具体情况还请waf同学斟酌

修复建议

针对超长截断,官方暂未给出补丁,所以建议临时关闭评论功能,防范此次的xss
 
-------------我的总结--------------
1. mysql字符编码最好采用utf-8mb4(或latin1)
2. mysql一定采用strict mode(mysql5.7好像已经是默认严格模式了)
3. 长度超过,程序就应该进行处理,所以还是程序写的不严谨
4. XSS 白名单
5. 该攻击的原理是,利用mysql在处理特殊字符和超长字符时,其会进行截断,所以导致了最后的 " 被截断了,导致了引号"没有被关闭,所以导致了浏览器将标签的属性当成了js代码来执行。
6. <abbr title=”123 onmouseover=alert(1) 在输出时,没有进行html编码,将<编码成&lt; ,onmouseover,alert等在输入时没有进行过滤。
7. 存储型XSS,需要鼠标移动到上面才会触发。

利用mysql对特殊字符和超长字符会进行截断的特性 进行存储型XSS攻击——WordPress <4.1.2 & <=4.2 存储型xss的更多相关文章

  1. 利用Mysql提供的字符串方法查找字符串中某字符出现的次数

    有这么一个需求,查出分类中没有子分类的一级分类,脑海中首次出现的解决思路和这样的 先使用PHP查出所有的一级分类 递归查询一级分类是否有子分类 将没有子分类的一级分类汇总 但觉的这样处理太麻烦了,然后 ...

  2. 在SQL注入中利用MySQL隐形的类型转换绕过WAF检测

    web应用一般采用基于表单的身份验证方式(页面雏形如下图所示),处理逻辑就是将表单中提交的用户名和密码传递到后台数据库去查询,并根据查询结果判断是否通过身份验证.对于LAMP架构的web应用而言,处理 ...

  3. mysql判断是否包含某个字符的方法和修改表中指定字段

    用locate 是最快的,like 最慢.position一般实战例子:select * from historydatawhere locate('0',opennum) and locate('1 ...

  4. mysql判断是否包含某个字符的方法

    mysql判断是否包含某个字符的方法用locate 是最快的,like 最慢.position一般实战例子:select * from historydatawhere locate('0',open ...

  5. 创建ASP.NET Core MVC应用程序(2)-利用MySQL Connector NET连接到MySQL

    创建ASP.NET Core MVC应用程序(2)-利用MySQL Connector NET连接到MySQL 用惯.NET的研发人员都习惯性地使用SQLServer作为数据库.然而.NET Core ...

  6. 关于 MySQL UTF8 编码下生僻字符插入失败/假死问题的分析

    原文:http://my.oschina.net/leejun2005/blog/343353 目录[-] 1.问题:mysql 遇到某些中文插入异常 2.原因:此 utf8 非彼 utf8 3.解决 ...

  7. 利用MySQL 的GROUP_CONCAT函数实现聚合乘法

    MySQL 聚合函数里面提供了加,平均数.最小,最大等,可是没有提供乘法,我们这里来利用MYSQL现有的GROUP_CONCAT函数实现聚合乘法. 先创建一张演示样例表: CREATE TABLE ` ...

  8. shell利用mysql表项的icmp检测

    作者:邓聪聪 利用mysql的表项记录IP地址和对应状态 +----+-----------------+--------+--------+ | id | ip_host | desc | stat ...

  9. 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)

    利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...

随机推荐

  1. [ASP.NET] 使用 ASP.NET SignalR 添加实时 Web

    ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...

  2. WebApi中跨域解决办法

    在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案.由于时间有限,本文不会深入. 笔者遇到的问题是Js调用WebAPI中的数据进行跨域的场景.涉及若干跨域方案: 方案1:j ...

  3. Unity多语言本地化改进版

    简介 之前捣鼓过一个通过csv配置游戏多语言支持的小工具,但是发现使用过程中,通过notepad++去进行转码很不方便,并且直接将配置的csv不加密的放在游戏中心里感觉不是很踏实 于是乎~~ 新的方案 ...

  4. 重新想象 Windows 8 Store Apps (65) - 后台任务: 音乐的后台播放和控制

    [源码下载] 重新想象 Windows 8 Store Apps (65) - 后台任务: 音乐的后台播放和控制 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后台 ...

  5. csharp:引入app.manifest,程序在win7下以管理员权限运行配置方法

    https://msdn.microsoft.com/en-us/library/windows/desktop/hh848036(v=vs.85).aspx https://msdn.microso ...

  6. 小白学Linux(四)--系统常用命令

    这里记录一下基础的系统常用命令,都是日常可能用到的,需要记住的一些命令.主要分为5个模块:关于时间,输出/查看,关机/重启,压缩归档和查找. 时间:      date :查看设置当前系统时间,dat ...

  7. yii2.0配置以pathinfo的形式访问

    yii2.0默认的访问形式为:dxr.com/index.php?r=index/list,一般我们都会配置成pathinfo的形式来访问:dxr.com/index/list,这样更符合用户习惯. ...

  8. bootstrap 学习片段

    1. 只要单击按钮添加了data-toggle="dropdown"属性, 在单击按钮的时候,默认隐藏的下拉列表就会显示出来 <div class="row&quo ...

  9. C语言范例学习02

    第二章 指针 算是重点吧,这也是C语言的特色啊,直接访问物理存储. 重点: 指针就是一个存放它指向变量地址的变量,好绕口.   区分*在定义是与引用是的作用.   区分*.&的不同.   指针 ...

  10. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...