Yang berubah adalah /bin/sh
itu entah menjadi bash
atau tinggal dash
yang mendapat flag tambahan -p
meniru perilaku bash.
Bash membutuhkan -p
tandai untuk tidak menghapus hak istimewa setuid seperti yang dijelaskan di halaman manualnya:
Jika shell dimulai dengan id pengguna (grup) efektif yang tidak sama dengan id pengguna (grup) sebenarnya, dan opsi -p tidak disediakan, tidak ada file startup yang dibaca, fungsi shell tidak diwariskan dari lingkungan, SHELLOPTS, Variabel BASHOPTS, CDPATH, dan GLOBIGNORE, jika muncul di lingkungan, diabaikan, dan id pengguna yang efektif disetel ke id pengguna sebenarnya . Jika opsi -p disediakan saat pemanggilan, perilaku pengaktifan sama, tetapi id pengguna yang efektif tidak disetel ulang.
Sebelumnya, dash
tidak peduli tentang ini dan mengizinkan eksekusi setuid (dengan tidak melakukan apa pun untuk mencegahnya). Tapi dash
Ubuntu 16.04 halaman manualnya memiliki opsi tambahan yang dijelaskan, mirip dengan bash
:
-p pribadi
Jangan mencoba mengatur ulang uid yang efektif jika tidak cocok dengan uid. Ini tidak disetel secara default untuk membantu menghindari penggunaan yang salah program root bysetuid melalui system(3) atau popen(3).
Opsi ini tidak ada di upstream (yang mungkin tidak reaktif terhadap tambalan yang diusulkan) atau Debian 9 tetapi ada di buster Debian yang mendapatkan tambalan sejak 2018.
CATATAN:seperti yang dijelaskan oleh Stéphane Chazelas, sudah terlambat untuk memanggil "/bin/sh -p"
di system()
karena system()
menjalankan apa pun yang diberikan melalui /bin/sh
dan setuid sudah dijatuhkan. jawaban derobert menjelaskan cara menangani ini, dalam kode sebelum system()
.
detail lebih lanjut tentang sejarah di sana-sini.
Mungkin shell mengubah ID pengguna efektifnya kembali ke ID pengguna asli sebagai bagian dari permulaannya karena beberapa alasan. Anda dapat memverifikasi ini dengan menambahkan:
/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);
sebelum system()
Anda . (Sebenarnya, bahkan di Linux, Anda mungkin hanya perlu menyetel yang asli; yang disimpan sebaiknya dibiarkan saja. Ini hanya kekerasan untuk debug. Bergantung pada mengapa Anda set-id, tentu saja Anda mungkin perlu untuk menyimpan ID asli di suatu tempat juga.)
[Juga, jika ini bukan hanya latihan mempelajari cara kerja setid, maka ada banyak masalah keamanan yang perlu dikhawatirkan, terutama saat memanggil shell. Ada banyak variabel lingkungan, misalnya, yang memengaruhi perilaku shell. Lebih suka pendekatan yang sudah ada seperti sudo
jika memungkinkan.]