Menggunakan CmndAlias ALL
tidak akan pernah aman
Ada 1000 cara untuk berlari service network restart
tanpa melakukan sudo service network restart
. Berikut adalah contoh yang mungkin dicoba oleh pengguna yang nakal:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
Jika Anda memberi pengguna ALL
alias perintah, dan kemudian mencoba membuat daftar hitam, mereka akan selalu dapat menemukan jalan keluarnya. Bash daftar hitam, dan mereka akan menggunakan python. Blacklist python, dan mereka akan menggunakan Perl. Perl Daftar Hitam, dan mereka akan menggunakan PHP. Tidak ada yang menginginkan itu!
Jika Anda benar-benar tidak ingin seseorang melakukan sesuatu, Anda harus melakukan seperti yang dikatakan Thomas, dan membuat daftar putih hal-hal yang boleh mereka lakukan.
Menyiapkan daftar putih dengan pengecualian
Contoh daftar putih kecil dengan pengecualian dapat ditemukan di dekat bagian bawah man sudoers
:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(Sebenarnya contoh dari halaman manual ini tidak aman dan dapat dieksploitasi untuk mengubah kata sandi root! Lihat komentar di bawah ini untuk caranya.)
Kita dapat mencoba untuk beradaptasi bahwa untuk kasus Anda, untuk menawarkan semua service
perintah ke kelompok staf, tapi mengecualikan para service network
perintah yang perhatian Anda:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
( ALL
Posisi itu mengacu pada Host_Alias, bukan Cmnd_Alias - membingungkan bukan?)
Pengguna tidak akan dapat menjalankan sudo bash
atau sudo tee
atau sudo wget
atau sudo /path/to/malicious_script
. Anda dapat membuat daftar putih lebih banyak perintah admin untuk pengguna Anda jika Anda berhati-hati. Lebih spesifik!
Catatan: Saya menambahkan *
sebelum kata di network
atas, kalau-kalau bendera yang tidak berbahaya pernah ditambahkan ke service
alat di masa depan. Mari kita bayangkan sebuah --verbose
bendera ditambahkan di masa depan, maka pengguna akan dapat menjalankan yang berikut:
$ sudo service --verbose network restart
Jadi kita perlu *
mengkonsumsi setiap flag sebelum nama layanan. Satu-satunya kelemahan adalah bahwa hal ini dapat memblokir layanan lain yang sebenarnya Anda tidak keberatan dijalankan oleh pengguna, misalnya layanan yang dipanggil safe-network
atau network-monitor
juga akan ditolak.
Bolehkan pengguna mengedit file menggunakan izin grup
Di bawah ini Anda dapat menemukan berbagai upaya menggunakan rnano
melalui sudo
untuk membiarkan pengguna mengedit file atau file. Tapi sebenarnya mereka lebih kompleks dan lebih berbahaya dari yang seharusnya.
Solusi yang jauh lebih sederhana dan aman adalah mengubah izin grup pada file tertentu yang ingin Anda buka hak suntingnya. Berikut adalah beberapa contoh:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
Jika Anda membutuhkan lebih banyak kontrol berbutir halus (misalnya: akses hanya untuk 3 pengguna, tetapi tidak semua anggota staf) Anda dapat membuat grup baru menggunakan addgroup
perintah, dan menambahkan hanya beberapa pengguna ke dalamnya.
Biarkan pengguna mengedit file melalui sudo
Sisa dari jawaban ini menjadi penyelidikan tentang betapa mudahnya meninggalkan lubang di sudo
konfigurasi Anda ketika mencoba menawarkan fleksibilitas kepada pengguna Anda. Saya tidak akan merekomendasikan melakukan hal-hal berikut!
Jika Anda ingin memberi pengguna Anda akses untuk mengedit file tertentu, Anda dapat mencoba menggunakan rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
hanya akan membiarkan mereka mengedit file yang ditentukan. Itu penting untuk mencegah pengguna jahat mengedit layanan pemula yang berbeda (misalnya /etc/init.d/urandom
), dan menambahkan baris yang akan dijalankan service network restart
.
Sayangnya saya tidak menemukan cara untuk membatasi secara rvim
memadai (pengguna masih dapat membuka file apa pun menggunakan :e
), jadi kami terjebak dengan nano
.
Sayangnya memungkinkan pengguna untuk mengedit banyak file jauh lebih sulit ...
Biarkan pengguna mengedit banyak file (jauh lebih sulit dari yang seharusnya)
1. Pendekatan yang tidak aman
Hati-hati dengan wildcard! Jika Anda menawarkan terlalu banyak fleksibilitas (atau fleksibilitas apa pun), itu dapat dieksploitasi:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
Dalam hal ini, pengguna jahat akan dapat mengedit skrip layanan pemula lainnya, dan kemudian menjalankannya:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo sebenarnya mencegah .
dan ..
memperluas perintah, tapi sayangnya tidak pada argumen.)
Saya berharap sesuatu seperti ini bisa berhasil, tetapi masih tidak aman:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
Karena sudo
saat ini hanya menawarkan pola gumpal , itu *
akan cocok dengan apa pun - itu bukan regexp!
(Sunting: Saya memang mempertimbangkan jika Anda mungkin lolos dengan hal di atas dalam situasi Anda, karena tidak ada sub-folder di bawah sites-available
. Kami memang meminta satu char dicocokkan setelah folder, dan /..
akan gagal setelah nama file. Namun ini bukan solusi yang bisa diterapkan, karena rnano
menerima beberapa argumen. Lagi pula secara umum ini masih tidak aman pada folder yang memiliki subfolder!)
Bahkan jika kita tidak memiliki subfolder, dan kita mengecualikan setiap baris yang mengandung /../
, aturan yang menawarkan *
bola dunia masih bisa dieksploitasi, karena rnano
menerima banyak argumen (beralih melalui mereka <C-X>
, dan ruang diterima dengan senang hati oleh *
bola.
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. Mendorong amplop (juga akhirnya tidak aman)
Jadi bagaimana jika kita menolak garis yang berisi spasi, atau berusaha menjangkau /..
? Maka solusi akhir yang bisa diterapkan adalah:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
Kami menerima apa pun "di bawah" folder tetapi kami juga menolak panggilan apa pun rnano
jika /..
atau /.
atau
diteruskan, atau jika folder ditargetkan secara langsung. (Secara teknis /.
eksklusi membuat eksklusi menjadi /..
berlebihan, tetapi saya telah meninggalkan keduanya untuk kejelasan.)
Saya menemukan folder dan /.
pengecualian diperlukan karena jika tidak pengguna dapat menargetkan folder itu sendiri. Sekarang Anda mungkin berpikir rnano
akan memblokir jika menunjuk ke folder, tetapi Anda akan salah. Sebenarnya versi saya (2.2.6-1ubuntu1) dimulai dengan peringatan ringan dan file kosong, lalu <C-X>
meminta saya untuk memasukkan nama file yang ingin saya simpan, membuka vektor serangan baru! Yah setidaknya itu menolak untuk menimpa file yang sudah ada (dalam satu tes yang saya lakukan). Bagaimanapun, karena tidak ada cara untuk memasukkan subfolder dengan sudo ke daftar hitam, kita harus menyimpulkan bahwa pendekatan ini sekali lagi tidak aman. Pengguna maaf!
Penemuan ini membuat saya meragukan ketelitian nano
mode "terbatas". Mereka mengatakan rantai hanya sekuat tautan terlemahnya. Saya mulai merasakan kombinasi sudo
black-magic hitam dan rnano
mungkin tidak lebih aman dari rantai aster.
3. Pendekatan yang aman tetapi terbatas
Glob sangat terbatas - mereka tidak membiarkan kami mencocokkan kelas karakter beberapa kali. Anda dapat menawarkan beberapa pengeditan file, jika semua nama file Anda memiliki panjang yang sama (dalam hal ini host
diikuti oleh satu digit):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
Tetapi jika Anda ingin memberikan akses kepada pengguna untuk mengedit berbagai file, Anda mungkin perlu menentukan setiap file secara eksplisit:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
Jangan tergoda untuk menggunakan suatu*
titik. Lihat bagian 1. dan 2. di atas untuk alasannya! Ingat: satu slip kecil dapat membahayakan seluruh akun pengguna super, dan seluruh sistem.
4. Tulis pemeriksa argumen Anda sendiri (keselamatan menjadi tanggung jawab Anda)
Saya berharap mereka akan menambahkan dukungan regexp sudo
di masa depan; itu bisa menyelesaikan banyak masalah jika digunakan dengan benar. Tetapi kita mungkin juga perlu kemampuan untuk memeriksa properti argumen (untuk mengizinkan hanya file, hanya folder, atau hanya flag tertentu).
Tetapi ada satu alternatif untuk menciptakan fleksibilitas dalam sudo. Lewati tanggung jawab:
%staff ALL = /root/bin/staffedit *
Kemudian tulis staffedit
skrip Anda sendiri atau dapat dieksekusi untuk memeriksa apakah argumen yang diberikan oleh pengguna adalah sah, dan hanya menjalankan permintaan mereka jika ada.
networking
dannetwork-manager
? Juga, mengapa pengguna Anda memilikisudo
akses? Mereka seharusnya tidak kecuali Anda ingin mereka memiliki hak root penuh.