TL; DR
Kerentanan shellshock sepenuhnya diperbaiki di
- Di cabang bash-2.05b: 2.05b.10 dan lebih tinggi (termasuk 10 patch)
- Di cabang bash-3.0: 3.0.19 dan lebih tinggi (tambalan 19 termasuk)
- Di cabang bash-3.1: 3.1.20 dan di atasnya (termasuk 20 patch)
- Di cabang bash-3.2: 3.2.54 dan yang lebih tinggi (termasuk patch 54)
- Di cabang bash-4.0: 4.0.41 dan lebih tinggi (termasuk patch 41)
- Di cabang bash-4.1: 4.1.14 dan lebih tinggi (tambalan 14 termasuk)
- Di cabang bash-4.2: 4.2.50 dan lebih tinggi (termasuk 50 patch)
- Di cabang bash-4.3: 4.3.27 ke atas (tambalan 27 termasuk)
Jika bash Anda menunjukkan versi yang lebih lama, vendor OS Anda mungkin masih menambalnya sendiri, jadi yang terbaik adalah memeriksa.
Jika:
env xx='() { echo vulnerable; }' bash -c xx
menunjukkan "rentan", Anda masih rentan. Itu adalah satu-satunya tes yang relevan (apakah parser bash masih terkena kode dalam variabel lingkungan apa pun ).
Detail
Bug itu dalam pelaksanaan awal fungsi mengekspor / mengimpor diperkenalkan pada 5 th Agustus 1989 oleh Brian Fox, dan pertama kali dirilis di bash-1.03 sekitar sebulan kemudian pada waktu di mana pesta itu tidak digunakan secara luas seperti itu, sebelum keamanan adalah bahwa banyak perhatian dan HTTP dan web atau Linux bahkan ada.
Dari ChangeLog di 1,05 :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Beberapa diskusi di gnu.bash.bug dan comp.unix.questions sekitar waktu itu juga menyebutkan fitur.
Sangat mudah untuk memahami bagaimana sampai di sana.
bash mengekspor fungsi dalam env vars seperti
foo=() {
code
}
Dan pada impor, yang harus dilakukan adalah menafsirkan bahwa dengan =
diganti dengan spasi ... kecuali bahwa itu tidak boleh menafsirkannya secara membabi buta.
Itu juga rusak di dalam bash
(bertentangan dengan Bourne shell), variabel skalar dan fungsi memiliki ruang nama yang berbeda. Sebenarnya kalau sudah
foo() { echo bar; }; export -f foo
export foo=bar
bash
akan dengan senang hati menempatkan keduanya di lingkungan (ya entri dengan nama variabel yang sama) tetapi banyak alat (termasuk banyak shell) tidak akan menyebarkannya.
Satu juga akan berpendapat bahwa bash harus menggunakan BASH_
awalan namespace untuk itu karena itu hanya relevan dari bash ke bash. rc
menggunakan fn_
awalan untuk fitur serupa.
Cara yang lebih baik untuk mengimplementasikannya adalah dengan meletakkan definisi dari semua variabel yang diekspor dalam variabel seperti:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Itu masih perlu disanitasi tapi setidaknya itu tidak bisa lebih dieksploitasi daripada $BASH_ENV
atau $SHELLOPTS
...
Ada tambalan yang mencegah bash
menafsirkan apa pun selain definisi fungsi di sana ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), dan itulah yang memiliki telah diterapkan di semua pembaruan keamanan dari berbagai distribusi Linux.
Namun, bash masih menginterpretasikan kode di sana dan bug apa pun di juru bisa dieksploitasi. Satu bug seperti itu telah ditemukan (CVE-2014-7169) meskipun dampaknya jauh lebih kecil. Jadi akan ada tambalan lain segera hadir.
Sampai perbaikan pengerasan yang mencegah bash untuk menafsirkan kode dalam variabel apa pun (seperti menggunakan BASH_FUNCDEFS
pendekatan di atas), kami tidak akan tahu pasti apakah kami tidak rentan terhadap bug di parser bash. Dan saya percaya akan ada perbaikan pengerasan yang dirilis cepat atau lambat.
Edit 2014-09-28
Dua bug tambahan di parser telah ditemukan (CVE-2014-718 {6,7}) (perhatikan bahwa sebagian besar shell pasti memiliki bug di parser mereka untuk kasus sudut, yang tidak akan menjadi masalah jika parser itu tidak telah terpapar ke data yang tidak dipercaya).
Sementara semua 3 bug 7169, 7186 dan 7187 telah diperbaiki dalam tambalan berikut, Red Hat mendorong untuk memperbaiki pengerasan. Dalam tambalan mereka, mereka mengubah perilaku sehingga fungsi diekspor dalam variabel yang BASH_FUNC_myfunc()
lebih atau kurang mendahului keputusan desain Chet.
Chet kemudian menerbitkan perbaikan itu sebagai bash patch upstreams resmi .
Patch pengerasan itu, atau varian dari itu sekarang tersedia untuk sebagian besar distribusi Linux utama dan akhirnya berhasil ke Apple OS / X.
Yang sekarang menyumbat keprihatinan untuk segala env var sewenang-wenang mengeksploitasi parser melalui vektor itu termasuk dua kerentanan lain dalam parser (CVE-2014-627 {7,8}) yang diungkapkan kemudian oleh Michał Zalewski (CVE-2014-6278 hampir seburuk CVE-2014-6271) untungnya setelah kebanyakan orang punya waktu untuk menginstal tambalan pengerasan
Bug di parser akan diperbaiki juga, tetapi mereka tidak lagi menjadi masalah sekarang karena parser tidak lagi begitu mudah terkena input yang tidak dipercaya.
Perhatikan bahwa meskipun kerentanan keamanan telah diperbaiki, kemungkinan kami akan melihat beberapa perubahan di area itu. Perbaikan awal untuk CVE-2014-6271 telah rusak kompatibilitas dalam hal itu berhenti fungsi mengimpor dengan .
atau :
atau /
di nama mereka. Itu masih bisa dideklarasikan oleh bash yang membuat perilaku tidak konsisten. Karena fungsi dengan .
dan :
namanya biasa digunakan, kemungkinan tambalan akan mengembalikan penerimaan setidaknya dari lingkungan.
Kenapa tidak ditemukan sebelumnya?
Itu juga sesuatu yang saya ingin tahu. Saya bisa memberikan beberapa penjelasan.
Pertama, saya berpikir bahwa jika seorang peneliti keamanan (dan saya bukan seorang peneliti keamanan profesional) secara khusus mencari kerentanan dalam bash, mereka mungkin akan menemukannya.
Misalnya, jika saya seorang peneliti keamanan, pendekatan saya bisa:
- Lihat dari mana
bash
mendapat input dan apa fungsinya. Dan lingkungannya jelas.
- Lihat di tempat mana
bash
penerjemah dipanggil dan pada data apa. Sekali lagi, itu akan menonjol.
- Mengimpor fungsi yang diekspor adalah salah satu fitur yang dinonaktifkan ketika
bash
adalah setuid / setgid, yang membuatnya menjadi tempat yang lebih jelas untuk melihat.
Sekarang, saya curiga tidak ada yang berpikir untuk menganggap bash
(penerjemah) sebagai ancaman, atau bahwa ancaman itu bisa datang dengan cara itu.
The bash
interpreter tidak dimaksudkan untuk memproses masukan yang tidak dipercaya.
Skrip Shell (bukan penerjemah) sering dilihat dari sudut pandang keamanan. Sintaksis shell sangat canggung dan ada begitu banyak peringatan dengan penulisan skrip yang dapat diandalkan (pernah melihat saya atau yang lain menyebut operator split + glob atau mengapa Anda harus mengutip variabel misalnya?) Sehingga cukup umum untuk menemukan kerentanan keamanan dalam skrip yang diproses. data yang tidak dipercaya.
Itu sebabnya Anda sering mendengar bahwa Anda tidak boleh menulis skrip shell CGI, atau skrip setuid dinonaktifkan di sebagian besar Unix. Atau Anda harus ekstra hati-hati saat memproses file dalam direktori yang dapat ditulis oleh dunia (lihat misalnya CVE-2011-0441 ).
Fokusnya adalah pada itu, skrip shell, bukan penerjemah.
Anda dapat mengekspos shell interpreter untuk data yang tidak dipercaya (makan data asing sebagai kode shell untuk menafsirkan) melalui eval
atau .
atau menelepon pada pengguna disediakan file, tapi kemudian Anda tidak perlu kerentanan dalam bash
untuk mengeksploitasi itu. Cukup jelas bahwa jika Anda mengoper data yang tidak bersih untuk diterjemahkan oleh shell, itu akan menafsirkannya.
Jadi shell disebut dalam konteks tepercaya. Itu diberikan skrip tetap untuk menafsirkan dan lebih sering daripada tidak (karena sangat sulit untuk menulis skrip yang dapat diandalkan) data tetap untuk diproses.
Misalnya, dalam konteks web, shell mungkin dipanggil dalam sesuatu seperti:
popen("sendmail -oi -t", "w");
Apa yang bisa salah dengan itu? Jika ada sesuatu yang salah yang dibayangkan, itu tentang data yang diumpankan ke sendmail itu, bukan bagaimana baris perintah shell itu sendiri diurai atau data tambahan apa yang diumpankan ke shell itu. Tidak ada alasan Anda ingin mempertimbangkan variabel lingkungan yang diteruskan ke shell itu. Dan jika Anda melakukannya, Anda menyadari itu semua env vars yang namanya dimulai dengan "HTTP_" atau dikenal dengan baik seperti env vars CGI SERVER_PROTOCOL
atau QUERYSTRING
tidak ada yang berhubungan dengan shell atau sendmail.
Dalam konteks elevasi hak istimewa seperti ketika menjalankan setuid / setgid atau melalui sudo, lingkungan umumnya dipertimbangkan dan ada banyak kerentanan di masa lalu, sekali lagi tidak terhadap shell itu sendiri tetapi terhadap hal-hal yang meningkatkan hak istimewa seperti sudo
(lihat misalnya CVE -2011-3628 ).
Misalnya, bash
tidak mempercayai lingkungan ketika setuid atau dipanggil oleh perintah setuid (pikirkan mount
misalnya yang memanggil pembantu). Secara khusus, ini mengabaikan fungsi yang diekspor.
sudo
tidak membersihkan lingkungan: semua secara default kecuali untuk daftar putih, dan jika tidak dikonfigurasi untuk, di daftar paling hitam beberapa yang diketahui mempengaruhi shell atau yang lain (seperti PS4
, BASH_ENV
, SHELLOPTS
...). Itu juga blacklist variabel lingkungan yang isinya dimulai dengan ()
(itulah sebabnya CVE-2014-6271 tidak mengizinkan eskalasi hak istimewa melalui sudo
).
Tetapi sekali lagi, itu untuk konteks di mana lingkungan tidak dapat dipercaya: variabel apa pun dengan nama dan nilai apa pun dapat ditetapkan oleh pengguna jahat dalam konteks itu. Itu tidak berlaku untuk server web / ssh atau semua vektor yang mengeksploitasi CVE-2014-6271 di mana lingkungan dikendalikan (setidaknya nama variabel lingkungan dikendalikan ...)
Sangat penting untuk memblokir variabel seperti echo="() { evil; }"
, tetapi tidak HTTP_FOO="() { evil; }"
, karena HTTP_FOO
tidak akan dipanggil sebagai perintah oleh skrip shell atau baris perintah. Dan apache2 tidak akan pernah mengatur echo
atau BASH_ENV
variabel.
Sudah cukup jelas bahwa beberapa variabel lingkungan harus dimasukkan dalam daftar hitam dalam beberapa konteks berdasarkan nama mereka , tetapi tidak ada yang berpikir bahwa mereka harus dimasukkan dalam daftar hitam berdasarkan konten mereka (kecuali untuk sudo
). Atau dengan kata lain, tidak ada yang mengira bahwa vv sewenang-wenang bisa menjadi vektor untuk injeksi kode.
Seperti apakah pengujian ekstensif ketika fitur ditambahkan bisa menangkapnya, saya akan mengatakan itu tidak mungkin.
Saat Anda menguji fitur , Anda menguji fungsionalitas. Fungsionalitas berfungsi dengan baik. Jika Anda mengekspor fungsi dalam satu bash
permintaan, itu diimpor baik-baik saja di lain. Pengujian yang sangat menyeluruh dapat menemukan masalah ketika variabel dan fungsi dengan nama yang sama diekspor atau ketika fungsi tersebut diimpor di lokal yang berbeda dari yang diekspor.
Tetapi untuk dapat mengetahui kerentanannya, ini bukan tes fungsionalitas yang harus Anda lakukan. Aspek keamanan harus menjadi fokus utama, dan Anda tidak akan menguji fungsionalitasnya, tetapi mekanismenya dan bagaimana hal itu dapat disalahgunakan.
Ini bukan sesuatu yang sering dimiliki pengembang (terutama pada tahun 1989), dan seorang pengembang shell dapat dimaafkan untuk berpikir perangkat lunaknya tidak mungkin dapat dieksploitasi jaringan.