1 पॉइंट द्वारा GN⁺ 2025-03-24 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • मार्च 2024 में मिला xz backdoor प्रभावित sshd environments में remote code execution तक ले जा सकता था, और NixOS का मामला दिखाता है कि reproducible builds supply chain में छेड़छाड़ को machine-driven तरीके से उजागर कर सकते हैं
  • malicious हिस्सा पूरे xz Git repository में नहीं, बल्कि 5.6.0·5.6.1 के maintainer-provided release tarball में छिपा था, और build के दौरान नकली .xz test files से shell script और object file बनाता था
  • attack ने glibc के ifunc का इस्तेमाल कर liblzma load होते समय code execute किया, और Debian·Fedora जैसी environments को target किया जहाँ sshd, libsystemd के जरिए liblzma पर transitive dependency रखता है
  • NixOS आम तौर पर GitHub के automatically generated source archives को prefer करता है, लेकिन xz nixpkgs के bootstrap चरण में होने के कारण autoconf dependency cycle से बचने के लिए maintainer tarball पर भरोसा करना पड़ा
  • सुझाया गया defense यह है कि bootstrap के बाद GitHub source से xz को दोबारा build कर existing tarball artifacts से compare किया जाए; condition activate करते ही liblzma.so के size में फर्क और _get_cpuid symbol जुड़ना सामने आया

xz backdoor कैसे छिपा था

  • xz compression/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 सीधे पूरे xz Git repository code में मौजूद नहीं थे, बल्कि Jia Tan द्वारा build और sign करके distribute किए गए xz 5.6.0 और 5.6.1 release tarballs में शामिल थे
  • Git repository के अंदर कुछ test .xz files में machine code छिपा था, और release tarball में उसे बाहर निकालने के लिए disguised changes जोड़े गए थे
  • खास तौर पर m4/build-to-host.m4 में किया गया change ऊपर से harmless दिखता था और उसमें comments भी थे, लेकिन वास्तव में वह कई fake .xz test files को decrypt और de-obfuscate करने वाली command chain छिपाता था
  • इस process के दो outputs थे
    • xz build के दौरान चलने वाली shell script
    • malicious binary object file
  • build के दौरान चलने वाली shell script दो भूमिकाएं निभाती है
    • खास Linux distribution, glibc features, ssh installation status आदि backdoor execution conditions check करती है
    • normal object liblzma_la-crc64_fast.o को modify करती है ताकि वह backdoor object file के _get_cpuid symbol का इस्तेमाल करे
  • Russ Cox का xz script 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 में से एक चुनने की सुविधा है, और xz backdoor ने इसे malicious code execution path के रूप में इस्तेमाल किया
  • Debian·Fedora आदि कुछ distributions में ssh, systemd notification support के लिए libsystemd से linked होता है, और libsystemd फिर liblzma से linked होता है
    • इस environment में sshd, liblzma पर transitive dependency रखता है
  • sshd run होते समय dynamic loader libsystemd और liblzma को load करता है, और backdoor installed होने पर liblzma loading के दौरान malicious code execute होता है
  • backdoor ifunc resolver से malicious _get_cpuid symbol call करवाता है, और अभी read-only न बने GOT को manipulate कर RSA_public_decrypt address को 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 से xz build किया, इसलिए यह attack प्रभावी हो सका
  • tarball workflow के historical और practical कारण हैं
    • यह शुरुआती Linux distributions की वह पद्धति है जो git से भी पुरानी है
    • release समय की source state को self-contained archive के रूप में सुरक्षित रखता है
    • manpage, configure script जैसे intermediate artifacts शामिल कर build burden घटा सकता है
    • compression से storage efficiency मिलती है
  • 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 है, लेकिन xz package fetchurl से manually uploaded maintainer tarball fetch कर रहा था
  • वजह यह है कि xz nixpkgs के bootstrap चरण में शामिल है
    • bootstrap वह process है जिससे छोटे seed binary set से पूरे nixpkgs package set को फिर से build किया जा सकता है
    • stdenv वह default compilation environment है जिसे दूसरे packages इस्तेमाल करते हैं
    • stdenv runtime में xz पर depend करता है, और coreutils जैसे packages को .tar.xz source archives extract करने के लिए xz चाहिए
  • GitHub source से xz build करने के लिए configure script बनाने वाला autoconf चाहिए, लेकिन autoconf भी xz पर depend करता है
    • maintainer-provided tarball में configure script पहले से generated होती है, इसलिए यह dependency cycle टूट सकता है
    • इसलिए nixpkgs graph में जिस point पर xz build होता है, वहां 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 autoconf dependency से बचना चाहें
  • 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

  • अगर xz bit-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-stage xz artifacts से compare किया जाए
  • implementation example में pkgs/tools/compression/xz के नीचे after-bootstrap.nix रखा गया और xz 5.6.1 को GitHub source से build किया गया
    • maintainer tarball में configure script पहले से मौजूद है, लेकिन GitHub source build में autoconf, libtool, automake आदि का इस्तेमाल कर ./autogen.sh चलाना पड़ता है
  • comparison step के रूप में compareArtifacts जोड़ा गया ताकि build के अंत में liblzma.so compare हो
    • example में केवल backdoor द्वारा modify की गई file liblzma.so compare की गई, लेकिन इसे सभी binary और library artifacts तक generalize किया जा सकता है
  • normal master revision में xz-after-bootstrap build सफल हुआ और दोनों artifacts identical थे
  • backdoor वाले revision c53bbe3 में शुरुआत में वे identical दिखे
    • NixOS में backdoor activate नहीं हुआ था, और इसका एक कारण installation script द्वारा RPM_ARCH variable setting check करना था
    • condition activate करने के लिए env.RPM_ARCH = true; set करने पर liblzma.so binary difference सामने आया
  • दोनों liblzma.so save कर 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 कई xz backdoor technical reports में documented symbol है

लागू करने के तरीके और सीमाएं

  • प्रस्तावित protection उन सभी packages पर लागू करने की है जो bootstrap stage में build होते हैं और trusted source archive इस्तेमाल नहीं करते
  • अगर *-after-bootstrap packages को channel blocker में जोड़ा जाए, तो build failure को ऐसा बड़ा alert बनाया जा सकता है जिसमें maintainer intervention चाहिए
  • xz case के proof of concept के तौर पर nixpkgs repository में pull request खुली
  • इस method के लिए assumption चाहिए कि target package bit-for-bit reproducible है
    • 2017 से 2023 तक nixpkgs-unstable revisions में से 17 samples लेकर stdenv के non-fixed-output derivations को nix-build --check से rebuild किया गया
    • सभी revisions में xz bit-for-bit reproducible था
    • 17 में से 12 revisions में 1–2 packages ऐसे थे जो build तो हो सकते थे लेकिन reproducible नहीं थे; उदाहरण के लिए gcc 2017–2021 तक, और bash 2019 तक लगातार non-reproducible थे
  • यह method सभी stdenv packages पर लागू नहीं किया जा सकता, लेकिन long term में अच्छी reproducibility वाले packages पर selectively activate किया जा सकता है
  • Ken Thompson की trusting trust problem इस method की theoretical limitation बनी रहती है
    • यह assumption चाहिए कि bootstrap stage का untrusted xz, xz-after-bootstrap build को indirectly contaminate करके artifacts identical दिखा नहीं सकता
    • ऐसा attack बहुत complex हो सकता है, लेकिन method खुद इसी assumption पर आधारित है
  • यह detection method तभी detect करता है जब tarball change final artifact को प्रभावित करे
    • NixOS executables में backdoor शामिल नहीं था, इसलिए अगर condition अलग से activate नहीं की गई होती तो इस case का backdoor नहीं मिला होता

1 टिप्पणियां

 
GN⁺ 2025-03-24
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 नहीं किया जा सकता

    • Nix का declarative configuration कई तरीकों से attack defense बढ़ाने में काफी उपयोगी है, लेकिन इसमें अभी बहुत-सी अप्रयुक्त संभावनाएं हैं। व्यक्तिगत रूप से मैं fine-grained one-shot containers को सबसे पहले implement करना चाहूंगा, और Guix में ऐसी functionality पहले से है।
      अगर हर process को सीमित permissions के साथ चलाया जा सके, और काम के लिए जरूरी directories को छोड़कर ~/ तक भी access न मिले, तो उदाहरण के लिए कोई malicious pip package SSH keys चुराने से रोका जा सकता है। फिर भी मुझे लगता है कि xz backdoor के NixOS पर न चलने की वजह NixOS की अनोखी non-FHS filesystem structure थी
    • फिर भी यह लेख अच्छा था। NixOS source code से अलग build artifacts—यानी non-reproducible artifacts—को रोकने का technical solution सामने रखता है, और xz backdoor ठीक build artifact के अंदर छिपा था
    • सही। Title देखकर लगा कि Nix approach ने शायद backdoor detect किया हो, लेकिन असल में लेख ज्यादा इस बारे में है कि Nix को कैसे बदला जाए ताकि ऐसे backdoor detect किए जा सकें
    • यह बात highlight करने के लिए अच्छा लगा कि reproducible builds ने दूसरे discovery paths से पहले xz backdoor को सच में नहीं पकड़ा था।
      आजकल अगर actual reality, objective reality को लेकर किसी व्यक्ति की feelings या values से मेल नहीं खाती, तो उसे अक्सर नीचा दिखाया जाता है। मेरी personal values हैं, लेकिन मैं actual reality को उसके बारे में अपनी feelings से कम महत्वपूर्ण नहीं मानता। जैसा मैं अक्सर कहता था, theory और reality में फर्क यह है कि theory में दोनों समान होते हैं, लेकिन reality में नहीं। उम्मीद है कि यह एहसास कि NixOS के reproducible builds xz attack पकड़ सकते थे लेकिन पकड़ नहीं पाए, आगे ऐसे builds का analysis करके दूसरे attacks को जल्दी खोजने की दिशा में progress बनाएगा
    • वजह थोड़ी मजेदार है। NixOS bootstrap source code download करता है, और वह source xz से compressed tarball होता है
  • लगता है लेखक का नजरिया इस बार संयोग से जिस तरीके से घटना हुई, उसी तक बहुत सीमित हो गया है। 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 किया था, जो बात अक्सर नजरअंदाज हो जाती है

    • थोड़ा बेहतर NixOS या Guix होता तो यह backdoor repository में आते ही automatically पकड़ लिया जाता। इसलिए यह relevant है
  • लेख कहता है कि distributions को traditional installation tarball के बजाय version control system, जैसे Github, से सीधे source code लेना चाहिए।
    लेकिन यह क्या solve करता है, समझ नहीं आता। कोई malicious maintainer binary blob को सीधे source code repository में add कर सकता है, है न? लेखक Github को ऐसा भरोसेमंद मानता है जैसे वह code verify करता हो, जबकि जाहिर है Github ऐसी verification नहीं करता

    • यह approach उस समस्या को solve करता है कि “जिसकी review हुई” और “software build में इस्तेमाल हुआ source code” अक्सर अलग होते हैं।
      verified reproducible builds xz utils compromise, SolarWinds Orion tampering जैसे मामलों को रोकने में मदद कर सकते थे, और यह करने लायक काम है
    • वह criticism थोड़ा सही नहीं बैठता। Source से build करने पर आप और बाकी सभी लोग source inspect कर सकते हैं, लेकिन provided tarball से build करने पर autoconf process files बदल देता है, इसलिए यह original source की तुलना में मूल रूप से अलग हो जाता है।
      अगर आप 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

    • लेख वाकई “Leveraging bitwise reproducibility” section में reproducible-builds project को cite करता है। इस लेख का point दो बातें हैं।
      पहला, 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 कर देता

    • हालांकि वह boot flexibility न होने वाली Windows side की समस्या है। Ubuntu भी ZFS पर ऐसा कर सकता है
  • भरोसेमंद framework इस्तेमाल करें तो वह framework जब तक attack नहीं होता, तब तक आप सुरक्षित रहते हैं। xz backdoor शायद पकड़ा गया हो, लेकिन उसे Nix ecosystem में चलाने के उद्देश्य से design नहीं किया गया था
    कभी न कभी अगर Nix का कोई core developer spy निकला या वैसी ही स्थिति बनी, तो Nix ecosystem को target करने वाले attacks भी आएंगे। उम्मीद है कि कोई यह जवाब नहीं देगा कि Nix मूल रूप से सुरक्षित है। अगर 1–2 साल के भीतर Nix पर सफल attack हो जाता है, तो इतना मन करेगा कि जाकर उनसे कहलवाऊं कि वे गलत थे

    • कसौटी पहले भी और आगे भी पूर्ण सुरक्षा नहीं है। वह ऐसी असंभव कसौटी है जिसे कोई भी चीज़ पूरा नहीं कर सकती। फिर भी यह objectively सच है कि आज का software कुल मिलाकर 30 साल पहले की तुलना में ज़्यादा सुरक्षित है
      ज़्यादा मजबूत दावा यह है कि “Nix पर हमला करना traditional build systems की तुलना में ज्यादा कठिन और महंगा है।” इसलिए अगर आपको Nix पर सस्ते में attack करने का तरीका मिल जाए, तब आना। तब तक, technical स्तर पर यह कहना कम-से-कम plausible है, और वास्तव में बहुत संभव भी है, कि Nix alternative systems की तुलना में attack करना कठिन बनाता है
    • backdoor Nix को target करके नहीं बनाया गया था, लेकिन expose न होने के लिए Nix में build होते समय भी उसे शक पैदा नहीं करना था
  • 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 होने की संभावना भी ज्यादा होगी