压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

WordPress 5.0.0遠程代碼執(zhí)行漏洞分析

一、概要

本文詳細介紹了如何通過路徑遍歷及本地文件包含(LFI)漏洞,在WordPress中實現(xiàn)遠程代碼執(zhí)行(RCE)。該漏洞在WordPress中已存在6年之久。攻擊視頻參考此處鏈接。

在WordPress站點上,如果攻擊者具備author及以上權限,就可以在底層服務器上執(zhí)行任意PHP代碼,最終可以遠程完全接管整個站點。我們已經向WordPress安全團隊反饋了另一個漏洞,該漏洞也能讓攻擊者在任意WordPress站點上獲得類似訪問權限,目前后一個漏洞尚未修復。

二、受影響版本

在4.9.9及5.0.1版本中,由于另一個安全補丁的存在,因此本文介紹的漏洞無法順利利用。然而路徑遍歷漏洞依然可能存在,并且當前處于未修復狀態(tài)。任何WordPress站點如果安裝了無法正確處理Post Meta條目的插件,漏洞就可能利用成功。在我們的WordPress安全月活動中,我們已經發(fā)現(xiàn)了某些流行插件(活躍安裝量達數百萬計)存在這類問題。

根據WordPress下載頁面的統(tǒng)計數據,互聯(lián)網上超過33%的站點正在使用WordPress??紤]到插件可能會帶來新的問題,并且有些網站并沒有及時更新,因此我們認為受影響的站點數仍達數百萬個。

三、技術分析

我們使用自己研發(fā)的SAST解決方案RIPS(參考示例),在3分鐘內就檢測到了路徑遍歷及本地文件包含漏洞。然而,初步分析時這些漏洞似乎無法使用。經過詳細調研,事實證明這些漏洞利用起來雖然非常復雜,但的確有可能成功利用。

攻擊過程及原理示意請參考此處視頻。

背景:WordPress圖像管理

當我們將圖像上傳到WordPress站點時,圖像首先會被存放到上傳目錄中(wp-content/uploads)。WordPress也會在數據庫中創(chuàng)建該圖像的一個內部引用,以跟蹤圖像的元信息(如圖像所有者或上傳時間)。

這種元信息以Post Meta條目形式存放在數據庫中,每個條目都包含一對key/value,與某個特定的ID相對應。以evil.jpg這張上傳圖像為例,相關Post Meta如下所示:

MariaDB [wordpress]> SELECT * FROM wp_postmeta WHERE post_ID = 50;
+---------+-------------------------+----------------------------+
| post_id | meta_key                | meta_value                 |
+---------+-------------------------+----------------------------+
|      50 | _wp_attached_file       | evil.jpg                   |
|      50 | _wp_attachment_metadata | a:5:{s:5:"width";i:450 ... |
...
+---------+-------------------------+----------------------------+

在本例中,圖片所對應的post_ID值為50。如果用戶后續(xù)想使用該ID來使用或者編輯該圖像,WordPress會查找匹配的_wp_attached_file元數據條目,使用其對應的值在wp-content/uploads目錄中定位該文件。

根本問題: Post Meta可被覆蓋

在WordPress 4.9.9和5.0.1之前的版本中,Post Meta條目可以被修改,被設置為任意值。

當某張圖像被更新時(如圖像描述發(fā)生改動),那么WordPress就會調用edit_post()函數,該函數直接作用于$_POST數組。

function edit_post( $post_data = null ) {

    if ( empty($postarr) )
        $postarr = &$_POST;
    ?
    if ( ! empty( $postarr['meta_input'] ) ) {
        foreach ( $postarr['meta_input'] as $field => $value ) {
            update_post_meta( $post_ID, $field, $value );
        }
    }

如上所示,攻擊者有可能注入任意Post Meta條目。由于WordPress并沒有檢查哪些條目被修改過,因此攻擊者可以更新_wp_attached_file元數據,將其設置為任意值。該操作并不會重命名文件,只是修改了WordPress在嘗試編輯目標圖像時所要尋找的文件。這將導致路徑遍歷問題,后面我們會進一步分析。

修改Post Meta實現(xiàn)路徑遍歷

路徑遍歷問題存在于wp_crop_image()函數中,當用戶裁剪圖像時,該函數就會被調用。

該函數會獲取待裁剪的圖像ID值($attachment_id),并從數據庫中獲取相應的_wp_attached_file?Post Meta信息。

需要注意的是,由于edit_post()中存在缺陷,因此$src_file可以被設置為任意值。

簡化版的wp_crop_image()函數如下,實際代碼位于wp-admin/includes/image.php文件中。

function wp_crop_image( $attachment_id, $src_x, ...) {

    $src_file = $file = get_post_meta( $attachment_id, '_wp_attached_file' );
    ?

在下一步中,WordPress必須確保圖像實際存在并加載該圖像。在WordPress中加載指定圖像有兩種方法。第一種是簡單地在wp-content/uploads目錄中,利用_wp_attached_file?Post Meta信息查找指定的文件名(參考下一個代碼段的第二行)。

如果該方法查找失敗,則WordPress會嘗試從站點服務器上下載該圖像,這是一種備用方案。為了完成該操作,WordPress會生成一個下載URL,該URL中包含wp-content/uploads目錄對應的URL以及_wp_attached_file?Post Meta條目中存儲的文件名(如下代碼片段第6行)。

舉一個具體例子:如果_wp_attached_file?Post Meta條目中存儲的值為evil.jpg,那么WordPress首先會嘗試檢查wp-content/uploads/evil.jpg文件是否存在。如果該文件不存在,則嘗試從https://targetserver.com/wp-content/uploads/evil.jpg這個URL下載該文件。

之所以嘗試下載文件,而不是在本地搜索文件,原因在于某些插件會在用戶訪問URL時動態(tài)生成圖像。

請注意,這個過程并沒有進行任何過濾處理。WordPress只會簡單地將上傳目錄以及URL拼接起來(URL中包含用戶輸入的$src_file)。

一旦WordPress通過wp_get_image_editor()成功加載一個有效的圖像,就會進行裁剪處理。

    ?
    if ( ! file_exists( "wp-content/uploads/" . $src_file ) ) {
            // If the file doesn't exist, attempt a URL fopen on the src link.
            // This can occur with certain file replication plugins.
            $uploads = wp_get_upload_dir();
            $src = $uploads['baseurl'] . "/" . $src_file;
        } else {
            $src = "wp-content/uploads/" . $src_file;
        }

    $editor = wp_get_image_editor( $src );
    ?

經過裁剪的圖片隨后會被保存回文件系統(tǒng)中(無論是下載文件還是本地文件)。保存文件所使用的文件名為get_post_meta()所返回的$src_file,而攻擊者可以控制這個值。代碼中對文件名做的唯一一處修改是為文件的basename(去掉文件名的目錄及后綴)添加cropped-前綴字符串(如下代碼段中第4行)。以前面的evil.jpg為例,這里生成的結果文件名為cropped-evil.jpg。

如果結果文件路徑不存在,則WordPress隨后會使用wp_mkdir_p()創(chuàng)建相應的目錄(參考第6行代碼)。

隨后,WordPress使用圖像編輯器對象的save()方法,將圖像最終寫入文件系統(tǒng)中。save()方法也沒有對給定的文件名執(zhí)行目錄遍歷檢查。

    ?
    $src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );

    $dst_file = str_replace( basename( $src_file ), 'cropped-' . basename( $src_file ), $src_file );

    wp_mkdir_p( dirname( $dst_file ) );

    $result = $editor->save( $dst_file );

利用思路

到目前為止,我們已經分析了哪個文件可能會被載入圖像編輯器中,因為WordPress沒有執(zhí)行過濾操作。然而,如果該文件并不是有效的圖像,那么圖像編輯器就會拋出異常。因此這里第一個假設是,WordPress只能裁剪上傳目錄外的圖像。

然而,由于WordPress在沒找到圖像時會嘗試下載圖像,因此會導致遠程代碼執(zhí)行(RCE)漏洞。

本地文件 HTTP下載文件
上傳的文件 evil.jpg evil.jpg
_wp_attached_file evil.jpg?shell.php evil.jpg?shell.php
待加載的結果文件 wp-content/uploads/evil.jpg?shell.php https://targetserver.com/wp-content/uploads/evil.jpg?shell.php
實際位置 wp-content/uploads/evil.jpg https://targetserver.com/wp-content/uploads/evil.jpg
結果文件名 None – 文件加載失敗 evil.jpg?cropped-shell.php

我們可以將_wp_attached_file的值設置為evil.jpg?shell.php,這樣WordPress就會發(fā)起一個HTTP請求,請求URL為https://targetserver.com/wp-content/uploads/evil.jpg?shell.php。由于在該上下文中,?后的所有字符都會被忽略,因此該請求會返回一個有效的圖像文件。最終結果文件名會變成evil.jpg?shell.php。

然而,雖然圖像編輯器的save()方法沒有檢查路徑遍歷攻擊,但會將待加載的圖像的mime擴展名附加到結果文件名中。在本例中,生成的文件名將為evil.jpg?cropped-shell.php.jpg。這樣可以讓新創(chuàng)建的文件再次保持無害狀態(tài)。

然而,我們還是可以使用類似evil.jpg?/../../evil.jpg的載荷,將結果圖像植入任意目錄中。

利用路徑遍歷:Theme目錄中的LFI

每個WordPress主題實際上都是位于wp-content/themes目錄中的一個子目錄,可以為不同場景提供模板文件。比如,如果博客的某位訪問者想查看博客文章,WordPress則會在當前激活的主題中查找post.php文件。如果找到模板,則會include()該模板。

為了支持額外的自定義層,我們可以為某些文章選擇自定義模板。為了完成該任務,用戶需要設置數據庫中的_wp_page_template?Post Meta條目,將其設置為自定義文件名。這里唯一的限制條件是:待include()的文件必須位于當前激活的主題目錄中。

通常情況下,該目錄無法訪問,并且不會有文件上傳到該目錄中。然而,攻擊者可以濫用前文描述的路徑遍歷漏洞,將惡意構造的圖像植入當前使用的主題目錄中。隨后攻擊者可以創(chuàng)建一個新的帖子,濫用同一個bug,更新_wp_attached_filePost Meta數據庫條目,以便include()該圖像。將PHP代碼注入圖像后,攻擊者隨后就能獲得任意遠程代碼執(zhí)行權限。

構造惡意圖像:GD及Imagick

WordPress支持PHP的兩種圖像編輯擴展:GD以及Imagick。這兩者有所不同,Imagick并不會刪除圖像的exif元數據,這樣我們就可以將PHP代碼藏身其中。GD會壓縮每張圖像,刪除所有的exif元數據。

然而,我們還是可以制作包含精心構造的像素的圖像來利用漏洞,當GD裁剪完圖像后,這些像素會以某種方式進行反轉,最終達到PHP代碼執(zhí)行執(zhí)行目標。在我們研究PHP GD擴展的內部結構過程中,libgd又爆出可被利用的一個內存破壞漏洞(CVE-2019-6977)。

四、時間線

日期 事件
2018/10/16 我們在Hackerone上將漏洞反饋給WordPress
2018/10/18 某個WordPress安全團隊成員確認該報告,并表示在驗證報告后會回頭聯(lián)系我們
2018/10/19 另一個WordPress安全團隊成員請求了解更多信息
2018/10/22 我們向WordPress提供了更多信息,并提供了包含270行利用代碼的完整腳本,幫助對方確認漏洞
2018/11/15 WordPress觸發(fā)該漏洞,表示可以復現(xiàn)該漏洞
2018/12/06 WordPress 5.0發(fā)布,沒有修復該漏洞
2018/12/12 WordPress 5.0.1發(fā)布,包含安全更新。某個補丁會阻止攻擊者任意設置post meta條目,因此使該漏洞無法直接利用。然而,路徑遍歷漏洞依然存在,并且如果已安裝的插件沒有正確處理Post Meta條目就可以利用該漏洞。WordPress 5.0.1并沒有解決路徑遍歷或者本地文件包含漏洞
2018/12/19 WordPress 5.0.2發(fā)布,沒有修復漏洞
2019/01/09 WordPress 5.0.3發(fā)布,沒有修復漏洞
2019/01/28 我們詢問WordPress下一個安全版本的發(fā)布時間,以便協(xié)調我們的文章公布時間,準備在補丁發(fā)布后公布我們的分析文章
2019/02/14 WordPress推出補丁
2019/02/14 我們提供補丁反饋,驗證補丁的確能緩解漏洞利用過程

五、總結

本文介紹了WordPress中存在的一個遠程代碼執(zhí)行漏洞,該漏洞存在時間已超過6年。RIPS報告了5.0.1版以及4.9.9版中的另一個漏洞,打上該漏洞補丁后,這個RCE漏洞也無法正常利用。然而如果目標站點安裝了允許覆蓋任意Post Data的插件,那么依然可以利用路徑遍歷漏洞。由于我們在攻擊目標WordPress站點時需要通過身份認證,因此我們決定在報告漏洞4個月后再公開該漏洞。

感謝WordPress安全團隊的志愿者們,他們在該問題溝通上非常友好并且非常專業(yè)。

原文地址:https://blog.ripstech.com/2019/wordpress-image-remote-code-execution/

上一篇:WinRAR被曝嚴重安全漏洞5億用戶受影響

下一篇:Lucky雙平臺勒索者解密分析