Mengapa kemampuan untuk mendefinisikan fungsi dalam variabel lingkungan itu sendiri bukan risiko keamanan?

9

Seperti yang saya pahami, umumnya dianggap aman untuk membiarkan siapa pun memberikan informasi yang akan disimpan dalam variabel lingkungan. Kerentanan shellshock adalah masalah di sini karena itu berarti kode pada akhir definisi fungsi di dalam variabel lingkungan akan dieksekusi ketika instance baru dari bash diluncurkan dan Anda jelas tidak ingin ada yang menjalankan kode apa pun yang mereka inginkan di server Anda . Definisi fungsi sendiri tampaknya bukan risiko keamanan dan diizinkan karena mereka harus secara eksplisit dipanggil agar kode mereka dieksekusi.

Pertanyaan saya adalah mengapa pengguna jahat tidak dapat dengan mudah mendefinisikan suatu fungsi, yang mengandung kode berbahaya mereka sebagai perintah bersama seperti lsdan kemudian berharap bahwa skrip (atau apa pun yang sedang dijalankan) akan menggunakan perintah ini di beberapa titik?

Contoh dari apa yang ada dalam pikiran saya:

$ export ls='() { echo "doing bad things..."; }'
$ bash -c ls
doing bad things...
Reed Espinosa
sumber

Jawaban:

10

Ini adalah risiko keamanan. Itu umumnya mengapa Anda tidak dapat melakukannya ketika beralih ke konteks lain (kendali jarak jauh suatu sistem, mengubah pengguna, dll).

Jika Anda memiliki kemampuan untuk membuat variabel lingkungan apa pun yang Anda inginkan, ada sejumlah cara potensial Anda dapat mengeksekusi kode arbitrer.
Ambil $LD_PRELOADsebagai contoh. Jika Anda memiliki kemampuan untuk mengatur variabel itu, Anda dapat mengganti fungsi perpustakaan, dan menempelkan kode Anda di sana. Anda dapat mengatur $DISPLAYvariabel, dan mengarahkan ulang tampilan X yang terhubung dengan program sehingga Anda dapat mengontrol aplikasi.

Inilah sebabnya mengapa hal-hal seperti sudomenghapus lingkungan semua variabel. sudohanya memungkinkan beberapa variabel terpilih melalui. Dan dari variabel-variabel itu, ia membersihkan mereka (melewati $TERMvariabel, tetapi tidak jika berisi karakter yang tidak biasa).

Patrick
sumber
Wow, saya selalu bertanya-tanya mengapa beberapa skrip besar yang saya lakukan di BASH akan mengalami kegagalan aneh yang aneh ketika dimulai dengan sudo, khususnya di sekitar jalur, yang membuat saya memeriksa sudo mulai dan memblokirnya, tetapi saya tidak pernah tahu mengapa itu terjadi dan masalah, terima kasih atas penjelasan yang baik dan sudo menghapus variabel lingkungan.
Lizardx
3

Saya akan mengatakan itu, ketika bash adalah / bin / sh Anda. Ini bukan fitur shell bourne, dan saya berani bertaruh itu bukan fitur shell posix, sebenarnya mereka mungkin ingin melarangnya.

Bash sebenarnya lebih merupakan shell turunan korn, daripada shell bourne, terlepas dari namanya, dan itu satu-satunya shell seperti Korn yang memiliki fitur, dan menurut saya itu adalah fitur kitchensink yang tidak memiliki sifat praktis. Pengembang yang menghindari fitur bash untuk standar, seperti shell bourne, shell posix, atau subset ksh88 yang memiliki kesamaan shell modern, atau dengan kata lain, berkomitmen pada praktik yang baik, dan idiom standar, terkejut ketika perangkat lunak mereka aktif linux dan mac dan sekarang berpotensi rentan, karena penulis yang mengeksploitasi bebas untuk menggunakan 'bashism', terlepas dari niat mereka. Sejauh kompatibilitas ditingkatkan, ketika dipanggil sebagai / bin / sh, atas turunan shell korn lainnya, hanya jika / bin / sh adalah shell login Anda, atau shell interaktif, ketika bash berperilaku lebih seperti shell bourne, daripada shell korn,

Saya akan mencoba meyakinkan Anda bahwa ini adalah fitur kitchen-sink, dengan 2 case: Anda seorang pengembang yang tertanam, yang membuat perangkat seperti router, penyimpanan pertama yang terhubung dengan jaringan, lebih banyak, memori, jadi, lebih banyak biaya, jadi lebih sedikit keuntungan, jadi, jika ini adalah alasan untuk mempertimbangkan untuk menggunakan fitur bash ini, bukankah Anda seharusnya menggunakan FPATH dan pengisian otomatis, fitur ksh88? bukannya melewati seluruh fungsi byte untuk byte di lingkungan? Anda bahkan dapat mempertimbangkan parsing dan pemangkasan grosir lingkungan, sebelum sampai ke shellscript yang dapat salah menguraikan variabel, seperti hanya menyaring ^ $ (. *) $, Dan sejenisnya ...

Itu menggarisbawahi apa yang unik tentang ini, tidak peduli apa variabelnya, dan skrip tidak harus referensi atau menggunakan variabel, itu masih bisa rentan.

#!/bin/sh
exec /usr/local/myapp/support/someperlscript.pl

Untuk hal lain di bawah matahari, di atas harus seaman skrip perl, Anda tidak menggunakan variabel apa pun bagaimana Anda bisa salah menguraikannya? Berubah menjadi

#!/bin/bash -norc
exec /usr/local/myapp/support/someperlscript.pl

Tidak membantu, ini tidak ada hubungannya dengan ENV atau yang seperti itu - semua orang terbakar karena bash harus unik. Fakta bahwa bash versi 2 memiliki masalah, bagi saya membuktikan bahwa tidak ada yang pernah menggunakan fitur ini untuk aplikasi mereka, karena kalau tidak seharusnya tidak bersembunyi selama ini . Dan yang lebih buruk, pada dasarnya tidak ada yang menghindari fitur ini . Berikut ini sebuah contoh dengan: dengan 'su -', yang jika Anda akan bertanya kepada seseorang, penjelasannya akan membuang lingkungan, periksa halaman manual, dan Anda akan menemukan hanya 99,9%. Saya menguji dengan cara yang benar, karena pada sistem ini / bin / sh adalah shell login root, dan / bin / sh adalah bash TAPI , dalam contoh ini saya mencobauntuk mengeraskan .bash_profile saya. Saya mengganti nama root saya yang ada (yang diaktifkan), tetapi pemikiran saya adalah jika su, maka mungkin sudo, bagaimanapun, saya berubah menjadi ini:

exec env -i TERM=vt102 LOGNAME=root USER=root HOME=/var/root /bin/ksh -i

Jadi, saya benar-benar membuang lingkungan sepenuhnya, dan menggunakan env minimal, dan kemudian menjalankan shell yang seharusnya tidak memiliki masalah, di tempat proses saat ini. Kemudian di tempat contoh standar coba:

%dock='() { echo -e "\e[2t\c"; echo dockshock;} ; dock' su 

Ini mengilustrasikan bagaimana itu tidak ada hubungannya dengan parsing fungsi tertentu, dan eksploit dapat merujuk dan menggunakan, fungsi tersebut. Anda dapat membayangkan fungsi yang memiliki logika untuk menguji apakah root, dll. Dalam hal ini, itu hanya bentuk yang dimodifikasi dari fungsi untuk memberi ikon atau merapat jendela terminal, menggunakan urutan escape, itu cukup standar, jadi setelah saya mengklik untuk mendeikonifikasi, saya lihat dockshock - tapi, jadi apa? Sekarang coba ini:

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su - 

Dan coba tebak? Jendela tersedot ke dermaga. Begini setelahnya ..

%TERM='() { echo -e "\e[2t\c"; echo dockshock;} ; TERM' su -
Password:
dockshock
# env
_=/usr/bin/env
HOME=/var/root
LOGNAME=root
TERM=vt102
USER=root
# echo $0
/bin/ksh
#

Jadi, sangat, banyak untuk itu! Fungsi yang diekspor sebenarnya memiliki prioritas di atas skrip rc. Anda tidak bisa mengelak.

Dan LaBell
sumber
1
POSIX mengizinkan fungsi yang dapat diekspor dalam konsep 2, dan tidak memperbolehkannya setelahnya. The fitur gila.
mikeserv