GET /wp-json/wp/v2/posts/1獲取一個ID為1的單獨的Post:

可以看到ID為1的文章標題為Hello World,包括文章的路由也有。

路由

路由是用于訪問端點的“名稱”,在URL中使用(在非法情況下可控,就像這個漏洞一樣)。

例如,使用URLhttp://example.com/wp-json/wp/v2/posts/123:

路由(route)是wp/v2/posts/123,不包括wp-json,因為wp-json是API本身的基本路徑。

這個路由有三個端點:

GET觸發一個get_item方法,將post數據返回給客戶端。

PUT觸發一個update_item方法,使數據更新,并返回更新的發布數據。

DELETE觸發delete_item方法,將現在刪除的發布數據返回給客戶端。 靜態追蹤

知道了WP-API的路由信息以及其操作方式,可以根據其運行的思路來看一下具體實現的代碼。

我們看一下/wp-includes/rest-api/endpoints/class-wp-rest-post-controller.php:

根據上面的信息,我們可以知道這是注冊controller對象的路由,實現路由中端點方法。

在這里,如果我們向/wp-json/wp/v2/posts/1發送請求,則ID參數將被設置為1:

同時,注意一下這里:

可以看到在registerrestroute中對路由進行了正則限制:

也就是防止攻擊者惡意構造ID值,但是我們可以發現$GET和$POST值優先于路由正則表達式生成的值:

這邊沒有找到ID為123hh的項目,所以返回rest_invalid。

現在我們可以忽略路由正則的限制,來傳入我們自定義的ID。

接下來在審查各個端點方法中,找到了updateitem這個方法,及其權限檢查方法updateitempermissionscheck:

可以看到,此函數通過檢查文章是否實際存在,以及我們的用戶是否有權限編輯這邊文章來驗證請求。

但是當我們發送一個沒有響應文章的ID時,就可以通過權限檢查,并允許繼續執行對update_item方法的請求。

具體到代碼,就是讓$post為空,就可以通過權限檢查,接下來跟進get_post方法中看一下:

從代碼中可以看出,它是用wpposts中的getinstance靜態方法來獲取文章的,跟進wp_posts類,位于/wp-includes/class-wp-post.php中:

public static function get_instance( $post_id ) {  
global $wpdb;

if ( ! is_numeric( $post_id ) || $post_id != floor
( $post_id ) || ! $post_id ) {
return false;
}

回頭再看一下可執行方法upload_item:

public function update_item( $request ) {  

$id = (int) $request['id'];

$post = get_post( $id );

if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) {
return new WP_Error( 'rest_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
}

$post = $this->prepare_item_for_database( $request );

if ( is_wp_error( $post ) ) {
return $post;
}

// convert the post object to an array, otherwise wp_update_post will expect non-escaped input.

$post_id = wp_update_post( wp_slash( (array) $post ), true );

在這邊將ID參數裝換為一個整數,然后傳遞給get_post。而PHP類型轉換的時候回出現這樣的情況:

所以,也就是說,當攻擊者發起/wp-json/wp/v2/posts/1?id=1hhh請求時,便是發起了對ID為1的文章的請求。

下面為利用[exploit-db][2]上的POC來進行測試:

新建文章:

測試:

測試結果:

多想了一下

乍一看,感覺這個洞并沒有什么太大的影響,但是仔細想了一下,危害還是很大的。

先不說WordPress頁面執行php代碼的各種插件,還有相當一部分的WordPress文章可以調用短代碼的方式來輸出特定的內容,以及向日志中添加內容,這是一個思路。

另一個思路就是可以進行對原來文章中的指定超鏈接進行修改,從而進行釣魚。

還有一個思路,就是利用WordPress文章中解析html以及JavaScript文件包含的做法,輔助其他方法,進行攻擊。

0x03 diff比較

對于該漏洞,關鍵的修改在/wp-includes/class-wp-post.php中:

更改了對于$post_id的參數的傳入順序和判斷條件,防止了我們傳入數字+字母這樣的格式進行繞過。

0x04 修補方案

將WordPress更新到最新版本。

0x05 參考鏈接

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

https://www.exploit-db.com/exploits/41223/

原文鏈接地址:http://paper.seebug.org/208/,點擊“閱讀原文”,即可進入。

本文章轉載微信公眾號@懸鏡安全說

上一篇:

深入解析API網關策略:認證、授權、安全、流量處理與可觀測性

下一篇:

API 網關集成 SkyWalking 打造全方位日志處理
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費