Keanggotaan grup dan proses setuid / setgid

10

Proses yang menghilangkan hak istimewa melalui setuid()dan setgid()tampaknya tidak mewarisi keanggotaan grup dari uid / gid yang mereka tetapkan.

Saya memiliki proses server yang harus dijalankan sebagai root untuk membuka port istimewa; setelah itu de-meningkat ke uid / gid non-privilleged tertentu, 1 - misalnya, bahwa pengguna foo(UID 73). Pengguna fooadalah anggota grup bar:

> cat /etc/group | grep bar
bar:x:54:foo

Karenanya jika saya login sebagai foo, saya dapat membaca file /test.txtdengan karakteristik ini:

> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar  8 16:22 /test.txt

Namun, program C berikut (kompilasi std=gnu99), saat menjalankan root:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main (void) {
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}   

Selalu melaporkan, Izin ditolak . Saya membayangkan ini ada hubungannya dengan itu menjadi proses non-login, tapi itu semacam hamstrings cara izin seharusnya bekerja.


1. Yang sering menjadi SOP untuk server, dan saya pikir pasti ada jalan keluarnya ketika saya menemukan laporan seseorang yang melakukannya dengan apache - apache telah ditambahkan ke grup audio dan ternyata kemudian dapat menggunakan sistem suara. Tentu saja, ini kemungkinan terjadi dalam percabangan dan bukan proses asli, tetapi kenyataannya kasusnya sama dalam konteks saya (ini adalah proses anak yang bercabang setelah panggilan setuid).

goldilocks
sumber
Ganti setuid()/ setgid()panggil.
vonbrand
@vonbrand ROTFL Saya pikir saya berada di facepalm di sana - tapi hasilnya sama, jadi saya akan mengedit pertanyaan untuk menghilangkan herring merah.
goldilocks
1
Jika Anda menggunakan setgid(54)alih-alih setgid(73)(seperti pada /etc/groups, grup barmemiliki gid 54), apakah itu berfungsi?
lgeorget
@ Lgeorget Tentu, tapi itu mengalahkan tujuannya. Proses membutuhkan GID sendiri untuk alasan lain, dan juga, file-file itu harus memiliki izin yang mereka miliki. Itu sebabnya keanggotaan dalam kelompok jamak diperlukan - misalnya, bagaimana jika Anda memiliki dua pengguna yang perlu melakukan ini. Perhatikan Anda tidak bisa setuid()lagi setelah melakukannya ... tapi, hmmm ... Saya pikir Anda bisa dengan seteuid()...
goldilocks
1
Pertanyaan saya adalah memastikan tidak ada masalah tersembunyi yang tersembunyi di suatu tempat. :-)
lgeorget

Jawaban:

14

Masalahnya adalah itu setuiddan setgid tidak cukup untuk memberikan semua kredensial yang dibutuhkan proses Anda. Otorisasi suatu proses bergantung pada

  • UID nya
  • GID-nya
  • kelompok tambahannya
  • kemampuannya.

Lihat man 7 credentialsuntuk mendapatkan gambaran yang lebih rinci. Jadi, dalam kasus Anda, masalahnya adalah Anda mengatur UID dan GID dengan benar, tetapi Anda tidak mengatur kelompok pelengkap proses. Dan grup barmemiliki GID 54, no 73 sehingga tidak dikenali sebagai grup proses Anda.

Kamu seharusnya melakukan

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <grp.h>

int main (void) {
    gid_t supplementary_groups[] = {54};

    setgroups(1, supplementary_groups);
    setgid(73);
    setuid(73);
    int fd = open("/test.txt", O_RDONLY);
    fprintf(stderr,"%d\n", fd);
    return 0;
}  
lororget
sumber
1
Itu adalah pertanyaan menarik yang pantas mendapatkan lebih banyak suara karena sebenarnya bisa bermanfaat bagi banyak orang di luar sana. :-)
lgeorget
Jadi saya mengalami masalah serupa dengan port serial. Saya menerapkan ini untuk dialoutgrup dan itu bekerja pertama kali.
tl8
0

OK, sedikit di jaring sedikit. Awalnya saya berpikir bahwa APUE akan memegang semua jawaban, tetapi salah. Dan salinan saya (edisi lama) sedang bekerja, jadi ... Bab 5 Unix dan Linux Administration Handbook terlihat menjanjikan, tetapi saya belum mendapatkannya (hanya salinan dari dua edisi pertama, juga sedang bekerja).

Sumber daya kecil yang saya temukan (google untuk "daemon writing unix") semua berbicara tentang langkah-langkah penting, seperti cara memisahkan dari tty, dll. Tapi tidak ada yang tentang UID / GID. Anehnya, bahkan koleksi HOWTO yang luas di http://tldp.org tampaknya tidak memiliki perincian. Hanya excetion adalah Jason Short Mari Tulis Linux Daemon - bagian I . Detail lengkap tentang bagaimana SUID / SGID dan semua kekacauan itu bekerja adalah Chen, Wagner dan Dean , IDID yang didemistifikasi (sebuah makalah dalam USENIX 2002). Tapi hati-hati, Linux memiliki UID tambahan, FSUID (lihat Catatan Ketidakcocokan Unix Wolter : Fungsi Pengaturan UID untuk diskusi).

Mendemonstrasikan suatu proses jelas bukan untuk menjadi lemah hati. Pertimbangan keamanan umum diberikan dalam D. Pemrograman Aman Wheeler untuk Linux dan Unix HOWTO - Membuat Perangkat Lunak Aman . Systemd berjanji untuk menyederhanakan sebagian besar dari itu (dan dengan demikian mengurangi ruang untuk kesalahan yang mengarah pada masalah keamanan), lihat manual daemon .

vonbrand
sumber
1
Pertanyaannya bukan tentang daemonisasi. Anda telah mengacaukan bit SUID (memberikan proses izin dari pemiliknya yang dapat dieksekusi) dengan setuid(), yang memungkinkan proses untuk mengubah UID-nya secara sewenang-wenang. SUID biasanya dimaksudkan untuk memungkinkan peningkatan izin (non-privilleged -> privilleged), sedangkan setuid()hanya bisa melakukan sebaliknya.
goldilocks