1. 程式人生 > >Wordpress4.9.6 任意檔案刪除漏洞復現分析

Wordpress4.9.6 任意檔案刪除漏洞復現分析

第一章 漏洞簡介及危害分析

1.1漏洞介紹

WordPress可以說是當今最受歡迎的(我想說沒有之一)基於PHP的開源CMS,其目前的全球使用者高達數百萬,並擁有超過4600萬次的超高下載量。它是一個開源的系統,其次它的功能也十分強大,原始碼可以在這裡找到。也正因為此,WordPress也成了眾多黑客的攻擊目標,一旦得手也就意味著數百萬使用者的淪陷。這種廣泛的採用使其成為網路犯罪分子的一個有趣目標。這次實驗的漏洞是在WordPress核心中的一個經過身份驗證的任意檔案刪除漏洞CVE-2018-20714

該漏洞可能導致攻擊者執行任意程式碼。該漏洞自發現到報告給WordPress安全團隊7個月,但仍未修補。自首次報告以來已經過去很長時間沒有任何補丁或具體計劃。現在wordpress4.9.6及以下版本都存在此漏洞。

1.2漏洞的利用條件

為了利用下面討論的漏洞,攻擊者需要獲得預先編輯和刪除媒體檔案的許可權。也就是擁有作者許可權。這裡我們也要了解一下wordpress有哪些許可權使用者。

  • 超級管理員(Super Admin) – 有權訪問站點網路管理功能和所有其他功能。
  • 管理員(Administrator) – 有權訪問單個站點內的所有管理功能。
  • 編輯(Editor) – 可以釋出和管理帖子,包括其他使用者的帖子。
  • 作者(Author) – 可以釋出和管理自己帖子。
  • 貢獻者(Contributor ) – 可以編寫和管理他們自己的帖子但不能釋出。
  • 訂閱者(Subscriber ) – 只能管理他們個人資料的人。

我們發現作者許可權使用者原本只可以釋出和管理自己的帖子,但通過這個漏洞卻可以劫持整個網站並在伺服器上執行任意程式碼,也就是通過這個WordPress漏洞,黑客可輕鬆控制網站。

該漏洞存在於使用者永久刪除上傳影象的縮圖時在後臺執行的WordPress核心功能之一。

1.3漏洞的危害

至少一個作者帳戶的要求會在某種程度上自動降低此漏洞的嚴重程度,這可能會被流氓內容撰稿人或黑客利用網路釣魚,密碼重用或其他攻擊以某種方式獲取作者的憑證所利用。

利用此漏洞可以使攻擊者能夠刪除WordPress安裝的任何檔案(+ PHP程序使用者具有刪除許可權的伺服器上的任何其他檔案)。除了擦除整個WordPress安裝的可能性,如果沒有可用的當前備份可能會帶來災難性的後果,攻擊者可以利用任意檔案刪除的能力來規避一些安全措施並在Web伺服器上執行任意程式碼。更準確地說,可以刪除以下檔案:

  • .htaccess:通常,刪除此檔案不會產生任何安全後果。但是,在某些情況下,.htaccess檔案包含與安全性相關的約束(例如,對某些資料夾的訪問約束)。刪除此檔案將停用這些安全約束。
  • index.php檔案:通常將空的index.php檔案放入目錄中,以防止Web伺服器無法執行此操作的目錄列表。刪除這些檔案會向攻擊者授予受此度量保護的目錄中所有檔案的列表。
  • wp-config.php:刪除WordPress安裝的這個檔案會在下次訪問網站時觸發WordPress安裝過程。這是因為wp-config.php包含資料庫憑據,並且沒有它的存在,WordPress就像尚未安裝一樣。攻擊者可以刪除此檔案,使用他為管理員帳戶選擇的憑據進行安裝過程,最後在伺服器上執行任意程式碼。

但是,應該注意的是,由於攻擊者無法直接讀取wp-config.php檔案的內容來知道現有的“資料庫名稱”,“mysql使用者名稱”及其“密碼”,所以他可以重新設定目標站點在他的控制下使用遠端資料庫伺服器。一旦完成,攻擊者可以建立一個新的管理員帳戶並完全控制網站,包括在伺服器上執行任意程式碼的能力。“除了刪除整個WordPress安裝的可能性,如果沒有當前的備份可用會造成災難性的後果,攻擊者可以利用任意檔案刪除的功能來規避一些安全措施並在Web伺服器上執行任意程式碼

 

第二章 漏洞環境搭建及復現

2.1.搭建環境

前往wordpress中文官網https://cn.wordpress.org/download/releases/下載有此漏洞的版本

(1)安裝wordpress

WordPress 4.9.6

 

安裝成功後,在後臺新增一個“作者”許可權賬戶 “xy” 只有寫作功能,用於測試

2.2漏洞復現測試

(1)用新新增的作者許可權使用者登陸到網站後臺

(2)新增媒體,上傳一張圖片

  

(3)點選編輯

(4)在頁面原始碼中找出 _wpnonce 值,通過頁面原始碼查詢 值為“388054b4f3”並將cookie複製下來。

 

(5)然後使用curl或burp構造http請求。

傳送到repeater構造資料包然後傳送post資料包 (需要帶入cookie值)

payload: action=editattachment&_wpnonce=388054b4f3&thumb=../../../../wp-config.php'   

POST /wp-admin/post.php?post=21&action=edit HTTP/1.1 

傳送成功會返回302狀態

 

(6)此時在點選刪除按鈕

(7)抓包檢視,也是返回302包

(8)再次訪問主網站就會要求重新安裝wordpress

 

 

第三章 漏洞程式碼審計以及臨時手動修復

 

3.1 原始碼審計

(1)既然是任意檔案刪除漏洞,那我們就從刪除功能入手,先來看wp-admin/post.php的246-268行:

case 'delete':

    check_admin_referer('delete-post_' . $post_id);

 

    if ( ! $post )

        wp_die( __( 'This item has already been deleted.' ) );

 

    if ( ! $post_type_object )

        wp_die( __( 'Invalid post type.' ) );

 

    if ( ! current_user_can( 'delete_post', $post_id ) )

        wp_die( __( 'Sorry, you are not allowed to delete this item.' ) );

 

    if ( $post->post_type == 'attachment' ) { //刪除附件

        $force = ( ! MEDIA_TRASH );

        if ( ! wp_delete_attachment( $post_id, $force ) )

            wp_die( __( 'Error in deleting.' ) );

    } else {

        if ( ! wp_delete_post( $post_id, true ) )

            wp_die( __( 'Error in deleting.' ) );

    }

 

    wp_redirect( add_query_arg('deleted', 1, $sendback) );

    exit();

 

(2)由於我們刪除的是圖片附件,所以程式會進入wp_delete_attachment函式,跟進:  wp-include/post.php,函式太長,只擷取關鍵部分。

function wp_delete_attachment( $post_id, $force_delete = false ) {
.... 
    if ( ! empty($meta['thumb']) ) {
    // Don't delete the thumb if another attachment uses it.
    if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like( $meta['thumb'] ) . '%', $post_id)) ) {
        $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
        /** 該過濾器記錄在wp-includes / functions.php中 */
        $thumbfile = apply_filters( 'wp_delete_file', $thumbfile );
        @ unlink( path_join($uploadpath['basedir'], $thumbfile) );
    }
}
. . . .
 
wp_delete_file( $file );

 

$meta['thumb']來自與資料庫,是圖片的屬性之一。程式碼未檢查$meta['thumb']的內容,直接帶入unlink函式,如果$meta['thumb']可控

 (3) 那麼可控點在哪呢?還記得漏洞利用的第一步嗎?現在我們就回到wp-admin/post.php看一下具體程式碼

/wp-admin/post.php

 
//178-189行
case 'editattachment':
    check_admin_referer('update-post_' . $post_id);
 
    // Don't let these be changed
    unset($_POST['guid']);
    $_POST['post_type'] = 'attachment';
 
    // Update the thumbnail filename
$newmeta = wp_get_attachment_metadata( $post_id, true ); 
//獲取附件的屬性
    $newmeta['thumb'] = $_POST['thumb'];
 
wp_update_attachment_metadata( $post_id, $newmeta );
 //更新資料庫中的資訊

程式碼片段/wp-admin/post.php表示如何將屬於附件的縮圖的檔名儲存到資料庫中。在從儲存的使用者輸入檢索$_POST[‘thumb’]和儲存到資料庫wp_update_attachment_metadata()之間,沒有安全措施來確保該值確實代表正在編輯的附件的縮圖。值$_POST[‘thumb’]可以變更修改為相對於WordPress上傳目錄的任何檔案的路徑,當附件被刪除時,檔案將被刪除,如第一個列表中所示。

總結一句就是該漏洞出現的原因是由於在WordPress的wp-includes/post.php檔案中wp_delete_attachement()函式在接收刪除檔案引數時未進行安全處理,直接進行執行導致。

3.2臨時手動修復

(1)在上面我們瞭解了漏洞生成的原因之後,我們將進行嘗試性的漏洞修復。

首先針對漏洞細節提出修復方向

1. 過濾. \等關鍵字元

2. 掛鉤wp_update_attachement_metadata()呼叫並確保為meta[‘thumb’]值提供的資料thumb不包含任何可以進行路徑遍歷的部分.

3. 將$newmeta['thumb'] = $_POST['thumb'];改為$newmeta['thumb'] = basename($_POST['thumb']);

(2)修復程式碼

通過將修復程式新增到functions.php當前活動的主題/子主題的檔案中,可以將修復程式整合到現有的WordPress安裝中。

add_filter('wp_update_attachment_metadata','rips_unlink_tempfix';
 
function rips_unlink_tempfix( $data ) {
    if( isset($data['thumb']) ) {
        $data['thumb'] = basename($data['thumb']);
    }
 
    return $data;
}

 

我們將補丁放入指定位置之後,再來測試漏洞。

 

可以看到在手動打了補丁之後,雖然發包和回顯跟之前區別不大,但是已經無法任意刪除檔案了

 

第四章 漏洞操作的流量分析

總體操作與上文漏洞復現差不多,但為了監控流量和避免干擾便於分析,本次操作在虛擬機器中進行並使用wireshark分析流量。

(1)使用wireshark捕獲惡意操作的流量資料

 

 

 

伺服器返回302

我們發現惡意資料最主要的特徵就是向伺服器傳入了一個“thumb”自定義的值

(2)我們追蹤這個包的tcp流

 

 

 

也出現了我們構造的關鍵程式碼,但由於這個漏洞可以刪除任意檔案,所以我們需要關注的就是thumb傳入的數值,不管上傳請求的方式是什麼,總需要傳入

thumb=xxxx

所以當流量中出現這些異常並指定thumb的值的時候,就需要引起我們的注意,要檢視數值是否合法。