- GPT5.6 Sol Ultra ने नवीनतम stable WordPress का विश्लेषण करके pre-auth SQL injection से admin account creation और remote code execution (RCE) तक जाने वाली attack chain को लगभग 10 घंटे में पूरा कर लिया
- शुरुआत WordPress 5.6 से उपलब्ध Batch API के array index mismatch से हुई, जिसमें recursive Batch requests को जोड़कर GET restriction और parameter validation को bypass किया गया
- बिना validate की गई
author_excludestring से UNION injection कराया गया, फिर manipulated post को memory cache में डालकर oEmbed cache·changeset·circular reference·hook का क्रमिक दुरुपयोग किया गया customize_changesetकेuser_id: 1से अस्थायी admin privilege हासिल की गई,parse_requesthook से Batch request को दोबारा चलाकर नया admin बनाया गया, फिर backdoor plugin ZIP upload करके code execution तक पहुँचा गया- 200 डॉलर प्रति माह subscription के साप्ताहिक उपयोग का 50% अनुपातिक रूप से गिनने पर लागत लगभग 25 डॉलर रही, और इंसानी भूमिका product व attack surface चुनने तथा prompt tuning जैसे उच्च-स्तरीय research direction की ओर खिसक सकती है
खोज की प्रक्रिया और प्रयोग की शर्तें
- OpenAI ने Cycle Double Cover conjecture को हल करने में उपयोग किया था, ऐसा बताया गया prompt, उसे security research के लिए संशोधित करके GPT5.6 Sol Ultra को दिया गया
- नवीनतम stable WordPress को
main/में clone किया गया और.gitdirectory हटा दी गई, साथ ही dependent code की जाँच के लिए खालीthird_party/directory तैयार की गई - Prompt में अधिकतम 4 agents को parallel चलाकर कम-से-कम 6 घंटे तक विभिन्न attack paths बनाए रखने का निर्देश था
- input parsing, character set, file upload, error handling, built-in paths, serialization, cache, race condition, crypto, type, mass assignment आदि की जाँच की गई
- approach families को register किया गया और जब agents किसी खास strategy पर ज़्यादा केंद्रित हो गए तो उन्हें कम explore किए गए क्षेत्रों में फिर से तैनात किया गया
- specific bugs को adversarial agents ने re-validate किया, और असफल paths को भी नया mechanism मिलने पर फिर से खोला गया
- Change history, patch versions से अंतर, या internet clues का उपयोग किए बिना source code itself से नया vulnerability खोजने तक सीमित रखा गया
- अवास्तविक settings या ऐसे preconditions से बचने के लिए जिन्हें attacker पूरा न कर सके, लक्ष्य को “MySQL का उपयोग करने वाली सामान्य production deployment में pre-auth RCE” के रूप में स्पष्ट किया गया
- लगभग 6 घंटे बाद model ने pre-auth SQL injection खोज ली, और default WordPress remote server पर कुछ ही मिनटों में admin email निकालकर उसे reproduce किया गया
- RCE तक escalation के लिए अतिरिक्त अनुरोध देने पर लगभग 4 घंटे बाद, password cracking या offline computation के बिना read-only SQL injection से admin privilege तक जाने वाली chain पूरी कर ली गई
- कुल काम का समय 10 घंटे से थोड़ा अधिक रहा और साप्ताहिक उपयोग का 50% खर्च हुआ. 200 डॉलर मासिक subscription fee के अनुपातिक हिसाब से लागत लगभग 25 डॉलर थी
- Public disclosure से पहले weekend के दौरान operator को WordPress upgrade करने का समय दिया गया, और इस बीच Calif तथा Hacktron ने GitHub की अन्य PoC से पहले पूरी chain को स्वतंत्र रूप से reproduce कर लिया
- चल रहे instances की vulnerability की जाँच wp2shell.com पर की जा सकती है
Batch API में validation mismatch
- WordPress 5.6 में जोड़ी गई Batch API एक request में कई virtual API requests को process करती है. Endpoint स्वयं authentication के बिना access किया जा सकता है, लेकिन हर sub-request को authentication information पास की जाती है
- सामान्य REST request निम्न क्रम में process होती है
has_valid_params()से required values और validity की जाँच होती हैsanitize_params()से values को sanitize किया जाता है- permission callback चलाया जाता है
- endpoint callback चलाया जाता है
- Performance के लिए Batch API validation और execution को दो loops में अलग करती है
- पहले loop में सभी requests को validate और sanitize किया जाता है
- दूसरे loop में validation result देखकर permission और endpoint callbacks चलाए जाते हैं
- Implementation यह मानकर चलती है कि route matching result
$matchesऔर validation result$validationमें एक ही index आपस में correspond करते हैं - अगर malformed request
is_wp_error($single_request)branch में चली जाए तो$validationमें item जोड़ दिया जाता है, लेकिनcontinueकी वजह से$matchesमें नहीं जोड़ा जाता- इसके बाद सभी
$matchesitems एक slot खिसक जाते हैं - एक request के parameters को दूसरी request के नियमों से validate करने के बाद उसे मूल इरादे से अलग endpoint handler में चलाया जा सकता है
- इसके बाद सभी
- इस index mismatch का उपयोग करके ऐसे दूसरे endpoint का validation result, जो parameters को sanitize नहीं करता, Batch-supported endpoint पर लागू किया जा सकता है
author__not_in में होने वाला SQL injection
GET /wp/v2/postsपरिणाम से कुछ authors को बाहर रखने के लिए internal query variableauthor__not_inका उपयोग करता है- यदि value array हो तो हर element पर
absintलागू करके उसे integer बनाया जाता है, लेकिन scalar value होने पर उसे वैसे हीimplodeकरके SQL केNOT INclause में डाल दिया जाता है - सामान्य call में public parameter
author_excludeinteger array होना चाहिए, इसलिए समस्या सामने नहीं आती - Batch index mismatch का उपयोग करके string
author_excludeको उसे न पहचानने वालेDELETE /wp/v2/posts/1नियमों से validate कराया जा सकता है और फिरGET /wp/v2/postsतक पहुँचाया जा सकता है - Batch API में GET sub-request की अनुमति न होने वाली सीमा को भी recursive Batch calls से bypass किया गया
- बाहरी Batch में index mismatch पैदा करके अंदरूनी request की
methodvalidation skip कराई गई - अंदरूनी Batch में फिर index mismatch पैदा करके
author_excludevalidation bypass की गई
- बाहरी Batch में index mismatch पैदा करके अंदरूनी request की
0) OR 1=1 --जैसी value देने पर सभी post rows लौट आती हैं, जिससे injection की पुष्टि होती है- इसके बाद UNION-based injection से
wp_postsजैसी shape वाली rows बनाकर मनचाहे database values leak कराई जा सकती हैं - Passwords, reset tokens, API keys आदि database में hash रूप में रहते हैं, इसलिए जब तक admin password कमज़ोर न हो, केवल data leak से account takeover तक पहुँचना आसान नहीं होता
request के भीतर post cache manipulation
- WordPress एक ही request के भीतर बार-बार refer होने वाले
WP_Postobjects को memory cache में रखता है ताकि database round-trip कम हों - UNION injection से fake post rows लौटाई जाएँ तो post ID, type, status, parent relation, body आदि कई fields attacker के चुने हुए रूप में cache में डाली जा सकती हैं
- API response में भी post body पर post-processing होती है, इसलिए manipulated body से अतिरिक्त code paths चलाए जा सकते हैं
- यह cache request समाप्त होते ही गायब हो जाती है और fake posts database में मौजूद नहीं होते, इसलिए केवल cache manipulation से requests के बीच persistence नहीं मिलती
oEmbed cache से database row बनाना
- WordPress की embeds feature post body के
[embed]...[/embed]syntax के ज़रिए supported remote content embed करती है - हर बार HTTP request भेजने से बचने के लिए result को
wp_postsमेंoembed_cachetype post के रूप में database में store किया जाता है - Relative path के जरिए local WordPress post को embed करने पर HTTP request छोड़ी जाती है, और referenced post ID वास्तव में मौजूद है या नहीं, इसकी जाँच नहीं होती
/?p=10जैसे non-existent local post को embed करने पर भी उस data के लिएoembed_cacherow बनाई जा सकती है- बनी हुई row को फिर SQL injection से query करते समय memory में post type को
postआदि में manipulate किया जाए तो database और cache की representations अलग हो जाती हैं - WordPress इन दोनों representations को reconcile करते समय
wp_update_post()को call करता है, और explicitly दिए गएIDतथाpost_contentके अलावा अन्य fields के लिए attacker द्वारा बनाए गए memory values को प्राथमिकता देता है - इसके चलते
oembed_cacherow को सामान्य post में बदला जा सकता है, लेकिन इस call मेंpost_contentembed result से overwrite हो जाता है, इसलिए attacker body तक control नहीं कर पाता
customize_changeset के जरिए अस्थायी admin privilege
- Theme customization work के draft
wp_postsमेंcustomize_changesettype की special posts के रूप में store होते हैं post_contentमें setting key के हिसाब से changed values, type, और बदलाव करने वाले user ID का JSON रहता है- Changeset लागू करते समय WordPress हर item का
user_idपढ़करwp_set_current_user()से current user को अस्थायी रूप से बदल देता है - यदि attacker
user_id: 1वाला changeset लागू करा दे, तो anonymous request के दौरान भी थोड़ी देर के लिए admin identity इस्तेमाल की जा सकती है - पहले वाला oEmbed reconcile call
post_contentको overwrite कर देता है, इसलिए malicious changeset JSON को बनाए रखने के लिए अलगwp_update_post()call path की ज़रूरत होती है
post parent cycle से body सुरक्षित रखना
- WordPress post का एक parent हो सकता है, लेकिन खुद को या अपने child post को parent बनाने वाली circular structure की अनुमति नहीं है
wp_insert_post_parentfilter parent hierarchy को follow करके cycle जाँचता है, और cycle मिलने पर उस post केpost_parentको 0 में बदलने के लिएwp_update_post()call करता है- इस दूसरे call में केवल
IDऔरpost_parentदिए जाते हैं,post_contentoverwrite नहीं होता - SQL injection से memory वाले post को खुद को parent रखने वाले
customize_changesetके रूप में तैयार किया जाए, तो cycle repair process में attacker-निर्धारित malicious changeset JSON database में लिखा जाता है - यदि पुरानी date और
futurestatus वाला changeset बनाया जाए तो WordPress उसे apply करता है, औरuser_id: 1के अनुसार admin privilege के साथ तय settings changes कर देता है - Admin privilege केवल changeset processing के दौरान रहती है; उसके बाद फिर guest privilege पर लौट आता है
dynamic hook से पूरी request दोबारा चलाना
- WordPress hooks action और filter में बँटे होते हैं, और plugins को login, publish, script registration जैसी lifecycle points पर intervene करने देते हैं
- Post status बदलने पर WordPress
"{$new_status}_{$post->post_type}"रूप का dynamic action चलाता है- सामान्य post के लिए यह
publish_postजैसा नाम बनता है - Memory में fake post की status और type मनचाहे तय किए जा सकते हैं, इसलिए एक या अधिक underscores वाले इच्छित action name बनाए जा सकते हैं
- सामान्य post के लिए यह
- Hook arguments attacker द्वारा तय post ID और
WP_Postobject तक सीमित होते हैं, इसलिए मनमाने action को सीधे उपयोगी ढंग से call करना आसान नहीं है - Attack chain status को
parseऔर type कोrequestमें manipulate करकेparse_requesthook को trigger करती है parse_requestrequest lifecycle के शुरुआती हिस्से में चलने वाला hook है, इसलिए इसे फिर से call करने पर मूल Batch API request पूरी तरह शुरुआत से re-process होती है- यह re-processing changeset द्वारा सेट की गई अस्थायी admin identity के बने रहने के दौरान होती है, इसलिए पहली execution में permission की कमी से fail हुई admin-only request दूसरी execution में सफल हो जाती है
दो requests में पूरी होने वाली RCE chain
- अंतिम exploit दो HTTP requests का उपयोग करता है और fake posts को इतने बड़े IDs दिए जाते हैं कि वे वास्तविक posts से टकराएँ नहीं
-
पहली request: persistent rows की तैयारी
- SQL injection से तीन local embeds वाले fake post को लौटाकर
O,C,Dके अनुरूप 3oembed_cacherows बनाई जाती हैं - तीनों embeds एक ही post
Sको point करते हैं, लेकिन अलग query strings का उपयोग करके अलग oEmbed cache hashes बनाते हैं
- SQL injection से तीन local embeds वाले fake post को लौटाकर
-
दूसरी request: छह posts की assembly
- Memory cache में निम्न छह fake posts तैयार किए जाते हैं
O: status/typepublish/oembed_cacheऔर parentCवाला पुराना cacheC: status/typefuture/customize_changeset, स्वयं को parent रखने वाला, और malicious changeset JSON समाहित किए हुएP: parentDवालाdraft/pageD: status/typeparse/request, स्वयं को parent रखने वालाS: embed data देने वालाpublish/postT: बाहरी embed रखने वालाpublish/postTका embedOको query करता है, और पुराना modified time होने के कारणSका cache refresh करवाता हैOrefresh के दौरान parentCकी cycle detect होने परCका parent 0 में बदला जाता है, और memory वालाcustomize_changesetतथा malicious JSON database में लिखा जाता है- पुरानी date वाला
futurechangeset apply हो जाता है औरuser_id: 1की admin identity के साथPको publish कर देता है Pupdate में parentDकी cycle मिलती है, जिससेDलिखा जाता है और manipulated status व type के साथparse_requestaction trigger होता है- Batch request में शुरू से ही new admin creation request शामिल रहती है
- पहली processing में guest privilege होने के कारण यह fail हो जाती है
parse_requestसे दोबारा execution होने पर अस्थायी admin privilege अभी भी मौजूद रहती है, इसलिए यह सफल हो जाती है- नए admin account से login करने के बाद backdoor plugin ZIP upload की जाए तो अंततः remote code execution हासिल हो जाता है
AI security research में बदलती भूमिकाएँ
- पूरी chain में खास तौर पर creative steps थे: recursive Batch call से GET restriction bypass करना, cache और changeset को मिलाकर admin privilege पाना, और fake post से
parse_requestcall करके request को re-execute करना - सामान्य श्रेष्ठता का निष्कर्ष निकालना कठिन है, लेकिन आकलन यह है कि AI के बिना कोई security researcher वही chain 10 घंटे के भीतर खोज और पूरा नहीं कर पाता
- भले ही मूल Batch bug पहले से दे दिया जाए, तब भी उस समय के भीतर RCE तक पहुँचना संभव होता या नहीं, इस पर भरोसा नहीं जताया गया
- अलग-अलग code gadgets खोजकर उन्हें एक chain में जोड़ने की क्षमता में GPT5.6 Sol Ultra, पुराने GPT5.5 की तुलना में काफी आगे बढ़ा हुआ माना गया
- जैसे-जैसे model technical exploit development का अधिक हिस्सा संभालेगा, इंसान की भूमिका इस बात पर केंद्रित होगी कि कौन-सा product और attack surface चुना जाए, कितना समय लगाया जाए, research direction क्या हो, और model भटके तो उसे कैसे सुधारा जाए
- ऐसी meta-research capability अभी AI अच्छी तरह नहीं संभाल पाता, और model की technical क्षमता जितनी बढ़ेगी, यह उतनी ही महत्वपूर्ण होती जाएगी
1 टिप्पणियां
Hacker News राय
इस बात का कोई आधार नहीं है कि ऐसे exploit के लिए 5 लाख डॉलर दिए गए हैं या दिए जाएंगे। लेख में कहा गया है कि prompt को बाइबल की तरह सावधानी से edit किया जाता है, तो बेहतर होगा कि वही prompt 5 लाख डॉलर में बेच दें
लेखक automated scanning AI product देने वाली https://www.assetnote.io/ में काम करते हैं
ऐसे brokers आम तौर पर बड़ी रकम एकमुश्त नहीं देते; वे nation-state actors को access बेचते हैं और जब तक bug patch नहीं होता, किस्तों में भुगतान करते हैं। यह structure resale या जल्दी burn हो जाने से रोकने के लिए होता है, इसलिए किसी मिलती-जुलती vulnerability के लिए वाकई पूरी रकम मिली या नहीं, इसकी पुष्टि करने वाला शायद ही कोई मिलेगा
सबसे नज़दीकी उदाहरण Florida के वे किशोर हैं जो Steam games में malware डालकर accounts चुरा रहे थे और पकड़े गए। वे वैसे भी पकड़े जाते, लेकिन अगर social media पर शेखी न बघारते तो जांच में कहीं ज़्यादा समय लगता
https://github.com/WordPress/WordPress/commit/3a640e1c5e39aa... को देखें तो 2026 में भी string-concatenation SQL injection दिख रहा है
SQL सीधे चलाने के बजाय
dbDeltaइस्तेमाल करने को कहते हैं, लेकिन हर field को अलग line में रखना,PRIMARY KEYके बीच दो spaces डालना,INDEXकी जगहKEYइस्तेमाल करना जैसी बेहद नखरीली formatting rules मांगते हैं। field names में quotes या backticks नहीं होने चाहिए, data types lowercase में, SQL keywords uppercase में होने चाहिए, और length parameters भी सभी specify करने होते हैंsprintfसे SQL queries बनाता हैPOSTऔरGETrequests में/wp/v2/widgets?author_exclude=1%29+AND+1%3D0+UNION+ALL+SELECT...जैसा payload शामिल थाPrincipal Software Engineer @ Bluehost,WordPress Core Committerलिखा है, लेकिन ऐसे code के साथ ‘principal’ शब्द सच में अजीब लगता हैFOMO-style writing से थक चुका हूं। यह सिर्फ 25 डॉलर में नहीं मिला; इसके पीछे domain expertise थी कि कहां देखना है और कैसे explore करना है, और कई सालों से जमा किया हुआ material था
जुए जैसी narrative और यह illusion फैलाना बंद करना चाहिए कि हर कोई मौका गंवा रहा है
चौंकाने वाली बात already-known vulnerability की ऊंची कीमत है, और यह सच न भी हो सकता है। WordPress को अक्सर blog feature के साथ remote root shell कहा जाता है
यह समझ आता है कि आम user से GitHub repository में commit कराकर Hugo से build कराने की तुलना में drag-and-drop समझाना आसान है। लेकिन security के लिहाज से यह ऐसी structure है जो बस core या हजारों plugins में से किसी एक में vulnerability आने और remote code execution as a service खुलने का इंतज़ार करती है
लेख दिलचस्प है, और LLM-based exploit discovery and disclosure वाकई चिंता की बात है। मैंने Linux local privilege escalation vulnerability से container escape code model से अपेक्षाकृत जल्दी बनवाया भी है
हालांकि यह हैरानी की बात है कि GPT-5.6 ने safeguards के कारण prompt block नहीं किया। GPT-5.5 और उससे ऊपर Opus 4.7+/Fable की तरह offensive security work से कतराते हैं, इसलिए लगता है कि लेखक को OpenAI से safeguards ढीले करने वाली cybersecurity approval मिली हो सकती है
2020 से पहले के non-AI Static Application Security Testing (SAST) टूल भी ऐसी SQL injection बहुत पकड़ लेते थे, और कम-से-कम code review में तो यह मिलना चाहिए था। सवाल है कि WordPress code review या SAST इस्तेमाल नहीं करता क्या
मेरी एक website इस vulnerability से hack हो गई, लेकिन अच्छी बात यह थी कि वहाँ कोई users नहीं थे
attacker ने database में दो admin accounts बनाए, और
wp-content/plugins/wp-coreमेंwp-core-[कोई भी 12 अक्षर].phpremote command execution web shell install किया।mu-pluginsमेंGET ?sergeiसे admin बनाने वालाfirewall.phpbackdoor रखा,cache-seo-helper.phpbackdoor भी जोड़ा, औरfixer.phpसे WordPress version number को patched version जैसा बदल दिया। आखिरकार मैंने WordPress इस्तेमाल छोड़ने का फैसला कियालेख के अंत में posts को अजीब नामों से बुलाना शुरू हो गया, जिससे समझना मुश्किल हो गया। एक ID को
O, दूसरी को0बनाने, औरEMBED_01याABCDEFकी जगह एक single character और random जैसे दिखने वालेOCPDSTका इस्तेमाल करने की वजह समझ नहीं आईOका मतलबpublish/oembed_cache,Cकाfuture/customize_changeset,Pकाdraft/page,Dकाparse/request,Sका embed data देने वालाpublish/post, औरTका external embed रखने वालाpublish/postहैक्या यह मानकर चला जा रहा है कि जो लोग 5 लाख डॉलर देंगे, उनमें GPT-5.6 को खुद इस्तेमाल करने की क्षमता नहीं होगी?
मैं भी LLM से security vulnerabilities ढूँढता हूँ, लेकिन result को ज्यों-का-त्यों submit करके काम खत्म नहीं कर सकता; हालांकि ऐसा करने की कोशिश करने वाले लोग बहुत हैं
GPT-5.6 Sol superhuman है या नहीं, यह कोई simple हाँ/नहीं वाला सवाल नहीं है। Computers दशकों पहले ही chess में इंसानों से आगे निकल गए थे, और यह लेख देखकर लगता है कि अब code understanding में भी इंसानों से आगे निकल गए हैं