【漏洞预警】WordPress全版本WPDB SQL注入预警及简要分析

admin 2022-06-24 06:30:53 AnQuanKeINFO 来源:ZONE.CI 全球网 0 阅读模式

http://p4.qhimg.com/t01723714f15f914546.png

漏洞作者:Anthony Ferrara

漏洞等级高危

影响版本:4.8.2 及之前版本

影响范围:WordPress版本4.8.2及之前版本受到该漏洞的影响: $wpdb->prepare()可以接收和执行不安全的查询,导致潜在的SQL注入(SQLi)。 WordPress核心并不容易直接受到这个漏洞的影响。

简要分析

WordPress 4.8.3中修复了一个重要的SQL注入漏洞,这个漏洞于2017年9月20日通过hackerone报给WordPress官方。

影响写法

以下$wpdb写法受该漏洞影响

不要将用户的输入传递给查询端,如以下写法1

$where = $wpdb->prepare(" WHERE foo = %s", $_GET['data']);
$query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", 1, 2);

理论上写法2也是不安全的

$where = "WHERE foo = '" . esc_sql($_GET['data']) . "'";
$query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", 1, 2);

应该单独的构建查询和参数,然后通过prepare方法执行。如以下写法3

$where = "WHERE foo = %s";
$args = [$_GET['data']];
$args[] = 1;
$args[] = 2;
$query = $wpdb->prepare("SELECT * FROM something $where LIMIT %d, %d", $args);

缺陷分析

为了了解本次报告中关于$wpdb的容易受攻击的代码,我们来跟进分析WordPress内部关于WPDB::prepare的部分。先来看源码(4.8.2版本之前)

public function prepare( $query, $args ) {
    if ( is_null( $query ) )
        return;
    // This is not meant to be foolproof -- but it will catch obviously incorrect usage.
    if ( strpos( $query, '%' ) === false ) {
        _doing_it_wrong( 'wpdb::prepare', sprintf( __( 'The query argument of %s must have a placeholder.' ), 'wpdb::prepare()' ), '3.9.0' );
    }
    $args = func_get_args();
    array_shift( $args );
    // If args were passed as an array (as in vsprintf), move them up
    if ( isset( $args[0] ) && is_array($args[0]) )
        $args = $args[0];
    $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it
    $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting
    $query = preg_replace( '|(?<!%)%f|' , '%F', $query ); // Force floats to be locale unaware
    $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); // quote the strings, avoiding escaped strings like %%s
    array_walk( $args, array( $this, 'escape_by_ref' ) );
    return @vsprintf( $query, $args );
}

这里需要注意三点

1.通过vsprintf格式化字符串,用$args替换占位符,并返回格式化后的一个字符串

2.利用str_replace函数正确处理$query中的占位符

3.如果传递的是参数,该参数是一个数组,那么它将用该数组的值替换参数。

总之,意思是调用$wpdb->prepare($sql, [1, 2])与调用$wpdb->prepare($sql, 1, 2)是相同的,这点很重要。

如以下的代码

$items = implode(", ", array_map([$wpdb, '_real_escape'], $_GET['items']));
$sql = "SELECT * FROM foo WHERE bar IN ($items) AND baz = %s";
$query = $wpdb->prepare($sql, $_GET['baz']);

这里涉及到vsprintf的一个小特性

vsprintf('%s, %d, %s', ["a", 1, "b"]); // "a, 1, b"
vsprintf('%s, %d, %1$s', ["a", 2, "b"]); // "a, 2, a"

注意,%n$s不会读取下一个参数,而是读取第n个位置的参数

我们可以基于这个验证上面的查询,假设我们发送以下请求信息给服务端

$_GET['items'] = ['%1$s'];
$_GET['baz'] = "test";

现在,查询将被改为SELECT * FROM foo WHERE bar IN ('test') AND baz = 'test';但这改变了查询的含义,为了更明显的说明sql注入,可以构造这样的请求数据

$_GET['items'] = ['%1$c) OR 1 = 1 /*'];
$_GET['baz'] = 39;

需要说明的是:sprintf还接受另一种类型的参数:%c它的作用就像chr()将十进制数字转换成一个字符。这里ASCII表39是'(单引号)的ASCII码。那么整个查询执行的sql语句是:

SELECT * FROM foo WHERE bar IN ('') OR 1 = 1 /*' AND baz = 'test';

事实证明,该缺陷也存在WordPress的核心文件/wp-includes/meta.php。

if ( $delete_all ) {
  $value_clause = '';
  if ( '' !== $meta_value && null !== $meta_value && false !== $meta_value ) {
    $value_clause = $wpdb->prepare( " AND meta_value = %s", $meta_value );
  }
  $object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s $value_clause", $meta_key ) );
}


修复方案

推荐升级官方最新版本WordPress 4.8.3。用户可以通过点击后台的仪表盘->更新。


参考

https://blog.ircmaxell.com/2017/10/disclosure-wordpress-wpdb-sql-injection-technical.HTML 

https://wordpress.org/news/2017/10/wordpress-4-8-3-security-release/ 

weinxin
特别声明
本站(ZONE.CI)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
记一奇葩弱口令到内网实战 AnQuanKeINFO

记一奇葩弱口令到内网实战

一、前期打点拿到目标后首先要做的就是信息收集,这次给的目标就给个单位名称,通过互联网上搜索发现其网站在阿里云上着实无奈,在这里推荐个寻找资产的方法,利用ICP/IP地址/域名信息备
MITRE漏洞公告意外展示易受攻击资产 AnQuanKeINFO

MITRE漏洞公告意外展示易受攻击资产

第317期你好呀~欢迎来到“安全头条”!如果你是第一次光顾,可以先阅读站内公告了解我们哦。欢迎各位新老顾客前来拜访,在文章底部时常交流、疯狂讨论,都是小安欢迎哒~如果对本小站的内容
浅识k8s中的准入控制器 AnQuanKeINFO

浅识k8s中的准入控制器

背景在 k8s中各组件和kube apiserver通信时的认证和鉴权 中提到”NodeRestriction准入插件”,实际上它是一个”准入控制器”。“准入控制器”是一个重要的概
评论:0   参与:  0