Mengapa bit setuid bekerja secara tidak konsisten?

8

Saya menulis kode:

// a.c
#include <stdlib.h>
int main () {
  system("/bin/sh");
  return 0;
}

dikompilasi dengan perintah:

gcc a.c -o a.out

menambahkan bit setuid di atasnya:

sudo chown root.root a.out
sudo chmod 4755 a.out

Di Ubuntu 14.04, ketika saya menjalankan sebagai pengguna umum, saya mendapat hak akses root.

tetapi pada Ubuntu 16.04, saya masih mendapatkan shell pengguna saat ini.

Kenapa berbeda?

pengguna10883182
sumber

Jawaban:

9

Apa yang berubah adalah /bin/shapakah menjadi bashatau tetap dashyang mendapat bendera tambahan yang -pmeniru perilaku bash.

Bash mengharuskan -pbendera untuk tidak membatalkan hak setuid seperti yang dijelaskan dalam halaman manualnya :

Jika shell dimulai dengan id pengguna (grup) yang efektif tidak sama dengan id pengguna (grup) yang sebenarnya, dan opsi -p tidak disediakan, tidak ada file startup yang dibaca, fungsi shell tidak diwarisi dari lingkungan, SHELLOPTS , Variabel BASHOPTS, CDPATH, dan GLOBIGNORE, jika muncul di lingkungan, diabaikan, dan id pengguna yang efektif ditetapkan ke id pengguna yang sebenarnya . Jika opsi -p disediakan saat doa, perilaku startup adalah sama, tetapi id pengguna yang efektif tidak diatur ulang.

Sebelumnya, dashtidak peduli tentang ini dan mengizinkan eksekusi setuid (dengan tidak melakukan apa pun untuk mencegahnya). Tetapi manual Ubuntu 16.04'sdash memiliki opsi tambahan yang dijelaskan, mirip dengan bash:

-p priv
Jangan mencoba mengatur ulang uid yang efektif jika tidak cocok dengan uid. Ini tidak diatur secara default untuk membantu menghindari penggunaan yang salah oleh program root setuid melalui sistem (3) atau popen (3).

Opsi ini tidak ada di hulu (yang mungkin tidak reaktif terhadap patch yang diusulkan * ) atau Debian 9 tetapi hadir dalam buster Debian yang mendapatkan patch sejak 2018.

CATATAN: seperti yang dijelaskan oleh Stéphane Chazelas, sudah terlambat untuk memohon "/bin/sh -p"di system()karena system()berjalan apapun yang diberikan melalui /bin/shdan setuid yang sudah dijatuhkan. Jawaban derobert menjelaskan bagaimana menangani ini, dalam kode sebelumnya system().

* lebih detail tentang sejarah di sana - sini .

AB
sumber
system("bash -p")berjalan sh -c "bash -p"sehingga hak istimewa telah dijatuhkan ketika bashdieksekusi.
Stéphane Chazelas
oh baiklah. Saya akan menghapus bagian "solusi" yang lebih baik ditangani oleh jawaban derobert.
AB
Lihat juga bugs.debian.org/cgi-bin/bugreport.cgi?bug=734869
Stéphane Chazelas
Sepertinya Ubuntu fixed dash di wily (15.10). bugs.launchpad.net/ubuntu/+source/dash/+bug/1215660
Mark Plotnick
1
Perhatikan bahwa Debian dulu sebaliknya. Ini digunakan untuk menambal bash agar tidak menjatuhkan hak istimewa. Apakah ini merupakan peningkatan, masih bisa diperdebatkan. Sekarang, orang-orang yang ingin melakukan system()dengan hak yang lebih tinggi (yang, memang, mereka seharusnya tidak di tempat pertama) akhirnya melakukan setresuid()sebelum yang jauh lebih buruk karena shell tidak tahu itu suid jadi tidak aktifkan mode di mana ia tidak mempercayai lingkungannya.
Stéphane Chazelas
8

Mungkin shell mengubah ID pengguna yang efektif kembali ke ID pengguna yang sebenarnya sebagai bagian dari startup untuk 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 Anda system(). (Sebenarnya, bahkan di Linux, Anda mungkin hanya perlu mengatur yang asli; yang disimpan harus baik-baik saja untuk dibiarkan sendiri. Ini hanya kekuatan kasar untuk debug. Tergantung pada mengapa Anda ditetapkan-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 mempengaruhi perilaku shell. Pilih pendekatan yang sudah ada seperti sudojika memungkinkan.]

derobert
sumber
Saya berkonsentrasi pada mengapa itu berubah, sementara Anda memberikan cara untuk menghindari masalah tersebut. +1
AB
Tentu saja, jika Anda benar-benar membutuhkan tempat untuk menyimpan ID asli, ID yang disimpan adalah tempat yang sangat nyaman untuk melakukannya. Terutama jika ID efektif tidak root: root.
Kevin