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

摘要:
WordPress保存评论的字段类型正是WordPress在TEXT3漏洞中使用的类型。在wp411wp includes.hp419中,$allowedtags=array('a'=&gt,array('href'=&gt.array('title'=>'blockquote'=<'code'=>'del'=&>array('datetime'=&t,

转自:Baidu Security Lab Xteam 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编码,不使用的话,会将不识 别的四字节的字符连同后面的字符串一同舍弃。示例如下,使用特殊字符wp12
    
UPDATE `wp_comments` SET `comment_content` = 'stefanie特殊字符555555555555555 ' WHERE `wp_comments`.`comment_ID` =12;
执行结果wp10,可以看出,后面的55555555已经被截断,并未插入数据库。
UTF-8编码在对于不同的字符区域,编码所占用的字节数各不相同,当然我们重点关注占用4字节的范围
wp11
通过刚刚对于官网的说明的理解,mysql utf-8编码对于占用四个字节的字符无法识别,那么这一部分占用字节编码的区域,插入数据库时可以与符号wp12产生同样的效果,在该范围中随机进行测试发现,均产生截断效果,如wp13wp14wp15等,如需完整验证猜想,可对针对图中范围进行FUZZ。
当mysql数据库的编码为utf-8mb4或者latin1时,是不存在该问题的,因为这两种字符集对该类字符可以进行正常识别,不会产生截 断效果,另外,当mysql开启strict mode时候,会更加严格地处理,确保在数据有效存储之前进行阻止,也就不会产生该问题。
2 超过长度截断
mysql type=TEXT时,TEXT的最大长度为64kb,当发生数据库的插入操作时,则会将大于64KB的部分抛弃,只插入前64KB,此时也造成了一种截断。
而wordpress保存评论的字段的type正是TEXT
wp16
3 漏洞利用
wordpress中,对于匿名评论内容中的标签以及属性,会按照白名单进行过滤,如下所示。
wp411wp-includeskses.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下面提交评论后可以发现,成功弹窗,代码如下图
wp17
可以看出,在poc中,onmouseover是在双引号内作为title属性的值出现的,而当特殊字符起到了截断的作用之后,该条评论的内容在数据库中保存如下
wp18
其中左边的双引号在输出的时候,会被替换,而另外一个包裹onmouseover的双引号被截断未存入数据库,此时的onmouseover成功变成了一个未在白名单允许范围之内的事件,并且被成功解析。
而用超过固定长度来构造截断与此同理。
<abbr title=”123 onmouseover=alert(1) 此处增加无用字符至64KB “>

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

wp19wp110

漏洞利用

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

style=position:absolute;left:0;top:0;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 &amp;lt;4.1.2 &amp;amp; &amp;lt;=4.2 存储型xss》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux下tomcat的启动、关闭JS实战(京东秒杀)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Oracle数据库脚本中的set define off

2018年8月6日15:11:34 Oracle数据库脚本中的set define off 前言 最近在公司写需求,接触到脚本,第一句set define off;就不知道什么意思了,查询后记录之。 名称 SET DEFINE 概要 SET DEFINE命令改变标记替代变量的前缀字符。你可以使用SET DEFINE关闭替代变量。 语法 SET DEF[IN...

回文自动机做题小结

模板 求以每个位置结尾的回文串的数量,加密输入 就是回文自动机节点的(len)数组,对应的是最长回文后缀 双倍回文 求形如(AA^rAA^r) 方法一:建立(fail)树,然后对每个(len)是偶数的点,在子树内找有没有长度为(2*len)的点,通过打标记做到(O(n)) 方法二:求一个与(fail)数组对应的(tran)数组,含义为长度不超过(frac{...

oracle数据库密码修改和解锁

oracle数据库密码修改步骤 1. 以root用户登录其中一台数据库服务器2. 执行如下命令扫描该服务器上存在多少个oracle或oracleN用户cat /etc/passwd 3. 执行命令su - oracle1切换到oracle1用户4. 执行命令./sqlplus / as sysdba连接数据库5. 执行命令select * from db...

liquibase之快速入门

第一步:   创建一个Changelog File:  这个database  Changelog file列举了数据库中所有的改变情况,该文件是以xml为基础的,下面是一个空的xml文件: 1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <databaseChangeLog 4 xm...

pb中数据窗口函数小结(转)

一、连接数据库 连接数据库也就是指定事务对象。PowerBuilder提供了两个函数:SetTrans()和SetTransObject()。语法格式:dw_control.SetTrans(TransactionObject)dw_control.SetTransObject(TransactionObject)其中,dw_control是所使用的数据窗...

【SequoiaDB】5 巨杉数据库SequoiaDB基本操作

Sequoia DB巨杉数据库作为分布式数据库,由数据库存储引擎与数据库实例两大模块组成。前面介绍了Sequoia DB巨杉数据库集群的部署以及MySQL实例的安装,下面将继续就以下主题进行介绍。 1 安装目录详解 1.1 SequoiaDB安装目录 SequoiaDB巨杉数据库的默认安装目录为/opt/sequoiadb/,安装完成后可以看到目录如下:...