- मार्च 2024 में मिला
xzbackdoor प्रभावितsshdenvironments में remote code execution तक ले जा सकता था, और NixOS का मामला दिखाता है कि reproducible builds supply chain में छेड़छाड़ को machine-driven तरीके से उजागर कर सकते हैं - malicious हिस्सा पूरे
xzGit repository में नहीं, बल्कि5.6.0·5.6.1के maintainer-provided release tarball में छिपा था, और build के दौरान नकली.xztest files से shell script और object file बनाता था - attack ने
glibcके ifunc का इस्तेमाल करliblzmaload होते समय code execute किया, और Debian·Fedora जैसी environments को target किया जहाँsshd,libsystemdके जरिएliblzmaपर transitive dependency रखता है - NixOS आम तौर पर GitHub के automatically generated source archives को prefer करता है, लेकिन
xznixpkgsके bootstrap चरण में होने के कारणautoconfdependency cycle से बचने के लिए maintainer tarball पर भरोसा करना पड़ा - सुझाया गया defense यह है कि bootstrap के बाद GitHub source से
xzको दोबारा build कर existing tarball artifacts से compare किया जाए; condition activate करते हीliblzma.soके size में फर्क और_get_cpuidsymbol जुड़ना सामने आया
xz backdoor कैसे छिपा था
xzcompression/decompression software है जिसका इस्तेमाल Linux distributions के core paths में source tarball extract करने के लिए अक्सर होता है- मार्च 2024 में
xzमें backdoor मिला, और malicious maintainer Jia Tan ने लगभग 3 साल में भरोसा हासिल कर repository push permission ली, फिर legitimate contributions के बीच obfuscated code थोड़ा-थोड़ा डालता गया - Andres Freund ने कई Debian unstable machines पर
sshमें आई 500ms performance degradation की जांच करते हुए trace कोliblzmaतक पहुंचाया, और backdoor की पहचान कर उसे document किया - backdoor का लक्ष्य
sshको hijack कर यह संभव बनाना था कि किसी खास RSA key से login होने पर attacker victim machine पर arbitrary commands execute कर सके
malicious tarball और build के दौरान बनने वाला object
- malicious components सीधे पूरे
xzGit repository code में मौजूद नहीं थे, बल्कि Jia Tan द्वारा build और sign करके distribute किए गएxz5.6.0 और 5.6.1 release tarballs में शामिल थे - Git repository के अंदर कुछ test
.xzfiles में machine code छिपा था, और release tarball में उसे बाहर निकालने के लिए disguised changes जोड़े गए थे - खास तौर पर
m4/build-to-host.m4में किया गया change ऊपर से harmless दिखता था और उसमें comments भी थे, लेकिन वास्तव में वह कई fake.xztest files को decrypt और de-obfuscate करने वाली command chain छिपाता था - इस process के दो outputs थे
xzbuild के दौरान चलने वाली shell script- malicious binary object file
- build के दौरान चलने वाली shell script दो भूमिकाएं निभाती है
- खास Linux distribution,
glibcfeatures,sshinstallation status आदि backdoor execution conditions check करती है - normal object
liblzma_la-crc64_fast.oको modify करती है ताकि वह backdoor object file के_get_cpuidsymbol का इस्तेमाल करे
- खास Linux distribution,
- Russ Cox का
xzscript analysis build के दौरान malicious resources बनने की प्रक्रिया को विस्तार से कवर करता है
sshd तक पहुंचने वाला ifunc hijacking
- dynamic linking program में runtime पर dynamic loader shared libraries को memory में load करता है, और symbol addresses को Global Offset Table(GOT) में भरता है
glibcका ifunc dynamic loading के समय एक ही function की कई implementations में से एक चुनने की सुविधा है, औरxzbackdoor ने इसे malicious code execution path के रूप में इस्तेमाल किया- Debian·Fedora आदि कुछ distributions में
ssh,systemdnotification support के लिएlibsystemdसे linked होता है, औरlibsystemdफिरliblzmaसे linked होता है- इस environment में
sshd,liblzmaपर transitive dependency रखता है
- इस environment में
sshdrun होते समय dynamic loaderlibsystemdऔरliblzmaको load करता है, और backdoor installed होने परliblzmaloading के दौरान malicious code execute होता है- backdoor ifunc resolver से malicious
_get_cpuidsymbol call करवाता है, और अभी read-only न बने GOT को manipulate करRSA_public_decryptaddress को malicious function में बदल देता है - Securelist का detailed analysis और attack vector व mitigations को summarize करने वाला research article reference material के तौर पर देखा जा सकता है
भरोसेमंद source और NixOS की bootstrap constraints
- कई distributions ने Git forge के original source के बजाय maintainer-provided tarball से
xzbuild किया, इसलिए यह attack प्रभावी हो सका - tarball workflow के historical और practical कारण हैं
- यह शुरुआती Linux distributions की वह पद्धति है जो
gitसे भी पुरानी है - release समय की source state को self-contained archive के रूप में सुरक्षित रखता है
- manpage, configure script जैसे intermediate artifacts शामिल कर build burden घटा सकता है
- compression से storage efficiency मिलती है
- यह शुरुआती Linux distributions की वह पद्धति है जो
- security के नजरिए से, जब technically संभव हो, तो सबसे भरोसेमंद entity द्वारा authenticated source से build करना चाहिए
- अगर project GitHub पर develop होता है, तो GitHub द्वारा हर release के लिए automatically generated archive इस्तेमाल किया जा सकता है
- यही logic Codeberg, SourceHut, GitLab जैसे trusted third-party platforms पर भी लागू किया जा सकता है
- NixOS functional package management model इस्तेमाल करता है, और packages Nix expressions के रूप में build recipes define करते हैं
- NixOS maintainers में जहां संभव हो
fetchFromGitHubके जरिए GitHub automatically generated source archive इस्तेमाल करने की culture है, लेकिनxzpackagefetchurlसे manually uploaded maintainer tarball fetch कर रहा था - वजह यह है कि
xznixpkgsके bootstrap चरण में शामिल है- bootstrap वह process है जिससे छोटे seed binary set से पूरे
nixpkgspackage set को फिर से build किया जा सकता है stdenvवह default compilation environment है जिसे दूसरे packages इस्तेमाल करते हैंstdenvruntime मेंxzपर depend करता है, औरcoreutilsजैसे packages को.tar.xzsource archives extract करने के लिएxzचाहिए
- bootstrap वह process है जिससे छोटे seed binary set से पूरे
- GitHub source से
xzbuild करने के लिए configure script बनाने वालाautoconfचाहिए, लेकिनautoconfभीxzपर depend करता है- maintainer-provided tarball में configure script पहले से generated होती है, इसलिए यह dependency cycle टूट सकता है
- इसलिए
nixpkgsgraph में जिस point परxzbuild होता है, वहां GitHub source archive इस्तेमाल करना कठिन था और maintainer tarball पर भरोसा करना पड़ा
source comparison से ज्यादा artifact convergence comparison
- maintainer tarball और GitHub source tarball identical हैं या नहीं, यह compare करना natural लगता है, लेकिन practice में यह ठीक फिट नहीं बैठता
- Daniel Stenberg ने समझाया कि release tarball का source से अलग होना एक feature है
- tarball में manpage, configure script जैसे intermediate artifacts शामिल किए जा सकते हैं
- खासकर तब उपयोगी है जब distributions
autoconfdependency से बचना चाहें
- supply chain security के नजरिए से यह flexibility maintainer की ईमानदारी पर भरोसा करने के बोझ में बदल जाती है
- reproducible builds का मतलब है कि समान conditions में दो बार build करने पर bit-for-bit identical artifacts मिलें
- reproducible-builds group का लक्ष्य जितने अधिक packages संभव हों उन्हें reproducible बनाना है, और Reproducible Builds: Increasing the Integrity of Software Supply Chains इसे binary artifacts distribution में trust बढ़ाने वाली property के रूप में देखता है
- tarball creation को ही reproducible बनाने वाला approach PostgreSQL project ने adopt किया
- users independently verify कर सकते हैं कि maintainer tarball original source से honestly generated हुआ है या नहीं
- हालांकि इसे upstream project maintainer को implement करना होता है, इसलिए FOSS community में adoption धीमा हो सकता है
NixOS में प्रस्तावित detection procedure
- अगर
xzbit-for-bit reproducible है और maintainer tarball में build process को प्रभावित करने वाला change नहीं है, तो GitHub tarball build और maintainer tarball build को समान artifacts देने चाहिए - प्रस्तावित method यह है कि
xzको bootstrap के बाद एक बार फिर build किया जाए, लेकिन इस बारfetchFromGitHubसे GitHub source archive इस्तेमाल किया जाए और इसे existing bootstrap-stagexzartifacts से compare किया जाए - implementation example में
pkgs/tools/compression/xzके नीचेafter-bootstrap.nixरखा गया औरxz5.6.1 को GitHub source से build किया गया- maintainer tarball में configure script पहले से मौजूद है, लेकिन GitHub source build में
autoconf,libtool,automakeआदि का इस्तेमाल कर./autogen.shचलाना पड़ता है
- maintainer tarball में configure script पहले से मौजूद है, लेकिन GitHub source build में
- comparison step के रूप में
compareArtifactsजोड़ा गया ताकि build के अंत मेंliblzma.socompare हो- example में केवल backdoor द्वारा modify की गई file
liblzma.socompare की गई, लेकिन इसे सभी binary और library artifacts तक generalize किया जा सकता है
- example में केवल backdoor द्वारा modify की गई file
- normal master revision में
xz-after-bootstrapbuild सफल हुआ और दोनों artifacts identical थे - backdoor वाले revision
c53bbe3में शुरुआत में वे identical दिखे- NixOS में backdoor activate नहीं हुआ था, और इसका एक कारण installation script द्वारा
RPM_ARCHvariable setting check करना था - condition activate करने के लिए
env.RPM_ARCH = true;set करने परliblzma.sobinary difference सामने आया
- NixOS में backdoor activate नहीं हुआ था, और इसका एक कारण installation script द्वारा
- दोनों
liblzma.sosave कर compare करने पर backdoor-included artifact 258KB था, जबकि bootstrap के बाद GitHub source build artifact 210KB था, यानी लगभग 48KB का फर्क था nmसे symbols compare करने पर_cpuid,_get_cpuid,__tls_get_addr@GLIBC_2.3जोड़े हुए मिले, और_get_cpuidकईxzbackdoor technical reports में documented symbol है
लागू करने के तरीके और सीमाएं
- प्रस्तावित protection उन सभी packages पर लागू करने की है जो bootstrap stage में build होते हैं और trusted source archive इस्तेमाल नहीं करते
- अगर
*-after-bootstrappackages को channel blocker में जोड़ा जाए, तो build failure को ऐसा बड़ा alert बनाया जा सकता है जिसमें maintainer intervention चाहिए xzcase के proof of concept के तौर परnixpkgsrepository में pull request खुली- इस method के लिए assumption चाहिए कि target package bit-for-bit reproducible है
- 2017 से 2023 तक
nixpkgs-unstablerevisions में से 17 samples लेकरstdenvके non-fixed-output derivations कोnix-build --checkसे rebuild किया गया - सभी revisions में
xzbit-for-bit reproducible था - 17 में से 12 revisions में 1–2 packages ऐसे थे जो build तो हो सकते थे लेकिन reproducible नहीं थे; उदाहरण के लिए
gcc2017–2021 तक, औरbash2019 तक लगातार non-reproducible थे
- 2017 से 2023 तक
- यह method सभी
stdenvpackages पर लागू नहीं किया जा सकता, लेकिन long term में अच्छी reproducibility वाले packages पर selectively activate किया जा सकता है - Ken Thompson की trusting trust problem इस method की theoretical limitation बनी रहती है
- यह assumption चाहिए कि bootstrap stage का untrusted
xz,xz-after-bootstrapbuild को indirectly contaminate करके artifacts identical दिखा नहीं सकता - ऐसा attack बहुत complex हो सकता है, लेकिन method खुद इसी assumption पर आधारित है
- यह assumption चाहिए कि bootstrap stage का untrusted
- यह detection method तभी detect करता है जब tarball change final artifact को प्रभावित करे
- NixOS executables में backdoor शामिल नहीं था, इसलिए अगर condition अलग से activate नहीं की गई होती तो इस case का backdoor नहीं मिला होता
1 टिप्पणियां
Hacker News टिप्पणियां
यह बात ध्यान देने लायक है कि NixOS और reproducible builds xz backdoor को detect नहीं कर पाए। असल में NixOS ने भी malicious xz build अपने users तक पहुंचाया था, बस malware ने NixOS को target नहीं किया था इसलिए वह चला नहीं।
NixOS developer ने भी कहा था, “जब backdoor सार्वजनिक हुआ तो यह जानकर हैरानी हुई कि xz का malicious version हमारे users को distribute हुआ था।” हमेशा की तरह theory और reality अलग होती हैं, और xz को संभव बनाने वाली चीज़ technical vulnerability से ज़्यादा real world की human vulnerability थी। Community अक्सर यह मानने में असहज रहती है कि ऐसी समस्याओं को सिर्फ बेहतर software से हमेशा patch नहीं किया जा सकता
अगर हर process को सीमित permissions के साथ चलाया जा सके, और काम के लिए जरूरी directories को छोड़कर
~/तक भी access न मिले, तो उदाहरण के लिए कोई maliciouspippackage SSH keys चुराने से रोका जा सकता है। फिर भी मुझे लगता है कि xz backdoor के NixOS पर न चलने की वजह NixOS की अनोखी non-FHS filesystem structure थीआजकल अगर actual reality, objective reality को लेकर किसी व्यक्ति की feelings या values से मेल नहीं खाती, तो उसे अक्सर नीचा दिखाया जाता है। मेरी personal values हैं, लेकिन मैं actual reality को उसके बारे में अपनी feelings से कम महत्वपूर्ण नहीं मानता। जैसा मैं अक्सर कहता था, theory और reality में फर्क यह है कि theory में दोनों समान होते हैं, लेकिन reality में नहीं। उम्मीद है कि यह एहसास कि NixOS के reproducible builds xz attack पकड़ सकते थे लेकिन पकड़ नहीं पाए, आगे ऐसे builds का analysis करके दूसरे attacks को जल्दी खोजने की दिशा में progress बनाएगा
लगता है लेखक का नजरिया इस बार संयोग से जिस तरीके से घटना हुई, उसी तक बहुत सीमित हो गया है। Jia Tan incident का sample सिर्फ एक है, इसलिए यह मान लेना कि सिर्फ वही तरीका संभव है, short-sighted है।
यहां propose की गई defense जिन scenarios में काम नहीं करेगी, ऐसे कई cases आसानी से imagine किए जा सकते हैं। Nix user होने के नाते भी मुझे लगता है कि NixOS के इसे पकड़ने की संभावना कम थी। असल में उसने पकड़ा भी नहीं। अभी मैंने कहा कि अगली बार यह अलग तरीके से हो सकता है, लेकिन बिना evidence के Nix पर भरोसा करना भी बेवकूफी है
यहां NixOS ज्यादा relevant नहीं है। xz backdoor ने खास तौर पर Red Hat और Debian को target किया था।
उसी logic से यह कहना भी लगभग उतना ही relevant है कि xz backdoor ने Windows को affect नहीं किया। Ironically, यह backdoor अंत में Microsoft employee ने discover किया था, जो बात अक्सर नजरअंदाज हो जाती है
लेख कहता है कि distributions को traditional installation tarball के बजाय version control system, जैसे Github, से सीधे source code लेना चाहिए।
लेकिन यह क्या solve करता है, समझ नहीं आता। कोई malicious maintainer binary blob को सीधे source code repository में add कर सकता है, है न? लेखक Github को ऐसा भरोसेमंद मानता है जैसे वह code verify करता हो, जबकि जाहिर है Github ऐसी verification नहीं करता
verified reproducible builds xz utils compromise, SolarWinds Orion tampering जैसे मामलों को रोकने में मदद कर सकते थे, और यह करने लायक काम है
अगर आप Github release से binary download करके चलाते हैं, तो maintainer पर पूरी तरह भरोसा करने के अलावा कोई रास्ता नहीं। Nix ऐसा सिर्फ closed source packages के लिए करता है
Argument इस तथ्य पर टिका है कि XZ maintainer ने malicious code को ऐसे tarball में छिपाया था जो Git में check in नहीं था।
लेखक दिखाता है कि Nix को Git से tarball generate करके binary build में डालने के लिए configure किया जा सकता है। लेकिन समझ नहीं आता कि यह Nix या NixOS की जरूरत वाली functionality क्यों है। RPM या Deb में जाने वाली चीजों समेत कोई भी build system intermediate step के रूप में tarball generate करने के लिए configure किया जा सकता है। असल में Debian लंबे समय से reproducible builds को एक महत्वपूर्ण लक्ष्य मानकर काम कर रहा है। https://wiki.debian.org/ReproducibleBuilds
पहला, NixOS build process में xz bootstrap की शुरुआत में इतना जल्दी चाहिए था कि xz का full source build किया ही नहीं जा सकता था। दूसरा, bootstrap की शुरुआत में जरूरी nixpkgs dependencies compromise हुई हैं या नहीं, इसे automatically detect करने के लिए nixpkgs adjustments propose किए गए हैं। दूसरे ecosystems भी निश्चित रूप से full source build try करके mismatch ढूंढ सकते हैं। लेख का core point यह है कि current nixpkgs ऐसा नहीं कर सकता
अगर NixOS जिस case को रोक सकता था उस पर focus करना है, तो CrowdStrike incident देखना चाहिए। आज की configuration काम न करे तो कल की configuration से boot कर पाना ही ज्यादातर damage mitigate कर देता
भरोसेमंद framework इस्तेमाल करें तो वह framework जब तक attack नहीं होता, तब तक आप सुरक्षित रहते हैं। xz backdoor शायद पकड़ा गया हो, लेकिन उसे Nix ecosystem में चलाने के उद्देश्य से design नहीं किया गया था
कभी न कभी अगर Nix का कोई core developer spy निकला या वैसी ही स्थिति बनी, तो Nix ecosystem को target करने वाले attacks भी आएंगे। उम्मीद है कि कोई यह जवाब नहीं देगा कि Nix मूल रूप से सुरक्षित है। अगर 1–2 साल के भीतर Nix पर सफल attack हो जाता है, तो इतना मन करेगा कि जाकर उनसे कहलवाऊं कि वे गलत थे
ज़्यादा मजबूत दावा यह है कि “Nix पर हमला करना traditional build systems की तुलना में ज्यादा कठिन और महंगा है।” इसलिए अगर आपको Nix पर सस्ते में attack करने का तरीका मिल जाए, तब आना। तब तक, technical स्तर पर यह कहना कम-से-कम plausible है, और वास्तव में बहुत संभव भी है, कि Nix alternative systems की तुलना में attack करना कठिन बनाता है
NixOS थोड़ा आगे जरूर है, लेकिन अधिकांश दूसरे distributions भी सब कुछ source से compile करते हैं, इस्तेमाल किए जा रहे source में tampering नहीं हुई है यह cryptographically verify करते हैं, और packages के बीच version-pinned dependencies रखते हैं। Debian के पास भी reproducible builds हैं
समस्या यह थी कि build system ने source से build करने से पहले precompiled object files को हटाया नहीं। उसे ठीक कर देने पर भी, अगर कोई source code inspect नहीं करता, तो आप जितने चाहें उतने backdoors जोड़ सकते हैं, और NixOS हो या कोई और distribution, इसे रोक नहीं सकता
शानदार technical analysis है, लेकिन title गलत है और भ्रम पैदा करता है। भले ही कहा जा सके कि “technically सही है”, अच्छे से अच्छे अर्थ में भी यह backdoor लगाए जाने के मतलब के करीब है
यह अच्छी तरह दिखाता है कि union filesystem layers से आगे जाने वाले build manager tools की जरूरत है। उदाहरण के लिए, tests build artifacts को contaminate न कर सकें, इसके लिए tracking और enforcement होनी चाहिए। build process में कोई file किस file को प्रभावित करती है, इसका causal tracking graph बनाना, उस graph को explicit बनाना, और फिर उसे enforce करना या पिछले tracking graph से अंतर report करना—ऐसा तरीका चाहिए
सही। backdoor छिपाना निश्चित रूप से ज्यादा कठिन हो गया होता। लेकिन यह असंभव से काफी दूर है
चाहें तो source code के अंदर backdoor कभी भी छिपाया जा सकता है। बस उसे एक plausible bug जैसा दिखाने में ज्यादा मेहनत लगेगी, और detect होने की संभावना भी ज्यादा होगी