Jika Anda menambahkan bit setuid untuk izin file di mana Anda memiliki izin eksekusi, itu akan mengubah x
ke s
artinya jika Anda mengeksekusi file tersebut, file tersebut akan dieksekusi sebagai pemilik file, bukan sebagai orang yang benar-benar mengeksekusinya.
Tetapi saya juga memperhatikan bahwa jika Anda menambahkan s
izin tetapi hapus x
izin itu berubah menjadi S
dalam daftar izin. Entah bagaimana ini akan menyiratkan bahwa itu tidak dapat dieksekusi tetapi secara bersamaan akan dieksekusi sebagai pemilik jika dapat dieksekusi? Benarkah?
Apakah saya salah memahami izin ini? Untuk apa itu digunakan? Apa artinya?
Jawaban yang Diterima:
Keempat kombinasi ada dan bermakna.
“Dapatkah pemilik file ini menjalankannya?” dan “Siapa yang akan berpura-pura menjalankan file ini?” adalah dua pertanyaan terpisah. Keempat kombinasi itu mungkin dan bermakna.
String izin ditampilkan oleh ls -l
atau stat -c %A
tampilkan, di posisi eksekusi pemilik (yaitu, sebagai pengganti ?
di ---?------
), empat karakter berbeda, satu untuk setiap kombinasi:
-
berarti pemiliknya tidak bisa jalankan file tersebut dan, jika bukan pemilik yang menjalankannya, file tersebut akan berjalan sebagai pengguna lain itu .x
berarti pemiliknya bisa jalankan file tersebut dan, jika bukan pemilik yang menjalankannya, file tersebut akan berjalan sebagai pengguna lain itu .S
berarti pemiliknya tidak bisa jalankan file tersebut dan, jika bukan pemilik yang menjalankannya, file tersebut akan menjalankan sebagai pemiliknya .s
berarti pemiliknya bisa jalankan file tersebut dan, jika bukan pemilik yang menjalankannya, file tersebut akan menjalankan sebagai pemiliknya .
Bit setuid dan bit eksekusi adalah bit yang terpisah, dan mode string benar-benar hanya cara yang nyaman untuk melihat bit izin, termasuk itu. Cara lain untuk memikirkannya adalah:
x
ataus
berarti bit eksekusi diatur.-
atauS
berarti tidak.s
atauS
berarti bit setuid disetel.-
ataux
berarti tidak.
Demikian pula, grup mungkin atau mungkin tidak memiliki izin mengeksekusi pada file dan, jika dieksekusi, mungkin atau mungkin tidak dijalankan dengan identitas grup yang berbeda dari pengguna yang menjalankannya. Untuk menyebabkan file berjalan dengan identitas grup pemilik grupnya daripada identitas pengguna yang menjalankannya, Anda harus menyetel bit setgid (------s---
atau ------S---
).
S
tidak mewakili bit mode terpisah. Ini hanyalah cara untuk menandakan bahwa bit setuid (atau setgid) disetel tetapi bit yang dapat dieksekusi terkait tidak disetel.
$ touch foo
$ chmod u+S foo
chmod: invalid mode: ‘u+S’
Try 'chmod --help' for more information.
Anda dapat memeriksa bitnya sendiri.
Untuk melihat bahwa ini adalah bit yang terpisah, gunakan %a
penentu format untuk stat
bukannya %A
. Untuk menyederhanakan, saya telah menghapus semua bit mode lainnya.
$ touch a b c d
$ chmod u=,g=,o= a
$ chmod u=x,g=,o= b
$ chmod u=s,g=,o= c
$ chmod u=xs,g=,o= d
$ stat -c '%A %n' a b c d
---------- a
---x------ b
---S------ c
---s------ d
$ stat -c '%04a %n' a b c d
0000 a
0100 b
4000 c
4100 d
Itu membuatnya jelas ... jika Anda merasa nyaman dengan oktal. Jika Anda ingin melihatnya dalam biner (mereka adalah bit) Anda dapat mengonversi representasi:
$ stat -c '%a %n' a b c d | perl -pe 's/\d+/sprintf("%012b", oct($&))/e'
000000000000 a
000001000000 b
100000000000 c
100001000000 d
Setuid menyetel ID pengguna yang efektif, bukan ID pengguna yang sebenarnya.
Eksekusi bit mengontrol apakah upaya untuk menjalankan file dapat berhasil atau tidak, sementara bit setuid/setgid mengontrol identitas siapa yang menjalankan proses baru jika diizinkan untuk dibuat. Jadi tidak ada yang tidak konsisten atau mengejutkan tentang kombinasi izin S
mewakili (-x,+s
). Ini akan terjadi bahkan jika executable berjalan sebagai pemiliknya karena pemiliknya benar-benar menjalankannya bekerja persis sama dengan executable yang berjalan sebagai pemiliknya karena seseorang menjalankannya tetapi setuid. Tapi bukan itu cara kerjanya.
Kernel menggunakan lebih dari satu nomor untuk melacak identitas pengguna dari proses yang sedang berjalan. Salah satu nomor tersebut adalah UID, dan lainnya adalah EUID. Lihat artikel ini untuk detailnya. Bit setuid menyebabkan EUID (efektif user ID) berubah, tetapi UID (real user ID) tetap sama. Salah satu kegunaannya untuk memungkinkan pertukaran sinyal antara proses yang berbagi UID tetapi memiliki EUID yang berbeda, tetapi yang lain adalah memungkinkan program yang dirancang untuk mengatur bit setuidnya untuk memeriksa siapa yang menjalankannya .
Misalnya, passwd
harus disetel, karena hanya root yang dapat mengubah entri di basis data kata sandi:
$ ls -l "$(command -v passwd)"
-rwsr-xr-x 1 root root 54256 May 16 19:37 /usr/bin/passwd
-rwsr-xr-x
memiliki r-x
pada akhirnya, untuk lainnya . Karena x
, bahkan pengguna yang bukan root atau dalam grup root dapat menjalankan passwd
. Dan memiliki rws
dekat awal, untuk pemilik . Karena s
, program berjalan sebagai root, bahkan ketika non-pemilik menjalankannya. Tetapi ketika Anda menjalankan passwd
Anda sendiri, ini akan menyetel ulang sandi Anda, bukan root.
passwd
apakah mampu melakukan perubahan apa pun pada basis data pengguna dan kata sandi, karena berjalan dengan ID pengguna root yang efektif. Tapi itu dirancang untuk menolak mengubah kata sandi siapa pun kecuali pengguna yang menjalankannya–kecuali jika pengguna tersebut adalah root–karena ia memeriksa ID pengguna aslinya.
Ini adalah kasus penggunaan khas dari setuid yang dapat dieksekusi:untuk membuat antarmuka yang memungkinkan satu pengguna menyebabkan tindakan dilakukan sebagai yang lain, dengan cara terbatas yang diperiksa oleh kode dari setuid yang dapat dieksekusi. Jadi hanya aman untuk menyetel bit setuid (atau bit setgid) pada program yang dirancang untuk memiliki izin tersebut.
Ini adalah bagian lain dari teka-teki untuk memahami mengapa izin S
menandakan bukanlah teka-teki:kekuatan yang diberikan bit setuid tidak mencapai hal yang sama seperti menjalankan program sebagai pemiliknya , bahkan setelah program diizinkan untuk dijalankan.
Memeriksa UID dan EUID dengan salinan id
menunjukkan cara kerja setuid.
Oke, saya akan menyetel bit setuid pada executable yang tidak dirancang untuk itu, untuk menunjukkan bagaimana ID pengguna yang nyata dan efektif terpengaruh.
- Yang dapat dieksekusi adalah salinan dari
id
program yang, antara lain, melaporkan ID pengguna yang nyata dan efektif. Meskipun program ini tidak dirancang untuk disetel, program ini juga tidak dirancang untuk mengubah apa pun—kecuali dengan menghasilkan output—jadi ini cukup aman. Tetapi Anda tetap harus menghapusnya setelah itu. (Salinan Anda. Bukan yang asli.) - Kami menggunakan salinan, bukan mengubah izin pada aslinya. Anda tidak perlu menggunakan
sudo
atau lakukan tindakan apa pun sebagai root untuk ini. - Untuk menjalankannya sebagai pengguna lain, Anda memerlukan akun pengguna kedua, tetapi Anda dapat menggunakan
su
untuk melakukan tindakan sebagai itu pengguna. (Secara default,root
akun tidak memungkinkan Anda untuk masuk dengan kata sandi, jadi jika Anda membuat kesalahan dan menjalankansu
tanpa memberikan nama pengguna yang ingin Anda alihkan, Anda tidak akan berakhir menjadi root secara tidak sengaja, kecuali Anda juga telah mengaktifkan login root. Jika Anda benar-benar ingin menggunakansudo -u user
bukannyasu user -c
, meskipun, maka Anda bisa.)
Akun pengguna utama saya bernama ek
dan akun kedua saya adalah ek2
. Tidak apa-apa jika milikmu berbeda. Pertama, sebagai ek
, saya salin id
ke direktori saat ini (yang ada di suatu tempat di dalam direktori home saya):
$ type -a id
id is /usr/bin/id
$ cp /usr/bin/id .
Salinan memiliki kepemilikan pengguna non-root yang menyalinnya, tetapi izin aslinya:
$ ls -l id /usr/bin/id
-rwxr-xr-x 1 ek ek 39760 Oct 5 11:23 id
-rwxr-xr-x 1 root root 39760 Mar 2 2017 /usr/bin/id
Melewati -n
ke id
menunjukkan nama, bukan nomor ID, -u
menunjukkan pengguna (dan bukan informasi lain seperti grup), dan -r
menyebabkan ID pengguna yang sebenarnya ditampilkan. Tanpa -r
, -u
menunjukkan ID pengguna yang efektif. Perilaku ini berlaku sepenuhnya untuk salinan dari id
Saya baru saja membuat.
Ketika saya menjalankannya sebagai pengguna pengganti, ID pengguna yang nyata dan efektif keduanya berubah. Ini adalah bagian dari cara su
dan sudo
ditulis, dan bukan hanya hasil dari su
itu sendiri menjadi root setuid, meskipun itu. (Inilah sebabnya saya menggunakan passwd
sebagai contoh dari setuid yang dapat dieksekusi, bukan su
atau sudo
.) Ini adalah dasar kami, untuk melihat bahwa id
di direktori saat ini berfungsi seperti yang diharapkan:
$ ./id -nu # ek runs id, displaying the effective user
ek
$ ./id -nur # ek runs id, displaying the real user
ek
$ su ek2 -c './id -nu' # ek2 runs id, displaying the effective user
Password:
ek2
$ su ek2 -c './id -nur' # ek2 runs id, displaying the real user
Password:
ek2
Sekarang saya membuat salinan lokal id
setuid:
$ chmod u+s id
$ ls -l id
-rwsr-xr-x 1 ek ek 39760 Oct 5 11:42 id
Sekarang ketika saya menjalankannya, ID pengguna yang sebenarnya adalah pengguna yang menjalankannya, sedangkan ID pengguna yang efektif adalah ek
bahkan ketika ek2
menjalankannya:
$ ./id -nu # ek runs id, displaying the effective user
ek
$ ./id -nur # ek runs id, displaying the real user
ek
$ su ek2 -c './id -nu' # ek2 runs id, displaying the effective user
Password:
ek
$ su ek2 -c './id -nur' # ek2 runs id, displaying the real user
Password:
ek2
Sekarang saya mengambil izin yang dapat dieksekusi dari pemiliknya tetapi membiarkannya untuk orang lain:
$ chmod u-x id
$ ls -l id
-rwSr-xr-x 1 ek ek 39760 Oct 5 11:42 id
ek2
masih bisa menjalankannya seperti dengan ek
ID pengguna yang efektif, meskipun ek
tidak dapat menjalankannya:
$ ./id -nu # ek runs id, displaying the effective user
-bash: ./id: Permission denied
$ ./id -nur # ek runs id, displaying the real user
-bash: ./id: Permission denied
$ su ek2 -c './id -nu' # ek2 runs id, displaying the effective user
Password:
ek
$ su ek2 -c './id -nur' # ek2 runs id, displaying the real user
Password:
ek2
Tapi, seperti yang ditunjukkan, ini tidak menghasilkan hasil yang sama seperti ek
benar-benar menjalankannya. ek2
benar-benar tidak bisa melakukan apa ek
bisa dilakukan jika ek
diizinkan untuk menjalankan program, kecuali jika program mengizinkannya.
(Setelah itu, saya menjalankan rm id
untuk menghapus file, jadi saya tidak akan memiliki executable setuid yang tidak perlu tergeletak di direktori home saya. Atau Anda bisa menghapus setuid bit dengan chmod -s id
.)