Verifikasi binari perintah sebelum eksekusi

13

Apakah ada metode untuk memeriksa apa yang sebenarnya Anda jalankan dari skrip bash?

Katakanlah bash script Anda memanggil beberapa perintah (misalnya: tar, mail, scp, mysqldump) dan Anda bersedia untuk memastikan bahwa taradalah yang sebenarnya, real tar, yang ditentukan oleh rootpengguna menjadi file dan direktori induk pemilik satu-satunya dengan hak akses menulis dan bukan sebagian /tmp/surprise/tardengan www-dataatau apache2menjadi pemilik.

Tentu saya tahu tentang PATHdan lingkungan, saya ingin tahu apakah ini juga dapat diperiksa dari skrip bash yang sedang berjalan dan, jika demikian, bagaimana tepatnya?

Contoh: (pseudo-code)

tarfile=$(which tar)
isroot=$(ls -l "$tarfile") | grep "root root"
#and so on...
Miloš Đakonović
sumber
2
Jika Anda sangat paranoid, maka gunakan binari Anda sendiri!
Ipor Sircer
8
Selain whichtidak mengatakan dengan benar apa yang tarakan dilakukan, seperti dijawab oleh xhienne, lsdapat diretas untuk mengembalikan info palsu tentang file, jika ada. Juga grepbisa diretas untuk mengembalikan info palsu; yang bisa dihindari dengan menggunakan pencocokan shell saja, tetapi kemudian shell bisa diretas. Dan shell dapat diretas untuk memberikan hasil yang salah sejak typeawal - atau diganti seluruhnya karena penggantian shell adalah inovasi penting dari Unix dibandingkan dengan OS yang berusia 50 tahun. Lihat alamat Turing 1984 Ken Thompson. Ini kura-kura sepanjang jalan.
dave_thompson_085
2
Saya tidak bisa menjawab ini untuk Linux - hanya AIX - yang memiliki komponen yang disebut Eksekusi Tepercaya ( TE) - yang memiliki database dengan tanda tangan (yaitu, lebih luas daripada MD5 checksum. Ketika TE aktif dan file ada dalam database Anda dapat memilih apakah program berjalan - atau hanya memperingatkan bahwa itu tidak cocok dengan database. Selanjutnya, ada dua pengaturan lain: TEP(PATH eksekusi tepercaya) dan TLP(PATH LIBrary tepercaya). Hanya program di TEP yang dapat dieksekusi dan perpustakaan hanya boleh dimuat dengan direktori ini termasuk dalam TLP. Di Linux saya ada sesuatu yang disebut 'AppArmor' yang dapat membantu Anda
Michael Felt
1
Anda dapat memiliki jenis keamanan ini, tetapi bukan dari skrip - saat skrip Anda dijalankan di lingkungan yang tidak terkendali, sudah terlambat. Yang Anda tahu semua yang dapat Anda lihat adalah chroot yang dibuat oleh penyerang.
Charles Duffy
2
... jika Anda ingin memiliki sistem yang tepercaya sepenuhnya, Anda harus menggunakan pendekatan ChromeOS: Perintahkan firmware Anda ditandatangani dengan kunci yang tertanam di perangkat keras Anda; bootloader / kernel Anda diverifikasi oleh firmware; Partisi root OS Anda hanya-baca menggunakan tanda tangan level blok untuk verifikasi; dll. Ada juga pendekatan yang mirip dengan apa yang dibahas oleh @MichaelFelt - lihat Arsitektur Pengukuran Integritas - tetapi dampak kinerja lebih tinggi dan tingkat integritas berkurang (karena memeriksa tanda tangan biner tidak membantu Anda dengan serangan melalui non-executable kandungan).
Charles Duffy

Jawaban:

24

Alih-alih memvalidasi binari yang akan Anda jalankan, Anda bisa menjalankan binari yang tepat dari awal. Misalnya, jika Anda ingin memastikan Anda tidak akan menjalankan /tmp/surprise/tar, jalankan saja /usr/bin/tardalam skrip Anda. Atau, atur nilai Anda $PATHmenjadi waras sebelum menjalankan apa pun.

Jika Anda tidak mempercayai file /usr/bin/dan direktori sistem lainnya, tidak ada cara untuk mendapatkan kembali kepercayaan. Dalam contoh Anda, Anda sedang memeriksa pemiliknya ls, tetapi bagaimana Anda tahu Anda bisa percaya ls? Argumen yang sama berlaku untuk solusi lain seperti md5sumdan strace.

Di mana kepercayaan tinggi dalam integritas sistem diperlukan, solusi khusus seperti IMA digunakan. Tapi ini bukan sesuatu yang bisa Anda gunakan dari skrip: seluruh sistem harus diatur dengan cara khusus, dengan konsep file yang tidak dapat diubah.

Dmitry Grigoryev
sumber
Istirahat yang bila distribusi yang berbeda memilih untuk menempatkan binari di /binbukannya /usr/bin.
Damian Yerrick
IMA adalah salah satu dari dua pendekatan siap produksi untuk ini - yang lain adalah pendekatan dm-verity yang diambil oleh ChromeOS untuk melakukan validasi tingkat blok dari rootfs.
Charles Duffy
Komentar @DamianYerrick Fair. Setel $PATHke kedua jalur tersebut kemudian, jika dukungan distribusi berganda diperlukan.
Dmitry Grigoryev
AIX TE (dengan atau tanpa RBAC) akan menjadi kernel-builtin "siap-produksi" ketiga yang akan mencapai ini - mungkin lebih. TE, setelah diaktifkan menjadi lebih dari pasif - akan mencegah file dibuka dan / atau program dieksekusi. Selain itu, aplikasi dan penggunaan perpustakaan dapat diatur secara eksklusif di TEP (jalur eksekusi tepercaya) atau TLP (jalur perpustakaan tepercaya). Lihat ibm.com/support/knowledgecenter/en/ssw_aix_61/… untuk info dasar
Michael Felt
6

Jika penyusup mendapatkan akses ke sistem Anda dan dapat memodifikasi Anda $PATH(yang seharusnya tidak termasuk /tmpdalam keadaan apa pun), maka sudah terlambat untuk mulai khawatir tentang kepemilikan dari executable.

Alih-alih, Anda harus membaca tentang cara menghadapi gangguan .

Lebih baik berkonsentrasi pada menghindari intrusi sama sekali.

Jika Anda memiliki sistem di mana hal-hal semacam ini penting, maka mungkin ide yang baik untuk mengisolasi bagian-bagiannya yang perlu diketahui publik dari bagian-bagian yang perlu pribadi, serta melakukan audit terhadap mode komunikasi di antara ini.

Kusalananda
sumber
4

Mungkin sampai batas tertentu dengan memverifikasi md5sumfile. Jadi pada sistem yang menggunakan aptmanajemen paket - dalam kasus khusus saya, Ubuntu 16.04 - ada file /var/lib/dpkg/info/tar.md5sums, yang menyimpan jumlah md5 dari semua file yang berasal dari tarsaat instalasi. Jadi, Anda bisa menulis pernyataan if sederhana yang memeriksa apakah output md5sum /bin/tarcocok dengan apa yang ada di file itu.

Itu tentu saja mengasumsikan bahwa file itu sendiri belum dirusak. Ini tentu saja hanya dapat terjadi ketika penyerang mendapatkan akses root / sudo, di mana semua taruhan dimatikan.

Sergiy Kolodyazhnyy
sumber
8
Tetapi bagaimana Anda memvalidasi /usr/bin/md5sum?
Dmitry Grigoryev
Jika seorang penyerang dapat mengganti /bin/taratau /usr/bin/tar, sangat mungkin mereka juga dapat dengan mudah mengganti md5sumatau /var/lib/dpkg/info/tar.md5sums. Atau $SHELL.
Jonas Schäfer
1
Saya pikir saya sudah menyebutkan dalam paragraf terakhir, bahwa untuk hal seperti itu terjadi, penyerang perlu mendapatkan akses root ke sistem, dan pada saat itu segala sesuatu mungkin terjadi. Dalam kasus, di mana penyerang tidak memiliki akses root, tetapi dapat mengubah variabel PATH untuk pengguna atau membuat alias di mana tarmenunjuk ke biner yang berbeda, itu akan berfungsi. Ketika sebuah sistem dikompromikan pada level root, Anda memiliki satu opsi saat itu - nuke dari orbit
Sergiy Kolodyazhnyy
3

Ya, ada metode: builtin type. Berlawanan dengan whichperintah yang hanya mencari di PATH Anda, typeakan memberi tahu Anda apakah nama perintah itu benar-benar kata kunci yang dipesan, bawaan, alias, fungsi, atau file disk.

$ type -t foobar || echo "Not found"
Not found

$ type -t echo
builtin

$ enable -n echo; type -t echo; type -p echo
file
/usr/bin/echo

$ echo() { printf "(echoing) %s\n" "$*"; }; type -t echo
function

$ alias echo="/bin/echo 'I say: ' "; type -t echo
alias

Selain itu type -aakan memberi Anda semua kandidat untuk perintah Anda (dari pilihan pertama hingga terakhir):

$ type -a echo
echo is aliased to `/bin/echo 'I say: ' '
echo is a function
echo () 
{ 
    printf "(echoing) %s\n" "$*"
}
echo is a shell builtin
echo is /usr/local/bin/echo
echo is /bin/echo

Akhirnya, jika Anda hanya peduli tentang binari pada disk Anda, Anda dapat menggunakan type -Pauntuk mendapatkan semua binari di PATH Anda (urutan yang sama seperti di atas):

$ type -Pa tar
/home/me/bin/tar                <= oh oh, is this normal?
/bin/tar

Yang mengatakan, typesendirian tidak akan memberi tahu Anda dengan tepat perintah apa yang akan dipanggil pada akhirnya. Misalnya, jika Anda taradalah alias yang memanggil biner (mis. alias tar="/tmp/tar") Maka typeakan memberi tahu Anda ini adalah alias.

xienne
sumber
type -atermasuk semua bentuk (misalnya program alias dan eksternal)
dave_thompson_085
Terima kasih @dave, ini memang menarik, saya telah memperbarui jawaban saya
xhienne
1
typeakan memberitahumu inasfar sebagai bash yang tahu, tetapi jika kita di bawah kendali dari penyerang jahat, tidak ada alasan untuk percaya bahwa apa yang menurut bash tahu itu mencerminkan kebenaran yang sebenarnya. Untuk semua yang Anda tahu ada LD_PRELOADmodul yang mencegat setiap panggilan C-library yang Anda buat.
Charles Duffy
1
@CharlesDuffy Anda benar tentu saja. Saya tidak ingin menjawab ke arah sudut keamanan. Saya hanya mengusulkan jawaban untuk pertanyaan di atas: "Apakah ada metode untuk memeriksa apa yang sebenarnya Anda jalankan dari skrip bash" dan mengusulkan alternatif untuk which.
xhienne
Saya belum pernah melihat enablesebelumnya. Saya menggunakan saran dari jawaban ini untuk menjalankannya type enableuntuk mencari tahu bahwa itu adalah built-in shell dan kemudian help enableuntuk melihat apa fungsinya.
Joe
3

Anda dapat memeriksa perintah apa yang sebenarnya dieksekusi oleh skrip dengan menggunakan strace. Sebagai contoh:

strace -f -e execve ./script.sh

Dengan skrip berikut:

#!/bin/bash
touch testfile.txt
echo "Hello" >> testfile.txt
cat testfile.txt
rm testfile.txt

straceakan memberi tahu Anda jalur yang tepat ke perintah yang dijalankan saat digunakan dengan -e execveparameter:

execve("./script.sh", ["./script.sh"], [/* 69 vars */]) = 0 
Process 8524 attached
[pid  8524] execve("/usr/bin/touch", ["touch", "testfile.txt"], [/* 68 vars */]) = 0 
[pid  8524] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8524, si_status=0, si_utime=0, si_stime=0} --- 
Process 8525 attached [pid > 8525] execve("/bin/cat", ["cat", "testfile.txt"], [/* 68 vars */]) = 0
Hello [pid  8525] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8525, si_status=0, si_utime=0, si_stime=0} --- 
Process 8526 attached [pid > 8526] execve("/bin/rm", ["rm", "testfile.txt"], [/* 68 vars */]) = 0
[pid  8526] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=8526, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

Parameter (dari strace man):

-f: Lacak proses anak karena dibuat oleh proses yang saat ini dilacak sebagai hasil dari garpu (2), vfork (2) dan panggilan sistem klon (2). Catatan yang -p PID -fakan melampirkan semua utas proses PID jika multi-utas, tidak hanya utas dengan thread_id = PID.

-e trace=file: Lacak semua panggilan sistem yang menggunakan nama file sebagai argumen. Anda dapat menganggap ini sebagai singkatan -e trace=open,stat,chmod,unlink,...yang berguna untuk melihat file apa yang dirujuk oleh proses. Selanjutnya, menggunakan singkatan akan memastikan bahwa Anda tidak sengaja lupa untuk memasukkan panggilan seperti lstat dalam daftar.

Zumo de Vidrio
sumber
3
Ini tidak dengan cara apa pun dapat digunakan oleh skrip untuk melakukan pengujian otomatis, dan tidak ada alasan khusus untuk percaya bahwa straceitu sendiri belum ditumbangkan.
Charles Duffy
0

OS Linux didasarkan pada file dan banyak perintah yang dijalankan di linux kemungkinan akan menyelesaikan beberapa perubahan pada file yang terletak di mesin Anda. Karena itu mungkin adalah solusi terbaik untuk masalah Anda. Anda dapat menguji perintah Anda untuk setiap perubahan pada sistem file sebelum dieksekusi.

masukkan deskripsi gambar di sini

Ada perintah 'strace' yang mendekompilasi perintah Anda di beberapa bagian ...

masukkan deskripsi gambar di sini

Jika Anda benar-benar ingin masuk lebih dalam, Anda ingin checkout dekompiler untuk skrip yang akan dieksekusi. Dengan kata lain Anda harus memeriksa interpretasi assembler dari perintah itu. Untuk bash di sana objdump -d. Skrip Linux bin terutama dibuat dengan Cbahasa pemrograman jadi gunakan Cdecompiler yang bagus .


sumber