0x00 简介
WordPress
是一个用PHP
编写的免费开源内容管理系统,
由于clean_query
函数的校验不当,导致了可能通过插件或主题以某种方式从而触发SQL
注入的情况。
这类似于tp爆出的那一堆注入,并不是直接就可以用,而是底层逻辑存在bug,要想触发漏洞还得上层的代码进行调用,调用方式如下
1 | new WP_Query($_POST['query_vars']) |
影响版本
3.7.37 - 5.8.2
其他
参数存在全局转义
0x01 漏洞分析
存在全局转义,有的地方反转义的,但是绝大部分没有,注入只能从不需要单引号的地方寻找,这里先贴一下此漏洞的调用堆栈
1 | WP_Query::__construct |
当传入的参数不为空时
调用query方法
对成员变量进行赋值,并调用get_posts方法
这个方法其实基本都是在组装sql语句
存在跟多的子结构,有机会可以看看其他地方是否还存在问题
这次只看之前发现的问题
这里的is_singular默认时false,默认就会进入此分支
进一步调用get_sql_clauses
跟进
继续
在clean_query中需要taxonomy参数为空
然后进入transform_query中
传入的值只要是term_taxonomy_id
,就会直接return
传入的注入值就会被拼接
这里会对字段进行判断,id类的就不会加单引号,其他的会加单引号
组装好sql语句之后
进入get_col方法
必须要说明的是箭头标注的方法里面会对数据库的字符集进行判断
我传入gbk的参数,无法将check_current_query设置为false
然后进入query
这里就有一点,上面无法设置false,这里面就会return false
最后会进入_do_query方法进行查询
0x02 漏洞复现
在admin-ajax.php中添加如下代码
构造payload
1 | action=aa&query_vars[tax_query][1][include_children]=1&query_vars[tax_query][1][terms][1]=1) or updatexml(0x7e,concat(1,user()),0x7e)#&query_vars[tax_query][1][field]=term_taxonomy_id |
0x03 修复
官方修复如下,只有当字段名为slug和name的时候,才会保留原数据
wp_parse_id_list
对参数进行的强转
0x04 end
至于上面提到的slug和name,可以跟一下
但是由于参数被固定,导致我们对term类的成员变量的可控力度很小
只有一个name参数可控,但是在拼接的时候被单引号包裹
由于存在全局转义,所以无法注入