1. はじめに
三菱電機の木原です。
三菱電機 情報技術総合研究所では、製品開発時のセキュリティ対策にフィードバックする目的で、複数種類のハニーポットを設置・運用しています。
今回はIoT家電を標的としたサイバー攻撃を観測するハニーポット「IoT家電ハニーポット」で観測した中で、2026年7月に公表された深刻度の高いWordPress[1]の脆弱性「wp2shell」を標的としたとみられるパケットに着目した分析結果をご紹介します。
2. wp2shellとは
wp2shellは、2026年7月に公表されたWordPressコアの2つの脆弱性(CVE-2026-63030[2]:CVSS v3.1スコア9.8、CVE-2026-60137[3]:CVSS v3.1スコア5.9-いずれもWPScanによる評価)を組み合わせた攻撃チェーンで、認証なしの状態からリモートコード実行に至る可能性がある、深刻度の高いものです。
さらに、WordPressのプラグインではなく、本体(コア)の脆弱性であることから、影響範囲も広いと考えられます。
CVE-2026-63030は、WordPressに実装されている、複数のREST APIリクエストを1つのHTTPリクエストで処理できるBatch API(/batch/v1)の脆弱性です。この脆弱性を悪用すると、Batch APIで処理の宛先の取り違え(ルート混同)が起き、本来適用されるべきパラメータのサニタイズを回避できてしまいます。
CVE-2026-60137は、WP_Queryのauthor__not_inパラメータのサニタイズが適切でないことによる、SQLインジェクションの脆弱性です。ただし、通常はREST API側で入力がサニタイズされるため、標準構成のWordPressコア単体では悪用されにくいものです。
この2つを組み合わせると、CVE-2026-63030でサニタイズを回避した入力がCVE-2026-60137のSQLインジェクション脆弱性の悪用に使われ、結果として認証なしでリモートコード実行に至る可能性が指摘されています[2][4]。
続いて、wp2shellに関連するニュースの時系列を以下に示します。
| 日付(日本時間) | 出来事 |
|---|---|
| 2026年7月18日 | WordPressによる修正版のリリース[5] |
| 2026年7月18日 | CVE(CVE-2026-63030[2]、CVE-2026-60137[3])が公開(NVDに掲載) |
| 2026年7月19日 | PoCの公開が報じられる[4][6] |
| 2026年7月22日 | CISAのKEV(Known Exploited Vulnerabilities)カタログに掲載[7][8] |
| 2026年7月22日 | IPAが注意喚起[9] |
| 2026年7月23日 | JPCERT/CC WeeklyReport掲載[10] |
※日付は全て日本時間に換算しています。
日本時間2026年7月18日(米国時間7月17日)に本脆弱性は明らかになり、CVE情報の公開(NVD掲載)とWordPressによる修正バージョンの公開が行われました。影響を受けるバージョンと修正後のバージョンは以下のとおりです[2][3][5]。
| 系列 | 影響を受けるバージョン | 影響を受ける脆弱性 | 修正後のバージョン |
|---|---|---|---|
| 7.0系 | 7.0.0~7.0.1 | CVE-2026-63030、CVE-2026-60137 | 7.0.2 |
| 6.9系 | 6.9.0~6.9.4 | CVE-2026-63030、CVE-2026-60137 | 6.9.5 |
| 6.8系 | 6.8.0~6.8.5 | CVE-2026-60137のみ | 6.8.6 |
6.8系はCVE-2026-63030の影響を受けないため、2つを組み合わせた攻撃チェーン(wp2shell)が成立するのは6.9系と7.0系です。なお、6.8より前のバージョンはどちらの脆弱性の影響も受けません[5]。
公表翌日の7月19日にはPoCの公開が報じられ、さらに3日後の22日には積極的に悪用されている脆弱性として、KEVカタログにも掲載されました。
同じく22日にはIPAが注意喚起を行い[9]、23日にはJPCERT/CCのWeeklyReportでも取り上げられています[10]。
3. 観測結果概要
続いて、当社が運営しているハニーポットで観測された、wp2shellを狙ったと思われるパケットの観測結果をご紹介します。なお、当社のIoT家電ハニーポットでは、WordPressは稼働していません。
観測期間は脆弱性が公表された2026年7月18日0時0分から9月30日23時59分までの75日間です(全て日本時間)。本期間で観測したパケットのうち、HTTPのPOSTリクエストにbatch/v1、batch%2Fv1(スラッシュをURLエンコードしたバージョン)、Batch/v1(Bが大文字のバージョン)、Batch%2Fv1(大文字&エンコード有)の4種類いずれかの文字列が含まれているパケットの総数は119件でした。なお、本記事では、HTTPリクエスト1件を1パケットとして数えています。
これら119件について、観測件数の推移を以下の図に示します。
上図より、7月21日に最初のパケットが観測されていることがわかります。パケットを受信した正確な時刻は7月21日21時4分であり、これは、wp2shellがKEVに掲載された時刻(KEVカタログデータの更新時刻[8]より、日本時間7月22日0時12分)の約3時間前にあたります。
また、8月22日に、119件中78件のパケットが集中していました。さらに、9月25日・28日にも再び観測されています。
続いて、パケットの内容を分析した結果を下表に示します。
| 日付 | 件数 | 送信元の国 | 送信元IPの種類 | パターン |
|---|---|---|---|---|
| 7/21 | 1 | シンガポール | ホスティング | ① 同一リクエストの観測 |
| 8/9 | 1 | ブルガリア | ホスティング | ① 同一リクエストの観測 |
| 8/18 | 1 | 中国 | ホスティング | 中身が空のリクエスト |
| 8/20 | 1 | ブルガリア | ホスティング | ① 同一リクエストの観測 |
| 8/22 | 78 | アメリカ | ホスティング | ② 自動化ツール |
| 8/30 | 2 | ブルガリア | ホスティング | ① 同一リクエストの観測 |
| 9/25 | 14 | ブルガリア | ホスティング | ② 自動化ツール |
| 9/28 | 21 | オランダ | ホスティング | ② 自動化ツール |
HTTPリクエストの内容を確認すると、7月21日・8月9日・20日・30日に観測されたパケットは、リクエストのURLとボディが同一でした。そのため、パターン①と置きます。
また、8月22日の78件は送信元IPアドレスが全て同一であり、リクエストの挙動から①とは異なるパターンと考えました。9月25日・28日の計35件は、送信元IPアドレスこそ8月22日と異なるものの、リクエストの内容が8月22日のものと類似していました。そのため、これらをまとめてパターン②と置きます。
8月18日に観測された1件のパケットは、/?rest_route=/batch/v1宛てのPOSTリクエストで、User-Agentがwp2shell-rce/1.0と、wp2shellを悪用するRCE用ツールであると名乗るものでした。ただし、リクエストのボディは空のJSONで、パターン①・②のいずれにも該当しなかったため、本記事では詳しい分析を割愛いたします。
なお、今回観測した通信には、実際の悪用(リモートコード実行)につながるペイロードは含まれておらず、研究者やセキュリティベンダーによる脆弱性確認のスキャンが含まれている可能性があります。実際に、wp2shellを狙ったスキャンの中に、正当なセキュリティスキャンが含まれていたという報告もあります[11]。
ここからは、パターン①・②について、さらに掘り下げていきます。
4. パターン①:同一リクエストの観測
パターン①に該当するのは、7月21日・8月9日・20日・30日に観測された計5件のパケットです。これら5件は全て、/batch/v1宛てに送られていました。
POST /index.php?rest_route=/batch/v1 HTTP/1.1
リクエストのボディも5件全てで同一で、以下の内容でした(読みやすくするため整形しています)。
{
"requests": [
{ "method": "POST", "path": "http:///x" },
{
"body": {
"requests": [
{ "method": "GET", "path": "/wp/v2/posts" }
]
},
"method": "POST",
"path": "/wp/v2/posts/1"
},
{ "method": "POST", "path": "/batch/v1" }
]
}
このリクエストは、Batch APIのリクエストの中にさらに別のリクエストを入れ子にしたものです。1つ目の脆弱性であるCVE-2026-63030を悪用して、本来行われるはずの入力の検証(サニタイズ)を回避することを狙ったものとみられます。
入れ子の中身は投稿一覧の取得(GET /wp/v2/posts)という、通常は認証なしでも行える無害なリクエストです。また、GETリクエストはBatch APIでは指定できない仕様になっています[12]。以上より、このリクエストは、情報を盗むことが目的ではなく、本来は受け付けられないはずのGETが処理されるかどうか、つまり脆弱性の有無を確認するためのリクエストと考えられます。
また、8月9日に観測された1件のパケットでは、User-AgentがMozilla/5.0 (compatible; checker) wp2shell/CVE-2026-63030となっており、wp2shell(CVE-2026-63030)の確認用ツール(checker)を名乗る文字列が含まれていました。このことからも、パターン①はwp2shellの脆弱性の有無を確認するためのリクエストであると考えられます。
さらに、5件のパケットのうち8月9日・20日・30日に観測された4件は、IPv4アドレスの上位24ビットが同一で、国情報も全てブルガリアのため、同一の送信者が数日に分けてパケットを送信してきた可能性があります(ただし、ホスティング事業者などでは同じ/24のアドレス帯が複数の利用者に割り当てられている場合もあるため、断定はできません)。
5. パターン②:自動化ツールによる攻撃
パターン②に該当するのは、8月22日・9月25日・28日に観測された計113件のパケットです。送信元IPアドレスは日ごとに異なりますが、いずれもホスティングサービスのIPでした。
まずは、最も多くのリクエストが観測された8月22日の攻撃について、詳しく見ていきます。
8月22日の攻撃について、同じ送信元からの通信をパケットキャプチャで前後も含めて確認したところ、HTTPリクエストは計86件(POST 78件、GET 8件)あり、約30秒の間に次の3つのフェーズで進んでいました。
| フェーズ | 経過時間 | リクエスト数 | 内容 |
|---|---|---|---|
| 1 | 0~27秒 | POST 78件 | 入口(/batch/v1)の探索 |
| 2 | 27~29秒 | GET 6件 | WordPressかどうかの確認 |
| 3 | 29秒 | GET 2件 | SQLインジェクションが通るかの確認 |
攻撃自動化ツールの可能性
8月22日の攻撃は、上の表から読み取れる以下の2点から、人の手作業ではなく自動化されたツールによるものと考えられます。
- リクエストの速さ:86件のリクエストが約30秒の間に送られていました。特にフェーズ1では、78件のPOSTを約27秒で送っています。
- フェーズ間の切り替えが速い:フェーズ1からフェーズ3までが途切れることなく続き、フェーズ2・3は合計約2~3秒で終わっていました。人が応答を見て次の手を判断している場合では、さらに時間がかかるはずです。
ここから、各フェーズの詳細な内容をご紹介します。
フェーズ1:入口(/batch/v1)の探索
最初のフェーズでは、/batch/v1へのPOSTリクエストを、URLの書き方を変えながら繰り返し送っていました。使われていた書き方は以下の11種類です。
| No. | URL | 書き方の特徴 | POST件数 |
|---|---|---|---|
| 1 | /index.php?rest_route=/batch/v1 |
rest_routeを使う形(index.phpあり) |
7 |
| 2 | /index.php?rest_route=%2Fbatch%2Fv1 |
No.1のスラッシュを%2Fにエンコード |
7 |
| 3 | /?rest_route=%2Fbatch%2Fv1 |
rest_routeを使う形(index.phpなし)+エンコード |
7 |
| 4 | /?rest_route=/batch%2Fv1 |
一部のスラッシュだけをエンコード | 7 |
| 5 | /?rest_route=/batch/v1 |
rest_routeを使う形(index.phpなし) |
8 |
| 6 | /wp-json/batch/v1 |
wp-jsonを使う形(標準のURL) |
7 |
| 7 | /wp-json/Batch/v1 |
大文字・小文字の違い | 7 |
| 8 | //wp-json/batch/v1 |
スラッシュの重複 | 7 |
| 9 | /wp-json/batch/v1/ |
末尾のスラッシュ | 7 |
| 10 | /blog/wp-json/batch/v1 |
/blog/配下に設置されている場合 |
7 |
| 11 | /wordpress/wp-json/batch/v1 |
/wordpress/配下に設置されている場合 |
7 |
| 合計 | 78 |
最初に/?rest_route=/batch/v1を1回送ったあと、この11種類を同じ順番で7周(計77件)、約0.3秒間隔で送っていました。
WordPressのREST APIは/wp-json/~と?rest_route=~のどちらかをURLに指定することで利用できますが、/wp-json/~はパーマリンクが無効なサイトでは使えません[13]。そのため、設定に依存しない?rest_route=~の形もあわせて試していると考えられます。また、WordPressはサブディレクトリに設置されることもあるため[14]、/blog/や/wordpress/配下のURL(No.10、11)も試していると考えられます。
一方、エンコード(No.2〜4)、大文字・小文字の違い(No.7)、スラッシュの重複(No.8)、末尾のスラッシュ(No.9)のようなURLのバリエーションは、文字列の一致でブロックするWAFの検知をすり抜けるためと考えられます。実際にwp2shellについては、すぐにアップデートできない場合の暫定策として、/wp-json/batch/v1と?rest_route=/batch/v1をWAFでブロックする方法が紹介されています[6]。
また、リクエストのボディは全て{"requests":[]}という、中身が空のバッチリクエストでした。つまり、このフェーズではまだ攻撃は行っておらず、「入口があるかどうか」を応答から確認しているだけとみられます。
さらに、User-Agentは最初の6周がWebブラウザ(Chrome 120)を装ったもので、最後の1周だけWordPress/6.4.3に変わっていました。User-Agentを変えることで、応答が変わるかを確かめていた可能性があります。
フェーズ2:WordPressかどうかの確認
入口の探索が終わると、次はGETリクエストで以下のURLにアクセスしていました。
| No. | URL | アクセス先 |
|---|---|---|
| 1 | /wp/v2/posts/999999 |
REST APIの投稿取得 |
| 2 | /wp-login.php |
ログイン画面 |
| 3 | /feed/ |
フィード |
| 4 | /wp-json/ |
REST APIのトップ |
| 5 | / |
トップページ |
| 6 | /index.asp |
5のリダイレクト先 |
ログイン画面やREST APIのトップ、フィードなど、WordPress独自のURLにアクセスし、対象が本当にWordPressであるか、REST APIに到達できるかを確認していると考えられます。
ただし、No.1の/wp/v2/posts/999999は、本来のREST APIのURL(/wp-json/wp/v2/posts/<id>[15])とは異なり、先頭の部分が欠けていました。そのため、このリクエストは不完全であり、実際は通りません。
考えられる原因として、フェーズ1でハニーポットがBatch APIへのリクエスト11種類全てに401 Unauthorizedを返したことで、ツールがREST APIの入口を特定できず、不完全なURLのままフェーズ2に進んだ可能性があります。
なお、No.6の/index.aspは、ハニーポットがNo.5のトップページへのアクセスにリダイレクトを返したため、そのリダイレクト先にアクセスしたものとみられます。WordPressを狙ったURLではありません。
フェーズ3:SQLインジェクションが通るかの確認
最後のフェーズでは、CVE-2026-60137のSQLインジェクションが通るかを確認しようとしたとみられるリクエストを2件送っていました。
1件目は、投稿ID(999999)を指定したURLに、author_exclude・orderby・per_pageの3つのパラメータを付けたリクエストです。
GET /wp/v2/posts/999999?author_exclude=1&orderby=none&per_page=5
author_excludeは「指定した投稿者の投稿を除外する」ためのREST APIのパラメータで[15]、投稿一覧の取得(/wp-json/wp/v2/posts)で指定した場合に、WordPressの内部でCVE-2026-60137の脆弱性があるWP_Queryのauthor__not_inに渡されます。この1件目は、2件目の応答と比べるための基準となる、無害なリクエストと考えられます。
2件目は、同じauthor_excludeパラメータにSQL文を埋め込んだリクエストです。悪用を避けるため、SQL文の部分は省略して示します。
GET /wp/v2/posts/999999?author_exclude=1)[SQL文(省略)]&orderby=none&per_page=500
リクエストの詳細に関しては安全のため割愛しますが、1件目の応答を基準として、2件目の応答に違いが現れるかどうかで、SQLインジェクションが通るかどうかを確認しようとしているとみられます。
しかし、フェーズ3のリクエストは、通常のREST APIの処理では意図どおりに動きません。author_exclude・orderby・per_pageは投稿一覧の取得(/wp-json/wp/v2/posts)用のパラメータで[15]、投稿1件の取得用のURL(/posts/<id>)では使われません。また、投稿一覧の取得に送った場合でも、orderby=noneやper_page=500はREST APIの入力検証で拒否されます。
これらの値は、入力検証を経ずにWP_Queryへ直接渡れば受け付けられるものです。つまりフェーズ3は、CVE-2026-63030で入力検証を回避することを前提とした作りと考えられます。しかし、実際にはBatch APIを経由せずに直接送られていたため、脆弱なバージョンのWordPressに送られた場合でも、SQLインジェクションは成立しないと考えられます。このように、2章で示した攻撃チェーンの形になっていないことから、ツールの実装が不完全である可能性があります。
9月25日・28日の攻撃
9月25日・28日にも、8月22日と同じツールによるものとみられる通信を観測しました。送信元IPアドレスと国情報は8月22日とは異なりますが、以下の点が8月22日と一致していました。
- フェーズ1で試すURLの種類と、送る順番
- リクエストのボディ(
{"requests":[]})とUser-Agent
一方で、どちらの日も/batch/v1へのリクエストはフェーズ1の2周目の途中(9月25日は14件、28日は21件)で終わっており、フェーズ2・3のリクエストは観測されませんでした。
どちらの日も、送信件数は14件・21件と異なるものの(ネットワーク応答速度の違いが原因として考えられます)、最初のリクエストから約29秒で送信が止まっていました。また、8月22日の攻撃も約30秒で終了しています。件数ではなく時間で打ち切られていることから、ツールの処理全体に約30秒の時間制限がある可能性があり、9月25日・28日の攻撃はフェーズ1の途中で時間切れとなり、フェーズ2・3に進まなかったと推測されます。
6. まとめ
今回は、当社のハニーポットで観測された、wp2shellを狙ったと思われる通信について、分析結果をご紹介しました。
今回の観測で興味深かった点として、CVEの公表から4日足らずで、KEVへの掲載よりも前に、当社のハニーポットでもwp2shellを狙ったとみられる通信が観測されたこと、また攻撃の自動化が行われているとみられる点が挙げられます。さらに、WordPressが動作していない当社のIoT家電ハニーポットにもパケットが届いていることから、広範囲にスキャンを行いターゲットを探索している様子もうかがえます。
このように、CVE公表からスキャン観測までの期間は短く、また広範囲なターゲット探索がみられることから、脆弱性に対する迅速な対応や、APIエンドポイントのセキュリティ対策がより重要になってくると思われます。
当社では、引き続きハニーポットを用いた観測を行い、こちらで観測・分析結果をご紹介する予定です。
ご質問やコメントもお待ちしております。
参考文献
[1] WordPress.org, https://wordpress.org/
[2] NVD, "CVE-2026-63030 Detail", 2026年7月17日(現地時間), https://nvd.nist.gov/vuln/detail/CVE-2026-63030
[3] NVD, "CVE-2026-60137 Detail", 2026年7月17日(現地時間), https://nvd.nist.gov/vuln/detail/CVE-2026-60137
[4] セキュリティ対策Lab, 「WordPress 本体で危険度の高い脆弱性 wp2shell-サイバー攻撃への悪用が発生(CVE-2026-63030,CVE-2026-60137)」, 2026年7月19日, https://rocket-boys.co.jp/security-measures-lab/wordpress-core-webshell-wp2shell-alert/
[5] WordPress.org, "WordPress 7.0.2 リリース", 2026年7月18日, https://ja.wordpress.org/2026/07/18/wordpress-7-0-2-release/
[6] BleepingComputer, "WordPress Core "wp2shell" RCE flaws get public exploits, patch now", 2026年7月18日(現地時間), https://www.bleepingcomputer.com/news/security/wordpress-core-wp2shell-rce-flaws-get-public-exploits-patch-now/
[7] CISA, "CISA Adds Four Known Exploited Vulnerabilities to Catalog", 2026年7月21日(現地時間), https://www.cisa.gov/news-events/alerts/2026/07/21/cisa-adds-four-known-exploited-vulnerabilities-catalog
[8] CISA, "Known Exploited Vulnerabilities Catalog"(catalogVersion 2026.07.21), cisagov/kev-data, https://github.com/cisagov/kev-data/blob/bc9dbb256ec16f37b646b564770af99b0a96cbe1/known_exploited_vulnerabilities.json
[9] IPA, 「WordPressの脆弱性対策について(CVE-2026-60137、CVE-2026-63030:wp2shell)」, 2026年7月22日, https://www.ipa.go.jp/security/security-alert/2026/alert20260722.html
[10] JPCERT/CC, 「Weekly Report 2026-07-23号」, 2026年7月23日, https://www.jpcert.or.jp/wr/2026/wr260723.html
[11] Wiz, "Exploitation in the Wild of wp2shell", 2026年7月20日, https://www.wiz.io/blog/wp2shell-cve-2026-63030-cve-2026-60137
[12] Make WordPress Core, "REST API Batch Framework in WordPress 5.6", 2020年11月20日, https://make.wordpress.org/core/2020/11/20/rest-api-batch-framework-in-wordpress-5-6/
[13] WordPress Developer Resources, "Routes and Endpoints", https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/
[14] WordPress Developer Resources, "How to install WordPress", https://developer.wordpress.org/advanced-administration/before-install/howto-install/
[15] WordPress Developer Resources, "Posts", https://developer.wordpress.org/rest-api/reference/posts/

