Apakah ada shell yang memeriksa untuk memastikan kode ditandatangani?

19

Saya bermain-main dengan PowerShell minggu ini dan menemukan bahwa Anda harus menandatangani skrip Anda agar dapat dijalankan. Apakah ada fungsi aman serupa di Linux yang berhubungan dengan mencegah skrip bash agar tidak dijalankan?

Satu-satunya fungsi yang mirip dengan ini, yang saya ketahui adalah SSH yang membutuhkan kunci tertentu.

leeand00
sumber
2
Kedengarannya seperti solusi ad-hoc untuk penandatanganan paket kepada saya. Saya tidak tahu apakah Windows memiliki paket kriptografi yang menandatangani cara Linux.
Wildcard
6
@ leeand00 Sebuah skrip adalah kasus khusus dari paket perangkat lunak dan saya tidak melihat ada gunanya memilih kasus itu.
Gilles 'SO- stop being evil'
2
Mekanisme yang paling saya sukai adalah cara ChromeOS melakukan ini - menempatkan satu-satunya filesystem yang tidak ditandai noexecpada partisi read-only pada perangkat blok bertanda dm-verity.
Charles Duffy
1
source.android.com/security/verifiedboot berbicara tentang adopsi Android terhadap fitur itu (awalnya ChromeOS).
Charles Duffy
1
Anda dapat mempertimbangkan bash sebagai sekelompok perintah yang dapat diketik secara manual di antarmuka baris perintah. Apa gunanya membatasi skrip ketika Anda bisa mengetik konten di baris perintah?
Ding-Yi Chen

Jawaban:

11

Jika Anda mengunci kemampuan pengguna untuk menjalankan skrip, sudomaka Anda dapat menggunakan digestfungsinya.
Anda dapat menentukan hash dari skrip / executable sudoersyang akan diverifikasi oleh sudosebelum dieksekusi. Jadi meskipun tidak sama dengan penandatanganan, itu memberi Anda jaminan dasar bahwa skrip setidaknya tidak dimodifikasi tanpa sudoers juga sedang dimodifikasi.

Jika nama perintah diawali dengan Digest_Spec, perintah hanya akan cocok jika itu dapat diverifikasi menggunakan SHA-2 digest yang ditentukan. Ini mungkin berguna dalam situasi di mana pengguna yang meminta sudo memiliki akses tulis ke perintah atau direktori induknya. Format digest berikut didukung: sha224, sha256, sha384 dan sha512. String dapat ditentukan dalam format hex atau base64 (base64 lebih ringkas). Ada beberapa utilitas yang mampu menghasilkan SHA-2 digest dalam format hex seperti openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.

http://www.sudo.ws/man/1.8.13/sudoers.man.html

batfastad
sumber
Itu akan menahan saya sampai saya membaca tentang SE Linux dan melakukannya dengan benar.
leeand00
13

Iya dan tidak.

Distribusi perangkat lunak Linux bekerja agak berbeda dari distribusi perangkat lunak Windows. Di dunia Linux (tidak tertanam), metode utama untuk mendistribusikan perangkat lunak adalah melalui distribusi (Ubuntu, Debian, RHEL, Fedora, Arch, dll.). Semua distribusi utama telah menandatangani paket mereka secara sistematis selama sekitar satu dekade.

Ketika perangkat lunak didistribusikan secara independen, tergantung pada vendor untuk memutuskan bagaimana mereka akan mengirimkan perangkat lunak mereka. Vendor yang baik menyediakan sumber paket yang kompatibel dengan distribusi utama (tidak ada mekanisme distribusi terpadu untuk semua Linux: distribusi perangkat lunak adalah salah satu poin utama diferensiasi antara distribusi) dan yang ditandatangani dengan kunci vendor. Distribusi Linux jarang bertindak sebagai otoritas penandatanganan untuk vendor pihak ketiga (Canonical melakukan ini dengan mitra Ubuntu, tetapi itu mencakup sangat sedikit vendor), dan saya pikir semua distribusi utama menggunakan web kepercayaan PGP daripada infrastruktur kunci publik TLS, jadi terserah kepada pengguna untuk mengetahui apakah mereka ingin mempercayai kunci.

Tidak ada mekanisme khusus yang memilih paket perangkat lunak yang terdiri dari satu skrip dari paket perangkat lunak yang terdiri dari executable asli, file data, atau beberapa file. Verifikasi tanda tangan juga tidak dibangun pada penerjemah skrip umum, karena memverifikasi paket perangkat lunak adalah masalah yang sepenuhnya ortogonal dari menjalankan skrip.

Saya pikir Windows memberi anotasi file dengan asalnya, dan memerlukan konfirmasi pengguna untuk menjalankan file yang asalnya "diunduh" daripada "lokal". Linux tidak memiliki mekanisme yang sama. Hal yang paling dekat adalah izin eksekusi: file yang diunduh tidak memiliki izin eksekusi, pengguna harus mengaktifkannya secara eksplisit ( chmod +xpada baris perintah, atau tindakan yang sepadan dalam manajer file).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
2
FWIW, di atas PowerShell ini dapat dikonfigurasi (dengan pengaturan kebijakan) untuk hanya menjalankan skrip yang ditandatangani dan kebijakan ini dapat dikonfigurasi sehingga semua skrip harus ditandatangani atau hanya skrip "remote origin", atau tanpa skrip. Ini bekerja paling baik dalam lingkungan AD dengan manajemen kunci dan manajemen kebijakan pusat. Ini dapat dilewati :-)
Stephen Harris
@StephenHarris Yah ya jika Anda mengaturnya untuk memotong ...
leeand00
@ leeand00 - Rupanya encoding base64 juga berfungsi sebagai bypass tapi saya tidak tahu apakah itu sudah ditutup di versi PowerShell yang lebih baru.
Stephen Harris
1
@ leeand00 - lihat darkoperator.com/blog/2013/3/5/... untuk bersenang-senang :-) Pada dasarnya lewati skrip yang dikodekan base64 sebagai parameter pada baris perintah :-) Cukup mudah untuk dibungkus!
Stephen Harris
2
SeLinux memberi anotasi file dengan asalnya. Itu salah satu tempat utamanya.
loa_in_
10

Linux tidak menyediakan kemampuan untuk membatasi pelaksanaan skrip bash berdasarkan tanda tangan digital.

Ada beberapa pekerjaan tentang otentikasi executable biner. Lihat https://lwn.net/Articles/488906/ untuk info.

Quentin Fennessy
sumber
Suara positif untuk jawaban langsung tanpa menyarankan solusi hackey.
user394
8

Dalam satu kata, "tidak".

Linux tidak benar-benar membedakan antara executable dan skrip; yang #!di awal adalah cara untuk memberitahu kernel apa program untuk menjalankan untuk mengevaluasi masukan tapi itu bukan satu-satunya cara script dapat dieksekusi.

Jadi, misalnya, jika saya punya skrip

$ cat x
#!/bin/sh 
echo hello

Maka saya bisa menjalankan ini dengan perintah

$ ./x

Itu akan menyebabkan kernel mencoba dan menjalankannya, mengenali #!dan kemudian menjalankannya secara efektif /bin/sh x.

Namun saya juga bisa menjalankan salah satu varian ini:

$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x

atau bahkan

. ./x

Jadi, bahkan jika kernel mencoba untuk menerapkan penandatanganan pada execlayer kita dapat memotong ini dengan hanya menjalankan interpreter dengan script sebagai parameter.

Ini berarti bahwa kode penandatanganan harus berada dalam juru bahasa itu sendiri. Dan apa yang akan menghentikan pengguna untuk mengkompilasi salinan shell mereka sendiri tanpa menandatangani kode penegakan?

Solusi standar untuk ini bukan menggunakan penandatanganan, tetapi untuk menggunakan Kontrol Akses Wajib (MAC), seperti SELinux. Dengan sistem MAC, Anda dapat menentukan dengan tepat apa yang diizinkan dijalankan oleh setiap pengguna dan lapisan transisi. Jadi, misalnya, Anda dapat mengatakan "pengguna normal dapat menjalankan apa pun kecuali server web dan proses CGI hanya dapat mengakses hal-hal dari /var/httpddirektori; semuanya ditolak".

Stephen Harris
sumber
1
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?Tidak memungkinkan terlaksananya setiap executable unsigned akan melakukannya, Jika pengguna tidak memiliki kunci penandatanganan. Sudah ada berbagai proyek * nix untuk ini.
alzee
2

Distro Linux biasanya memiliki gnupg . Kedengarannya bagi saya seperti yang Anda inginkan adalah bash wrapper sederhana yang memeriksa tanda tangan gpg terpisah terhadap skrip argumen dan hanya menghasilkan menjalankan skrip jika cek berhasil:

#!/bin/sh
gpgv2 $1.asc && bash "$@"
PSkocik
sumber
Satu-satunya hal yang tidak ada adalah menjalankan skrip yang dibuat seseorang ... sendiri ...
leeand00
2

Pertanyaan balasan yang langsung muncul di benak Anda adalah "Mengapa Anda ingin mencegah pengguna menjalankan program yang mereka tulis? " Ada beberapa kemungkinan:

  1. Secara harfiah tidak mungkin mendeteksi siapa yang membuat kode di tempat pertama. Pemilik file skrip adalah siapa saja yang sebenarnya menyimpan konten file tersebut, terlepas dari mana asalnya. Jadi menegakkan tanda tangan hanyalah pengganti rumit untuk kotak dialog konfirmasi: "Apakah Anda yakin ingin melakukan ini?" Di Linux bagian dari masalah ini diselesaikan secara transparan dengan paket yang ditandatangani, dan dimitigasi oleh fakta bahwa pengguna memiliki akses terbatas secara default. Pengguna juga diharapkan mengetahui bahwa menjalankan kode orang lain bisa berbahaya *.
  2. Dalam nada yang sama menandatangani naskah adalah operasi yang jauh lebih kompleks daripada menyimpan file. Dalam kasus terbaik ini meminta pengguna untuk menyadari bahwa mereka melakukan tindakan yang mirip dengan menandatangani dokumen, dan harus memeriksa apa yang dikatakannya sebelum melanjutkan. Kemungkinan besar itu hanya memastikan tingkat kemahiran teknis yang sangat minimal pada bagian pengguna untuk diizinkan menjalankan skrip. Dalam kasus terburuk itu menunjukkan kesediaan untuk melompati serangkaian rintangan untuk menjalankan apa yang mereka inginkan. Kemahiran teknis diasumsikan di Linux *.
  3. Kemungkinan besar orang akan mendeteksi kode berbahaya saat mengetik / menempelkan serangkaian perintah ke baris perintah mereka. Cuplikan teks yang dimaksudkan untuk disalin dan ditempelkan biasanya lebih kecil dari serangkaian perintah yang diperlukan untuk melakukan sesuatu yang benar jahat. Pengguna juga dapat dengan hati-hati menyalin dan menempel setiap baris secara terpisah, memahami apa yang terjadi saat itu terjadi. Dengan skrip, mungkin saja pengguna tidak pernah melihat kode sama sekali. Ini mungkin aplikasi yang berguna dari skrip yang ditandatangani, dengan biaya kepuasan yang terlalu umum setelah 12 kali Anda harus melakukannya.

* Ini mungkin menjadi semakin tidak benar karena semakin banyak orang mulai menggunakan Linux

l0b0
sumber
1

Alasan sistem berevolusi secara berbeda adalah karena Linux memiliki atribut file 'exec' dan Windows menggunakan ekstensi file untuk menentukan eksekusi.

Jadi di Windows mudah untuk menipu pengguna agar mengunduh file dengan ekstensi ".exe", ".bat", ".scr", yang akan disembunyikan secara default . Mengklik dua kali file itu akan memberi Anda eksekusi kode arbiter. Oleh karena itu mekanisme besar pelacakan asal dan penandatanganan dieksekusi / skrip dibangun untuk mengurangi risiko ini.

Di Linux, Anda mungkin bisa mendapatkan file ke pengguna, tetapi Anda tidak bisa dengan mudah memaksa bit 'exec' untuk diatur. Selain itu, dimungkinkan untuk membuat seluruh filesystem 'noexec'.

Anda dapat menjalankan skrip secara eksplisit dengan memohon penerjemah. Anda bahkan dapat membuat skrip shell saat runtime dan menyalurkannya ke "sh", atau menjalankan "sh -c".

pjc50
sumber
0

Secara khusus, banyak program pengarsipan tidak mempertahankan bit eksekusi pada file yang terkandung. Ini membuatnya tidak mungkin untuk menjalankan executable yang sewenang-wenang. Hampir saja.

Intinya adalah, apa yang dijelaskan dalam jawaban lain bahwa kurangnya bit eksekusi tidak mencegah Anda melewati skrip tersebut secara langsung bash. Meskipun dapat diperdebatkan bahwa sebagian besar skrip tersebut adalah bashskrip, shebang dapat menentukan program apa saja sebagai penerjemah. Ini berarti bahwa itu tergantung pada pengguna untuk menjalankan juru bahasa yang sesuai jika mereka memutuskan untuk mengabaikan semantik yang dapat dieksekusi.

Walaupun ini tidak banyak, ini cukup banyak mencakup pencegahan menjalankan executable yang tidak tepercaya di * nixes hanya dengan kernel dan shell .

Seperti yang saya sebutkan di salah satu komentar, ada satu lapisan perlindungan lainnya - SeLinux- yang melacak asal file berdasarkan seperangkat aturan. Suatu pengaturan SeLinuxtidak akan misalnya mengizinkan root untuk menjalankan yang dapat dieksekusi dengan bit yang dapat dieksekusi yang diunduh dari internet, bahkan jika Anda menyalin dan memindahkan file tersebut. Seseorang dapat menambahkan aturan bahwa file seperti itu hanya dapat dijalankan melalui biner lain yang akan memeriksa tanda tangan, tidak seperti apa yang Anda sebutkan dalam pertanyaan Anda.

Jadi, pada akhirnya ini masalah konfigurasi alat yang umumnya diinstal sebelumnya, dan jawabannya adalah ya .

loa_in_
sumber
banyak program pengarsipan tidak mempertahankan bit eksekusi pada file yang terkandung .. well, itu semacam cacat ketika Anda benar-benar ingin menggunakannya untuk pengarsipan. Untungnya tar tidak mempertahankan bit eksekusi.
pjc50
Anda harus menggunakan tar -p sumber
loa_in_
-p, --preserve-permissions, --same-permissionsberarti mengekstrak informasi tentang izin file (default untuk superuser)
loa_in_
Tidak, Anda TIDAK perlu -p. Saya melihat apa yang dikatakan halaman manual, tetapi bukan itu yang terjadi. touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest- ini dapat dieksekusi di sini, dan saya bukan root.
domen
Saya akan mencoba meningkatkan jawaban saya.
loa_in_