最新消息:图 床

從WordPress SQLi談PHP格式化字符串問題(2017.11.01更新)

COOL IAM 250浏览 0评论

作者:SeaFood@知道創宇404實驗室

0x00 背景

近日,WordPress爆出了一個SQLi漏洞,漏洞發生在WP的後台上傳圖片的位置,通過修改圖片在數據庫中的參數,以及利用php的sprintf函數的特性,在刪除圖片時,導致'單引號的逃逸。漏洞利用較為困難,但思路非常值得學習。

0x01 漏洞分析

漏洞發生在wp-admin/upload.php的157行,進入刪除功能,

https://medium.com/websec/wordpress-sqli-poc-f1827c20bf8e

http://php.net/manual/zh/function.sprintf.php

https://github.com/php/php-src/blob/c8aa6f3a9a3d2c114d0c5e0c9fdd0a465dbb54a5/ext/standard/formatted_print.c

https://www.seebug.org/vuldb/ssvid-96376

————————————2017.11.01 更新————————————

0x07 WordPress 4.8.2補丁問題

國外安全研究人員Anthony Ferrara給出了另一種此漏洞的利用方式,並指出了WordPress 4.8.2補丁存在的問題。

如下代碼

<?php

$input1 = '%1$c) OR 1 = 1 /*';
$input2 = 39;
$sql = "SELECT * FROM foo WHERE bar IN ('$input1') AND baz = %s";
$sql = sprintf($sql, $input2);
echo $sql;
//result: SELECT * FROM foo WHERE bar IN ('') OR 1 = 1 /*') AND baz = 39

%c起到了類似chr()的效果,將數字39轉化為',從而導致了sql注入。

對此,WordPress 4.8.2補丁在WPDB::prepare()中加入

$query = preg_replace( '/%(?:%|$|([^dsF]))/', '%%//1', $query );

從而,禁用了除%d%s%F之外的格式,這種方法導致了三個問題。

1.大量開發者在開發過程中使用了例如%1$s的格式,此次補丁導致代碼出錯。

2.在例如以下代碼中

   $db->prepare("SELECT * FROM foo WHERE name= '%4s' AND user_id = %d", $_GET['name'], get_current_user_id());

%4s會被替換成%%4s%%在sprintf中代表字符%,沒有格式化功能。所以,$_GET['name']會被寫到%d處,攻擊者可以控制user id,可能導致越權問題的出現。

3.補丁可以被繞過

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 ) );
   }

如果輸入

   $meta_value = ' %s ';
   $meta_key = ['dump', ' OR 1=1 /*'];

之後兩次進入prepare(),因為

   $query = preg_replace( '|(?<!%)%s|', "'%s'", $query ); 

使得%s變為''%s''

最後結果

   SELECT type FROM table WHERE meta_key = 'dump' AND meta_value = '' OR 1=1 /*''

WordPress也承認這是一個錯誤的修復

在WordPress 4.8.3的補丁中,一是修改了meta.php中兩次使用prepare()的問題,二是使用隨機生成的佔位符替換%,在進入數據庫前再替換回來。


转载请注明:IAMCOOL » 從WordPress SQLi談PHP格式化字符串問題(2017.11.01更新)

0 0 vote
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x