- CVE-2024-YIKES एक ऐसी घटना है जिसमें JavaScript dependency compromise फैलकर Rust·Python supply chain तक पहुँच गया
left-justify phishing के जरिए .npmrc, .pypirc, Cargo·Gem credentials लीक हुए
vulpine-lz4 के malicious build.rs ने CI host पर shell script डाउनलोड कर चलाया
snekpack 3.7.0 malware लगभग 42 लाख डिवाइसों तक फैल गया और SSH key·reverse shell जोड़ दिए
- cryptobro-9000 worm ने संयोगवश
snekpack को 3.7.1 पर अपग्रेड कर दिया, जिससे malware हट गया
घटना का सार
- CVE-2024-YIKES एक security incident है जिसमें JavaScript ecosystem की compromised dependency credential theft तक पहुँची, और फिर Rust compression library supply chain attack तथा Python build tool malware distribution में बदल गई
- घटना 03:47 UTC पर दर्ज हुई, और इसकी स्थिति “संयोगवश हल”, severity “Critical → Catastrophic → Somehow Fine” में बदलती रही
- इसकी अवधि 73 घंटे रही, और प्रभावित systems की स्थिति “Yes” पर बनी रही
- compromised package और toolchain
left-justify, vulpine-lz4, snekpack तक पहुँचे, और लगभग 40 लाख developers तक malware वितरित हुआ
- अंत में एक अलग cryptocurrency mining worm
cryptobro-9000 ने infected machines पर update चलाया, जिससे snekpack normal version पर चला गया और malware संयोग से हट गया
घटना का क्रम
-
दिन 1: JavaScript package में credential theft शुरू
- 03:14 UTC पर
left-justify maintainer Marcus Chen ने Twitter पर लिखा कि उनका transit card, पुराना laptop, और “कुछ ऐसा जो Kubernetes ने उगलकर निकाला हो” चोरी हो गया, लेकिन इसे तुरंत package security issue से नहीं जोड़ा गया
- 09:22 UTC पर Chen ने nmp registry में login करने की कोशिश की और पाया कि उनकी hardware 2FA key गायब है; Google search result के सबसे ऊपर AI Overview ने 6 घंटे पहले registered phishing site
yubikey-official-store.net की ओर भेज दिया
- 09:31 UTC पर Chen ने उस phishing site में nmp credentials दर्ज किए, और site ने खरीद के लिए धन्यवाद देते हुए 3–5 business days में delivery का वादा किया
- 11:00 UTC पर
[email protected] को “performance improvements” changelog के साथ publish किया गया
- इस package में post-install script शामिल थी, जो
.npmrc, .pypirc, ~/.cargo/credentials, ~/.gem/credentials को attacker के चुने हुए server पर exfiltrate करती थी
- 13:15 UTC पर
left-justify के लिए “why is your SDK exfiltrating my .npmrc” शीर्षक से support ticket खोला गया, लेकिन उसे “low priority - user environment issue” चिह्नित कर दिया गया और 14 दिन तक कोई activity न होने पर auto-close हो गया
-
दिन 1: Rust library तक supply chain attack का फैलाव
- लीक हुए credentials में Rust library
vulpine-lz4 maintainer के credentials भी शामिल थे
vulpine-lz4 “blazingly fast Firefox-themed LZ4 decompression” के लिए library थी, GitHub पर केवल 12 stars थे, लेकिन यह cargo की transitive dependency थी
- 22:00 UTC पर
vulpine-lz4 0.4.1 publish हुआ, और commit message था “fix: resolve edge case in streaming decompression”
- असल बदलाव यह था कि एक
build.rs script जोड़ी गई, जो hostname में “build”, “ci”, “action”, “jenkins”, “travis”, या “karen” होने पर shell script डाउनलोड कर उसे execute करती थी
-
दिन 2: detection और response की विफलता
- 08:15 UTC पर security researcher Karen Oyelaran ने malicious commit का पता लगाया, जब payload उनके personal laptop पर चल पड़ा
- Karen Oyelaran ने “your build script downloads and runs a shell script from the internet?” शीर्षक से issue खोला, लेकिन कोई जवाब नहीं मिला
- असली maintainer EuroMillions में €2.3 million जीत चुके थे और Portugal में goat farm देख रहे थे
- 10:00 UTC पर Fortune 500 की
snekpack customer company के VP of Engineering को LinkedIn post “Is YOUR Company Affected by left-justify?” से घटना का पता चला; वे जानना चाहते थे कि उन्हें पहले क्यों शामिल नहीं किया गया, जबकि वास्तव में वे पहले से ही शामिल थे
- 10:47 UTC पर
#incident-response Slack channel 45-message thread में इस बहस में भटक गया कि “compromised” की American spelling में ‘z’ होना चाहिए या नहीं
-
दिन 2: Python build tool snekpack संक्रमित
- 12:33 UTC पर shell script ने
snekpack की CI pipeline को specific victim के रूप में target किया
snekpack एक Python build tool है, जिसका उपयोग उन PyPI packages में 60% करते हैं जिनके नाम में “data” आता है
snekpack ने “Rust is memory safe” कारण देकर vulpine-lz4 को vendor किया हुआ था
- 18:00 UTC पर
snekpack 3.7.0 release हुआ, और malware दुनिया भर की developer machines पर install होना शुरू हुआ
- malware ने
~/.ssh/authorized_keys में SSH key जोड़ी, केवल मंगलवार को सक्रिय होने वाला reverse shell install किया, और user का default shell fish में बदल दिया
- default shell को
fish में बदलना एक bug माना गया
- 19:45 UTC पर एक और security researcher ने “I found a supply chain attack and reported it to all the wrong people” शीर्षक से 14,000 शब्दों की blog post publish की, जिसमें “in this economy?” वाक्यांश 7 बार शामिल था
-
दिन 3: संयोगवश patch और घटना का अंत
- 01:17 UTC पर Auckland के एक junior developer ने अलग issue debug करते समय malware खोजा और
snekpack में vendor की गई vulpine-lz4 को revert करने के लिए PR खोला
- उस PR को 2 approvals चाहिए थे, लेकिन दोनों approvers सो रहे थे
- 02:00 UTC पर
left-justify maintainer को yubikey-official-store.net से YubiKey मिला, जो असल में 4-dollar USB drive था जिसमें “lol” लिखा README था
- 06:12 UTC पर एक अलग cryptocurrency mining worm
cryptobro-9000, jsonify-extreme vulnerability के जरिए फैलना शुरू हुआ
jsonify-extreme को “makes JSON even more JSON, now with nested comment support” package बताया गया
cryptobro-9000 का payload अपने आप में खास नहीं था, लेकिन उसके propagation logic में infected machine पर npm update और pip install --upgrade चलाना शामिल था ताकि future attack surface बढ़ सके
- 06:14 UTC पर
cryptobro-9000 ने संयोग से snekpack को 3.7.1 पर upgrade कर दिया
snekpack 3.7.1 एक वैध release था, जिसे एक confused co-maintainer ने publish किया था, और उसने vendor की गई vulpine-lz4 को पुराने version पर revert कर दिया
- 06:15 UTC पर मंगलवार वाला reverse shell सक्रिय हुआ, लेकिन command-and-control server
cryptobro-9000 द्वारा compromise हो चुका था, इसलिए जवाब नहीं दे सका
- 09:00 UTC पर
snekpack maintainers ने 4-वाक्यों की security advisory जारी की, जिसमें “out of an abundance of caution” और “no evidence of active exploitation” वाक्यांश शामिल थे
- “no evidence of active exploitation” तकनीकी रूप से सही माना गया, क्योंकि किसी ने evidence ढूंढा ही नहीं था
- 11:30 UTC पर एक developer ने ट्वीट किया, “I updated all my dependencies and now my terminal is in fish???” और उसे 47,000 likes मिले
- 14:00 UTC पर
vulpine-lz4 के compromised credentials बदल दिए गए
- असली maintainer को उनके नए goat farm पर email मिला, और उन्होंने जवाब दिया “मैंने दो साल से उस repository को छुआ नहीं है” तथा “मुझे लगा Cargo में 2FA optional है”
- 15:22 UTC पर incident resolved घोषित किया गया, और postmortem schedule तय होने के बाद तीन बार बदला गया
CVE आवंटन और नुकसान का पैमाना
- 6वें हफ्ते में CVE-2024-YIKES आधिकारिक रूप से assign किया गया
- advisory embargo में रही, क्योंकि MITRE और GitHub Security Advisories CWE classification पर बहस कर रहे थे
- CVE public होने तक Medium पर 3 posts और एक DEF CON talk पहले ही इस incident को detail में cover कर चुके थे
- कुल नुकसान अज्ञात ही रहा
- compromised machines की संख्या 42 लाख आंकी गई
- cryptocurrency worm द्वारा बचाई गई machines की संख्या भी 42 लाख आंकी गई
- net security posture में बदलाव “असुविधा” पर रहा
मूल कारण और योगदान देने वाले कारक
-
मूल कारण
- Kubernetes नाम के कुत्ते द्वारा YubiKey खा जाना मूल कारण माना गया
-
योगदान देने वाले कारक
- nmp registry अभी भी उन packages के लिए password-only authentication की अनुमति देती है जिनके weekly downloads 1 करोड़ से कम हैं
- Google AI Overviews ने पूरे आत्मविश्वास से ऐसे URL की ओर भेजा जिसे अस्तित्व में नहीं होना चाहिए था
- Rust ecosystem की “small crates” philosophy को npm ecosystem ने दोहराया, जिससे GitHub पर 3-star वाले
is-even-number-rs जैसे packages critical infrastructure की चार-स्तरीय transitive dependency बन सकते हैं
- Python build tools “performance” के नाम पर Rust libraries को vendor कर लेते हैं और फिर update नहीं करते
- Dependabot ने CI pass होने के बाद PR auto-merge किया, और CI इसलिए pass हुआ क्योंकि malware ने
volkswagen install कर दिया था
- cryptocurrency worm के पास ज़्यादातर startups से बेहतर CI/CD hygiene है
- कोई single owner नहीं था, लेकिन Dependabot PR को उस contractor ने approve किया जिसका उस शुक्रवार आखिरी working day था
- घटना वाले दिन मंगलवार था
सुधारात्मक कदम और बचे हुए विकल्प
- artifact signing लागू करना Q3 2022 incident का action item था, लेकिन अभी भी backlog में है
- mandatory 2FA पहले से required था, लेकिन इससे मदद नहीं मिली
- transitive dependency audit को target 847 items होने की वजह से काट दिया गया
- सभी dependency versions pin करने से security patches मिलना रुक जाता है
- dependency versions pin न करने से supply chain attack संभव हो जाता है
- Rust में rewrite करने का विकल्प
vulpine-lz4 की ओर इशारा करते हुए काट दिया गया
- बचे हुए विकल्पों में एक benevolent worm की उम्मीद करना या goat farm में career change पर विचार करना शामिल है
ग्राहक प्रभाव और संगठनात्मक प्रतिक्रिया
- कुछ customers ने “optimal न होने वाले security outcomes” का अनुभव किया हो सकता है
- प्रभावित stakeholders को स्थिति की visibility देने के लिए proactively संपर्क किया गया
- customer trust को “north star” बनाए रखा गया
- security posture की review के लिए cross-functional working group बनाया गया, लेकिन उसने अभी तक कोई meeting नहीं की
- legal review के बाद यह पंक्ति जोड़ी गई कि
fish shell malware नहीं है, हालांकि कभी-कभी ऐसा महसूस हो सकता है
- यह incident report उस quarter की तीसरी incident report है
- security team की headcount request Q1 2023 से backlog में पड़ी है
आभार
- Karen Oyelaran ने hostname के regex से match हो जाने की वजह से issue खोजा
- Auckland के junior developer द्वारा खोला गया PR incident resolve होने के 4 घंटे बाद approve हुआ
- कुछ security researchers ने issue पहले ढूंढ लिया, लेकिन गलत लोगों को report कर दिया
cryptobro-9000 के लेखक ने नाम सार्वजनिक नहीं करना चाहा, लेकिन अपनी SoundCloud का ज़िक्र करने को कहा
- Kubernetes नाम के कुत्ते ने टिप्पणी देने से इनकार किया
- security team ने सब कुछ होने के बावजूद इस report का SLA पूरा किया
1 टिप्पणियां
Hacker News की राय
जो लोग भ्रमित हो गए हों, उनके लिए बता दूँ: यह लेख supply chain incident पर आधारित काफ़ी अच्छी तरह लिखा गया fiction है
ऊपर-ऊपर पढ़ते समय मुझे यह सच लगा और मैं काफ़ी चिंतित हो गया, इसलिए और ध्यान से पढ़ने लगा :)
nmpउद्धृत हिस्से में “GitHub पर 12 stars वाला vulpine-lz4 cargo की अपनी transitive dependency है” वाली बात ने मुझे उत्सुक किया, तो मैंने मोटे तौर पर ऐसे crates की सूची निकाली जो cargo build में घुस सकते हैं और जिनमें पहले से
build.rsभी है, इसलिए कम नज़र आएँगे:flate2,tar,curl-sys,libgit2-sys,openssl-sys,libsqlite3-sys,blake3,libz-sys,zstd-sys,ccबोनस के तौर पर, अगर
xz2पर कब्ज़ा मिल जाए तो rustup को भी दूषित किया जा सकता हैफिर भी कम से कम वे
Cargo.lockको track तो करते हैं-syscrates तो सिर्फ bindings होते हैं, इसलिए वहाँ कुछ और हो रहा हो तो काफ़ी संदिग्ध लगेगाबाकी के बारे में मेरी समझ है कि वे
alexcrichtonजैसे Rust maintainers याrustlangखुद के स्वामित्व में हैंनिंदक बन जाना आसान है, क्योंकि बाद में देखने पर समस्या और समाधान बहुत साफ़ दिखते हैं
लेकिन लंबे समय तक, और शायद आज भी, hacker culture का मंत्र move fast and break things ही रहा है
npmजैसे supply chain systems की साफ़ समस्याओं को ठीक करने की दिशा में बढ़ती कोशिशें अच्छी बात हैं, लेकिन मुझे चिंता है कि हम agentic development से बड़े हिस्से में पैदा होने वाले नए security issues के दौर में प्रवेश कर रहे हैंबात सिर्फ यह नहीं कि Mythos/Glasswing जिन लगभग हर चीज़ को छूता है उनमें vulnerabilities उजागर हो जाती हैं, बल्कि यह भी है कि software बनाने, dependencies खींच लाने, और complex systems के बारे में इंसानी सोच के मॉडल को खो देने का हमारा तरीका बहुत सारा ऐसा जुगाड़ू software और infrastructure बनाएगा जिसे इंसान ठीक से समझता ही नहीं
उम्मीद है कुछ साल बाद आज को देखकर हमें यह पछतावा नहीं होगा कि हम इतने भोले कैसे थे, और हमने AI development की लंबी tail के लिए ठीक से तैयारी क्यों नहीं की, वह भी बिना इस तरह की समस्या-समाधान सोच के कि complex systems को AI से फिर से बना दिया जाए
फिर भी लेख मज़ेदार था
Fish के प्रशंसक के तौर पर, यह पंक्ति एक साथ हमला भी लगी और समझे जाने जैसा एहसास भी हुआ: “कृपया साफ़ करें कि fish shell malware नहीं है, बस कभी-कभी वैसा महसूस होता है”
shell से अलग, “security team में headcount बढ़ाने का अनुरोध 2023 की पहली तिमाही से backlog में पड़ा था” वाली बात भी बहुत जानी-पहचानी लगी
apt-getयाdnfसेfigletinstall करके/etc/motdकी सामग्री को विशाल ASCII art फ़ॉन्ट में all your base are belong to us से overwrite कर दिया जाएजिस हिस्से में left-justify maintainer को
yubikey-official-store.netसे YubiKey मिला, और वह असल में 4 डॉलर की USB drive निकली जिसकेREADMEमें “lol” लिखा था, वहाँ मैं सच में ज़ोर से हँसापूरा trollपन है
मुझे यह बात पसंद आई कि phishing site से आए USB device को plug in करना अपने आप में एक और attack vector है
यह सचमुच SCP नहीं था, लेकिन हाल में पढ़ी चीज़ों में सबसे ज़्यादा SCP जैसा यही लगा
Karen वाले हिस्से पर मैं ज़ोर से हँसा :D ;)
मुझे वह
makeआधारित build script याद आ गई जो मुझे कभी एक सहपाठी के project की समीक्षा करते समय मिली थी; अगर hostname मेंbpavukशामिल हो तो वह मेरे home folder परrm -rfचलाने की कोशिश करती थीवह तब की बात है जब मैं 7वीं कक्षा में था!!
Supply chain incidents वाकई सिरदर्द हैं और हमें इसमें बेहतर करना होगा
निजी तौर पर Rust में मैं इस पक्ष में हूँ कि foundation कुछ core crates को support करे ताकि वे Rust language के मुख्य हिस्से जैसी audit process से गुजरें, और supply chain vulnerabilities कम करने के लिए projects को funding मिले
मुझे नहीं लगता कि
cratesयाnpmजैसे systems को खत्म करना सही जवाब है।cratesऔरnpmबहुत से developers के लिए बहुत उपयोगी हैंcratesनेrustsecको शामिल करने की दिशा में प्रयास किए हैं, लेकिन उससे अलग मैं चाहूँगा कि community छोटी dependencies की बड़ी संख्या रखने के बजायtokioजैसी कम संख्या वाली बड़ी dependencies की ओर जाएcrates.ioपर सबसे लोकप्रिय crates में से काफ़ी सारे पहले से ही Rust organization द्वारा दिए गए first-party crates हैंRust crate graph को लेकर चिंता करते समय इस बात को अक्सर नज़रअंदाज़ कर दिया जाता है
crates.ioके पहले पेज पर top 10 downloads देखें, तो उनमें Rust organization या Rust core maintainers द्वारा न बनाया गया सिर्फbase64crate हैnpmऔरnmpदोनों की ज़रूरत है“आधिकारिक maintainer ने EuroMillions में 23 लाख euro जीत लिए हैं और अब Portugal में बकरी पालन के बारे में जानकारी ले रहे हैं”, और “root cause: Kubernets नाम के कुत्ते ने YubiKey खा ली”
आह, हाँ। उस क्लासिक मशहूर attack का शिकार होना, कितनी गैरज़िम्मेदारी है
वही पुराना तरीका जिसमें “lottery winnings से किसी को इतना व्यस्त कर दो कि दूसरे व्यक्ति के पालतू जानवर को dongle असहनीय रूप से स्वादिष्ट लगे”
लोग आख़िर कब सीखेंगे
अच्छा हुआ कि मैं
npmयाpipका इस्तेमाल नहीं करता, और recommended तरीकाcurl ... | bashही अपनाता हूँcurl | sudo bashहोता हैबिल्कुल amateur