simple social buttons插件漏洞
版本为v2.0.4到v2.0.22
下载好该插件,放于/wp-content/plugins
打开后台管理,发现插件已经存在
activate是启用的意思
该漏洞利用POST /wordpress/wordpress/wp-admin/admin-ajax.php请求,以任意普通用户身份即可执行管理员操作,危害较大。
应该是这个文件没有设置访问权限的原因(我乱说的)
wordpress源码分析
WordPress是一个开源的内容管理系统(CMS),允许用户构建动态网站和博客。
index.php:
define( 'WP_USE_THEMES', true );
require( dirname( __FILE__ ) . '/wp-blog-header.php' );//加载主要文件
wp-blog-header.php:
if ( ! isset( $wp_did_header ) ) {
$wp_did_header = true;//防止加载多次
// wp-load.php加载wordpress核心文件,如wp-settings.php,wp-config.php
require_once( dirname( __FILE__ ) . '/wp-load.php' );
// 调用wp类的main方法,以此调用更多方法,主要有parse_request,从这里开始解析URL并建立主循环
wp();
// ABSPATH指的是目录路径,WPINC指的是wp-includes(在wp-load.php里面有记录)
require_once( ABSPATH . WPINC . '/template-loader.php' );
wp-load.php:
//定义ABSPATH为目录路径
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}
//error_reporting规定报告哪几种错误,具体错误设置解释看表格
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );
//是否存在wp-config.php,存在即导入
//如果不存在可以去上级目录再查找,可以保证wordpress目录不被改动???
//如果都不存在定义WPINC为wp-includes,加载进其下文件load.php,设置安装变量,进行安装生成wp-config.php
if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
require_once( ABSPATH . 'wp-config.php' );
} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
require_once( dirname( ABSPATH ) . '/wp-config.php' );
} else {
define( 'WPINC', 'wp-includes' );
require_once( ABSPATH . WPINC . '/load.php' );
// Standardize $_SERVER variables across setups.
wp_fix_server_vars();
require_once( ABSPATH . WPINC . '/functions.php' );
$path = wp_guess_url() . '/wp-admin/setup-config.php';
。。。
错误代号 | 含义 |
---|---|
E_ERROR | 运行时的致命错误,脚本会被暂停 |
E_WARNING | 运行时的非致命错误,脚本不会被暂停 |
E_PARSE | 编译时错误 |
E_NOTICE | 运行时间的通知 |
E_CORE_ERROR | 启动时的致命错误 |
E_CORE_WARNING | 启动时的非致命错误 |
E_COMPILE_ ERROR | 编译时的致命错误 |
E_COMPILE_WARNING | 编译时的非致命错误 |
E_USER_ ERROR | 用户生成的致命错误 |
E_USER_WARNING | 用户生成的非致命错误 |
E_RECOVERABLE_ ERROR | 捕捉致命的错误 |
E_ALL | 所有错误 |
wordpress分析
总框架
- wp-admin:所有关于后台的代码
- wp-content:插件、主题、语言等,最容易出现漏洞
- languages
- plugins
- themes
- wp-includes:核心代码,包括前台代码
- index.php
- wp-login.php
解析wp中的nonce机制
出于防御csrf攻击的目的,wordpress引入了nonce安全机制,只有请求中_wpnonce和预期相等,请求才会被处理。Wordpress的nonce不是数字,而一是串由数字和字符组成的Hash值,不仅只能使用一次,还同时具有生命周期(lifetime),在生命周期内,针对每个用户,同样的参数会生成同样的nonce值,直到生命周期结束。
wp-admin里面的edit.php:
edit.php是管理员编辑文章的代码段
check_admin_referer()此函数检查管理员界面的nonce的有效性
跳到check_admin_referer函数所在的wp-includes/pluggable.php中:
跟踪$result中的wp_verify_nonce:
wp_verify_nonce( $_REQUEST[ $query_arg ], $action )
传入的参数是$_REQUEST[$query_arg]和$action
可知REQUEST[query_arg]为nonce值
hash_equals()用来比对nonce是否与预想一样
$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
- $i通过wp_hash函数可知,在一定时间内是个定值,总体随时间改变而改变
- $action行为属性,在代码段中是固定值,可预测
- $uid用户id,1自增,可预测
- $token最核心部分,无法预测
token即cookie中的第三部分,cookie中第一部分为用户名,第二部分为时间
用nonce一定程度上可以预防csrf和ssrf,以下是引用某篇文章的例子
wordpress的nonce机制分析完毕
解析wordpress中的过滤机制
wordpress用过prepare拼接sql语句并做部分转义
prepare函数中的主要转义函数escape_by_ref():
进入escape_by_ref():
进入_real_escape():
包含mysqli_real_escape_string、addslasshes等转义函数的封装
用到esc_sql函数安全性应该有保障
Wordpress Sqli漏洞
漏洞发生:后台传图片
基础知识
SELECT post_id FROM wp_postmeta WHERE meta_key = '%s' AND meta_value = '22 %1$%s hello'
结果为
SELECT post_id FROM wp_postmeta WHERE meta_key = '%s' AND meta_value = '22 %s hello'
1.因为代码会将所有%s转化为'%s',即meta_value = '22 %1$'%s' hello'
2.%1为空,'被吞掉,最终变成$__thumbnail_id,所以一个引号逃逸出来