问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
CVE-2022-21663 wordpress <5.8.3 对象注入漏洞
漏洞分析
CVE-2022-21663 wordpress <5.8.3 对象注入漏洞
本文仅用于技术讨论与研究,文中的实现方法切勿应用在任何违法场景。如因涉嫌违法造成的一切不良影响,本文作者概不负责。 0x01漏洞简介 ======== 看了 `wordpress`注入(CVE-2022-21661)的洞之后,发现还存在另外一个对象注入漏洞,具有管理员权限的用户通过更改一些选项,将有机会 `getshell`。 0x02影响范围 ======== `getshell`的条件: - `wordpress < 5.8.3` - 启用多站点模式 - 存在一条可用的反序列化链(在本文中不会讲这个) 这是 `github`上的漏洞修复记录 <https://github.com/WordPress/WordPress/commit/66bb979049fa1a515d031e53ab100d507ed7bc8b>  因此这里的环境选择前一条提交 ```php git clone https://github.com/WordPress/WordPress git checkout 7d20ea9 ``` 0x03漏洞分析 ======== 这里是以我复现这个漏洞时候的角度来分析的,因此会有一些弯路 漏洞入口点 ----- 首先来到 `wp-admin/upgrade.php`,这是管理员可以直接访问到的文件,也是我认为的此漏洞的入口点。  跟进 `wp_upgrade`函数,来到 `wp-admin/includes/upgrade.php`  首先看几个全局变量,`$wp_db_version`在 `wp-includes/version.php`中定义,根据其定义处的注释来看,这是本安装程序的数据库版本,在下一行中从数据库中取出了 `db_version`赋值给 `$wp_current_db_version`,看这情况,大概是一个是固定的数据库版本,另一个是可变的,`upgrade.php`会时不时地比较,当发生改变时,会进行一些操作 接下来看到我下的断点处,进入 `upgrade_all()`函数  这里就是在将两个版本进行比较,一致时不发生任何变化,不一致时运行后面的代码,接着看下面  根据从数据库中取出的 `db_version`也就是此处的 `$wp_current_db_version`的大小,会进行不同的处理,我们来关注断点处的 `upgrade_280`函数  看到 1611 行的 `is_multisite()`,跟进  这是一个判断是否开启了多站点的函数,这也是本漏洞的一个开启条件,必须要开启多站点才可以。开多站点需要改配置文件,我这里图省事儿,直接改了判断条件 `!is_multisite()`,强行让他绕过了 继续看上面,进入循环,每次从 `wp_options`表中取 20 条数据,将每一条数据都进行反序列化,漏洞的点就在此处了,因为 `wp_options`中的数据大部分都是可控的,我们可以通过管理员修改其值,最后进入反序列化。 还有两个问题,第一,如何控制 `db_version`的值,让他进入我们想要进入的函数;第二,如何更改 `wp_options`中的值。 数据写入 ---- 其实这两个是同一个问题,一并解决,`wordpress`后台没有直接访问所有 `options`的按钮,但我们可以访问 `wp-admin/options.php`  这里可以更改 `db_options`中大部分的值,包括 `db_version`,我们将其修改为 10300,就满足了进入漏洞函数的要求,接下来我们尝试写入反序列化字符串 我们先随便选择一个选项写入反序列化字符串,这里我首先选择的是 `blogdescription`,也就是博客描述,这个也可以在常规选项中更改(更建议,因为需要处理的值会更少,调试没那么费力),`post`的数据会逐个进入 `wp-includes/option.php`中的 `update_option`,来看几个比较重要的函数(PS:太长截图截不完)  这里首先说明一下 `$option`是每个选项的键,`$value`是每个选项的值 首先看到 `sanitize_option`  这个函数会根据不同的键来选择不同的处理方式,比如一些一定会用整数的,就会`intval`处理,所以选择的选项也是有讲究的,我之前选择的`blogdescription`,就因为这个函数而无法使用,他会将一些特殊字符编码,导致无法正常反序列化,这个可以慢慢尝试,尽量选择这个函数不会进行太多处理的选项 最终我选择的是 `wp-admin/options-writing.php`中的 “密码”(选择 `options.php`中的`mailserver_pass`也一样,是同一个),一般来说,密码对字符都不会有太多的限制,至少这里是的 回到之前的 `update_option`的代码,稍微注意一下这里的比较  如果我们输入的选择没有发生改变,就不会继续后面的代码,继续往下走,进入 `wp-includes/functions.php`中的`maybe_serialize`函数  如果是数组或者对象,那么会直接序列化后返回。然后进入 `is_serialized`函数  这里会取字符串的第一个字符进行比较,这里几乎囊括了反序列化字符串的所有类型,遇到是这一些的,返回后会再次反序列化,也就是进行了二次反序列化,这样几乎是防止了可能的反序列化。 这里遗漏了一个 `C`类型,官方文档对他的描述是 `custom object`,自定义对象,这个以前几乎没有用到过,因此这次进行了一次测试 代码:  结果  同一个类,将类型从 `O`修改为了 `C`,反序列化运行后,虽然报错,但最后仍然会触发 `__destruct`方法,因此我们可以将一个正常的反序列化字符串,将第一个字符 `O`修改为 `C`,这样就可以逃过这里的二次反序列化,从而将我们的反序列化字符串写入数据库,等待触发即可。 0x04漏洞复现 ======== 本菜鸡找不到 `wordpress`的链子,只能随意触发一个 `__destruct`意思意思 这里使用 `wp-includes/Requests/Transport/cURL.php`中的 `Requests_Transport_cURL`类 ```php C:23:"Requests_Transport_cURL":0:{} ```  查看数据库,并没有被二次序列化  来到`wp-admin/options.php`,将 `db_version`修改为 10300  这里一个意外的发现,修改数据库的时候就会触发漏洞入口  成功取出数据库中的反序列化串,并且执行反序列化  触发 `__destruct`方法  0x05总结 ====== 坑点不少,需要多琢磨,不说了,还是太菜了,都没法搞条链子。 0x06参考链接 ======== - <https://blog.sonarsource.com/wordpress-object-injection-vulnerability> 目前在学代码审计,对此感兴趣的师傅可以加好友一起交流学习
发表于 2022-03-15 09:24:52
阅读 ( 7317 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
shenwu
10 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!