WordPress のPingback 機能の悪用を防ぐ

最近、増幅攻撃が増えている。DNS、NTP を利用した増幅攻撃は、ニュースになったので知っている人も多いだろう(そのDNSサーバやブロードバンドルータ、オープンリゾルバ? 確認サイトをJPCERT/CCが公開増幅攻撃はDNSだけではない――NTPサーバーの脆弱性に注意喚起を参照)。増幅攻撃は、主に他のサーバーへのDDoS攻撃に利用される。脆弱性のあるサーバーは「踏み台」として利用され、対象のサーバーに膨大な量のパケットを送信する。対象となったサーバーには、多数のリクエストが集中するため、サービスを提供できない状態になる。増幅攻撃のやっかいなところは、「踏み台」として利用されたサーバー側の管理者が問題に気づきにくいところだ。脆弱性を利用されても直接的な被害は発生しないため、増幅攻撃が流行した時に管理者が対処していくしかない。

WordPress の XML-RPC 機能を悪用した増幅攻撃

2014年3月13日には、WordPress の Pingback 機能を悪用した DDos 攻撃が発生したというニュースが流れた(今度はWordPressが踏み台に、Pingback機能を悪用しDDoS攻撃)。攻撃の概要は WordPress に用意された XML-RPC 機能を悪用し、Krebs on Securityに大量に Pingback を送りつけたというもの。利用するのは、WordPress が用意している xmlrpc.php というファイルだ。

xmlrpc.php が提供している機能

WordPress の XML-RPC 機能を提供している xmlrpc.php は、多くの機能を提供しているようだ。ドキュメントを探したが簡単に見つからなかったので、ソースコードを確認してみると、記事やコメントの投稿、ファイルのアップロードができる。今回問題になっているのは、任意のソース URL を指定して Pingback の送信を行える点のようだ。WordPress の XML-RPC 機能を利用していないのであれば、単純に xmlrpc.php へのアクセスを制限すればよいのだが、ソースコードを見ると Pingback の受信も xmlrpc.php で行っているようだ。
xmlrpc.php が提供している機能を調べるために今回の DDoS 攻撃について Google で検索してみると、踏み台にされたくないのでXML-RPCを無効にしたという記事や、DoSの踏み台にされているJPドメインのWordPressをまとめてみたという記事が見つかった。対応策をまとめると、

  1. XML-RPC 機能のうち、Pingback のみ無効にするようにフィルターを記述する
  2. プラグインで XML-RPC 機能の Pingback 機能を無効にする
  3. .htaccess で xmlrpc.php へのアクセスを制限する

などが挙げられていた。

WordPress に投稿するスマートフォンのアプリなどを使っている場合は、XML-RPC 機能へのアクセスは制限できないので、(1)か(2)の対処を行う必要があるだろう。また、Pingback を受信したい場合も、xmlrpc.php へのアクセスは制限できないので同様の措置が必要になる。

採用した対処策

UB Lab. では、「任意の URL をつけて、任意のサイトに Pingback を送信できる」という脆弱性が近い将来に修正されると考えて、(3)の対処策をとり、以下の記述を WordPress を設置しているディレクトリの .htaccess に追記した。

<Files xmlrpc.php>
<Limit GET>
Order allow,deny
Allow from all
</Limit>
<LimitExcept GET>
Order deny,allow
Deny from all
Allow from localhost
Allow from <サーバーのIPアドレス>
Allow from <管理元のIPアドレス>
</LimitExcept>
</Files>

XML-RPC の機能を動作させるためには、xmlrpc.php に POST でアクセスする必要があるのだが、「?rsd」というパラメーターをつけた GET のアクセスだけ受け付けているようだ。そこで、GET メソッドによるアクセスは任意のアドレスから、それ以外のメソッドを利用した場合は、自分自身か管理元の IP アドレスからのみアクセスを受け付けるようにした。アクセス制限を行うだけであれば、Pingback を送信できる API の仕様が修正されたら制限を外せばよいので対応が簡単だ。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.