WordPressのセキュリティ

こんにちは、新里です。
ここでは人気があるCMSであるWordPressを実際にサーバー上に立てて、セキュリティスキャン・対策などを簡単に紹介します。

環境

まずは適当にサーバーを用意してWordPressを動作させます。環境は以下の通りです。

  • Ubuntu : 20.04
  • WordPress :5.8.1(MariaDB)
sudo apt install mariadb-client mariadb-server apache2 php php-mysql certbot python3-certbot-apache
cd /var/www/html
wget https://ja.wordpress.org/latest-ja.tar.gz
tar -zxvf latest-ja.tar.gz

各種インストールしてDBの作成・WordPressのセットアップを行った後、サイトを見てみると、デフォルトの投稿があります。とりあえずWordPressをサクッと動かすことができました。テスト投稿はあっても無くても良いので、WordPressにログインしてテスト投稿を消してまっさらな状態にしておきます。

wpscanで確認する

デフォルトで立ち上げたWordPressのセキュリティスキャンを行ってみます。ここではよく利用されるwpscanを利用して行ってみます。ドメインは便宜上hogehogeとしています。

# dockerで実行
docker run -it --rm wpscanteam/wpscan --url https://hogehoge --enumerate u

_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ®
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.19
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[+] URL: https://hogehoge/ [xxx.xxx.xxx.xxx]
[+] Started: Wed Oct 20 08:38:53 2021

Interesting Finding(s):

[+] Headers
 | Interesting Entry: Server: Apache/2.4.41
 | Found By: Headers (Passive Detection)
 | Confidence: 100%

[+] XML-RPC seems to be enabled: https://hogehoge/xmlrpc.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%
 | References:
 |  - http://codex.wordpress.org/XML-RPC_Pingback_API
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_ghost_scanner/
 |  - https://www.rapid7.com/db/modules/auxiliary/dos/http/wordpress_xmlrpc_dos/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_xmlrpc_login/
 |  - https://www.rapid7.com/db/modules/auxiliary/scanner/http/wordpress_pingback_access/

[+] WordPress readme found: https://hogehoge/readme.html
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] Upload directory has listing enabled: https://hogehoge/wp-content/uploads/
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 100%

[+] The external WP-Cron seems to be enabled: https://hogehoge/wp-cron.php
 | Found By: Direct Access (Aggressive Detection)
 | Confidence: 60%
 | References:
 |  - https://www.iplocation.net/defend-wordpress-from-ddos
 |  - https://github.com/wpscanteam/wpscan/issues/1299

[+] WordPress version 5.8.1 identified (Latest, released on 2021-09-09).
 | Found By: Rss Generator (Passive Detection)
 |  - https://hogehoge/index.php/feed/, <generator>https://wordpress.org/?v=5.8.1</generator>
 |  - https://hogehoge/index.php/comments/feed/, <generator>https://wordpress.org/?v=5.8.1</generator>

[+] WordPress theme in use: twentytwentyone
 | Location: https://hogehoge/wp-content/themes/twentytwentyone/
 | Latest Version: 1.4 (up to date)
 | Last Updated: 2021-07-22T00:00:00.000Z
 | Readme: https://hogehoge/wp-content/themes/twentytwentyone/readme.txt
 | Style URL: https://hogehoge/wp-content/themes/twentytwentyone/style.css?ver=1.4
 | Style Name: Twenty Twenty-One
 | Style URI: https://wordpress.org/themes/twentytwentyone/
 | Description: Twenty Twenty-One is a blank canvas for your ideas and it makes the block editor your best brush. Wi...
 | Author: the WordPress team
 | Author URI: https://wordpress.org/
 |
 | Found By: Css Style In Homepage (Passive Detection)
 |
 | Version: 1.4 (80% confidence)
 | Found By: Style (Passive Detection)
 |  - https://hogehoge/wp-content/themes/twentytwentyone/style.css?ver=1.4, Match: 'Version: 1.4'

[+] Enumerating Users (via Passive and Aggressive Methods)
 Brute Forcing Author IDs - Time: 00:00:00 <=================================================================================================================> (10 / 10) 100.00% Time: 00:00:00

[i] User(s) Identified:

[+] admin
 | Found By: Wp Json Api (Aggressive Detection)
 |  - https://hogehoge/index.php/wp-json/wp/v2/users/?per_page=100&page=1
 | Confirmed By: Author Id Brute Forcing - Author Pattern (Aggressive Detection)

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Wed Oct 20 08:38:57 2021
[+] Requests Done: 53
[+] Cached Requests: 7
[+] Data Sent: 14.086 KB
[+] Data Received: 403.391 KB
[+] Memory used: 199.523 MB
[+] Elapsed time: 00:00:03

適当にadminユーザーを作成した、”admin”が判明していますね。これは投稿してあるWordPressのREST API(wp-json)からユーザ一覧を取得することができています。
他にもApacheのバージョン、WordPressのバージョン、利用しているプラグインなど一通り出てきました。バージョンが判明すると、対象となるバージョンの脆弱性から攻撃を受けてしまうので、あまり良い気がしません。以下、簡単に対策を行います。

HTTPヘッダからバージョンを消す

HTTP headerServer: Apache/2.4.41 まずはこの部分を見せないようにします。

# /etc/apache2/conf-enabled/security.conf
ServerTokens Prod

#  /etc/php/7.4/apache2/php.ini
expose_php = Off

readme.htmlを削除する

デフォルトではWordPressをインストールしたディレクトリに”readme.html”があります。ログイン画面へのURLへの記載があったりするので削除しておきます。

Indexesを無効にする

何もしないと/wp-contents/uploads/配下にアクセスするとファイル一覧が見れてしまいます。これはちょっと良くないですね。

そこで、Apacheもしくは.htaccessの設定で以下を設定しておきます。

Options -Indexes

ログイン画面

何もしないとWordPressの管理画面に直接アクセスすることができます。先にユーザー名が判明しているので、ユーザー名を使った辞書攻撃や、パスワード再発行から当該ユーザーに対してパスワード変更通知メールを送信することができたりもします。

そこで管理者画面にアクセスする時は、何個か対策を用意しておきます。これらは利用しているWordPressの環境に合わせて行います。

  • セキュリティのプラグインを入れて画像認証(CAPTCHA)
  • BASIC認証を使う
  • 特定のIP以外からのアクセスはブロック

セキュリティプラグインを使う

ここではSiteGuardというWordPress向けのプラグインを利用します。SiteGuardを使うとログイン画面の制御の他に、wpscanで指摘されたREST APIを無効にしてユーザー名の取得を防ぐことが出来ます。
WordPressのプラグインからSiteGuardを指定してインストールして、ログインページの設定を行います。

とりあえずデフォルトの設定にして変更を保存しておきます。そして管理画面にアクセスするとCAPTCHAの指定が出てきます。他にも一定回数のログイン試行で失敗するとロックする仕組みや、ログインURL(wp-login.php)を変える機能など、機能が充実してます。WordPressのプラグインを使って、簡単にセキュアにする時は良いでしょう。

他にも管理画面にBASIC認証をかけたり、特定のIPからのみアクセス可能にする(例えば社内のみからアクセス可能)といった設定をすることで、不意のログインやアクセス対策をすることが出来るでしょう。

おまけ

SiteGuardには前述したREST APIを無効化する機能があります。WordPressはREST APIで様々な情報にアクセスできます。ユーザー名・記事・アップロードしているファイルなどです。これらの情報にアクセス出来るため、意図しないファイルアップロードがアクセスされる可能性があります。
実際に行って見てみましょう。

  • 適当にExcelファイルを用意する。
  • WordPressにファイルをアップロードする

手順1:適当にExcelファイルを用意する

ここではサンプルとして適当なExcelファイルを用意します。PDFや画像ファイルなどでも構いません。

手順2:WordPressにファイルをアップロードする


 用意したファイルをWordPressにアップロードします。

ここではファイル(private_items.xlsx)をWordPressにアップロードしただけで、まだ記事は何も公開されていない状態です。

公開した記事が無い状態でファイルをアップロードしただけなら、そのファイルは見られないと通常は思うはずです。しかし、アップロードしたファイルは実はすでに見える状態になっています。ここでWordPressにログインしていないユーザーでREST APIをブラウザから叩いて見てみましょう。URLは”サイト名/wp-json/wp/v2/media”などでアクセス可能です。

先程アップロードしたファイルが見えてきました。ここで実際にこのファイルのURL(https://wp〜/wp-content/uploads/2021/11/private_items.xlsx)にアクセスすると、先程アップロードしたファイルを実際に見ることが出来ます。
誤ってアップロードしたファイルや不意にアップロードしたファイルなど、REST APIを利用することで、公開・非公開に関わらず、記事で使ってなくてもファイルのURLを特定して見ることが出来ます。

このようなREST APIの利用はSiteGuardの”REST API無効化”で防ぐことが出来ます。この機能を有効にすると、先程のWordPressのREST APIのURLを見にいってもアクセスすることが出来なくなります。またREST API経由でのユーザーIDの取得についても防止できるというメリットがあります。
WordPressは非常に手軽に利用できて、豊富なプラグイン・テンプレートがあるので誰でも簡単に利用できます。ただ、便利で簡単に使える反面、セキュリティにも一定の配慮をした方が良いでしょう。

ブログの著者欄

新里 祐教

GMOインターネットグループ株式会社

プログラマー。GMOインターネットグループにて開発案件・新規事業開発に携わる。またオープンソースの開発や色々なアイデアを形にして展示をするなどの活動を行っている。

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック