Jatuhkan Hak Istimewa Proses

12

Saya memiliki proses yang dimulai dengan damon berjalan sebagai root, sekarang saya ingin "menurunkan" hak istimewa proses ini ke orang-orang dari pengguna rata-rata Anda. Apakah ini mungkin? Jika ya, bagaimana?

PS: Menjalankan unix di mac

Samantha Catania
sumber

Jawaban:

5

Prosesnya sendiri harus memanggil setuid (2). Anda juga harus menyelidiki menjalankannya di dalam chroot (8) jika Anda belum melakukannya. Sejauh yang saya tahu, tidak ada cara bagi root untuk mengubah cairan proses lain.

Jika alasan Anda menjalankannya sebagai root adalah untuk mengikat port, saya sarankan menjalankannya sebagai pengguna normal pada port yang lebih tinggi dan menggunakan ipfw (8) pada OS X untuk meneruskan port 80/443 / etc ke port yang lebih tinggi:

http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx

jumlahnya banyak
sumber
Saya meletakkan setuid (uid) dalam program saya yang berjalan sebagai root tetapi saya membutuhkannya untuk dijalankan sebagai pengguna normal & tidak ada yang terjadi yaitu ia terus berjalan sebagai root
Samantha Catania
Anda mungkin perlu menangkap kesalahan dari itu (mungkin Anda mendapatkan EINVAL untuk uid). Setuid yang tidak mungkin rusak pada mesin Anda, Anda dapat memverifikasi dengan melihat apakah apache berjalan sebagai _www. Dokumen pemrogram: developer.apple.com/library/mac/#documentation/Darwin/Reference/…
polinomial
Anda benar itu memberikan kesalahan sintaks dari uid meskipun sudah benar. apakah ini format setuid yang tepat (500)?
Samantha Catania
menemukan masalah: Saya mencoba menjalankan perintah melalui sistem () tetapi saya hanya menjalankan perintah itu berfungsi & menyelesaikan masalah saya; Terima kasih atas bantuannya
Samantha Catania
Tidak. Ini bukan saran yang bagus: menelepon setuid()seorang diri sama sekali tidak cukup.
Nicholas Wilson
13

sudo tcpdump -Z menggunakan initgroups (3), setgid (2) dan setuid (2) untuk menghentikan hak root dari prosesnya sendiri.

# code taken from: 
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c

/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
            if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
               setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
                    fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
                        username, 
                        (unsigned long)pw->pw_uid,
                        (unsigned long)pw->pw_gid,
                        pcap_strerror(errno));
                    exit(1);
            }
...
}
phron
sumber
2
Benar. initgroups, setgid, setuid(Terakhir!) Justru paradigma yang tepat pada unix, dan harus selalu diikuti. Selain itu, fungsi "droproot" yang bertanggung jawab memeriksa apakah uid dan gidnya benar-benar telah disetel, meskipun ketiga fungsi utama tersebut mengembalikan kesuksesan.
Nicholas Wilson
3

Anda dapat menjalankan perintah sebagai pengguna lain menggunakan su:

 su USERNAME -c COMMAND

Akan berjalan COMMANDdengan hak istimewa turun ke USER.


Perhatikan bahwa, secara default, suakan menggunakan penerjemah shell pengguna target untuk menjalankan perintah. Sebaliknya, perilaku default sudoadalah memperlakukan COMMANDprogram mandiri, yang menjalankan lingkungan saat ini. Tentu saja perilaku default ini dapat diubah dengan berbagai sakelar dan variabel lingkungan.

rozcietrzewiacz
sumber
Sepertinya sutidak berfungsi jika USERNAME tidak memiliki shell yang ditentukan (atau /bin/false) sedangkan sudo tidak berfungsi.
Aif
1
@Aif Jika pengguna tidak diizinkan menjalankan perintah interaktif, maka perilaku defaultsu akan mencerminkan hal itu. Namun, kita selalu bisa menimpanya menggunakan -ssakelar. Perhatikan bahwa tujuannya suadalah untuk meniru perilaku pengguna tertentu - yang biasanya dipengaruhi oleh cangkangnya. Sebaliknya, sudoakan (secara default) mengabaikan pengaturan shell pengguna target.
rozcietrzewiacz
Tidak, tolong jangan menjalankan sesuatu menggunakan shell hanya untuk menjatuhkan hak istimewa. Itu meninggalkan terlalu banyak dalam kendali penyerang, membaca berbagai file konfigurasi yang tidak ingin Anda sentuh.
Nicholas Wilson
2

Untuk melepaskan hak istimewa, Anda perlu pengguna non-root untuk berpindah. Maka itu hanya masalah beralih ke pengguna itu:

#define UNPRIV_UID  48
#define UNPRIV_GID  48

if (getuid() == 0) { // we are root
    // setting UID/GID requires root privileges, so if you don't set
    // the GID first, you won't be able to do it at all.
    if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
    if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}

ASSERT(getuid() != 0); 

Perhatikan bahwa ini dilakukan dalam program itu sendiri, bukan dalam skrip pembungkus. Banyak program memerlukan hak akses root untuk beberapa tujuan tertentu (misalnya untuk mengikat ke port bernomor rendah), tetapi tidak perlu root setelah itu. Jadi program-program ini akan mulai sebagai root, tetapi kemudian menjatuhkan hak istimewa begitu mereka tidak lagi diperlukan.

Jika Anda sama sekali tidak memerlukan hak akses root, maka jangan jalankan sebagai root. Misalnya:

# Change this:
myprog -C /my/config/file

# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
tylerl
sumber
1
Perhatikan bahwa ini memungkinkan proses untuk memulihkan hak istimewa jika diinginkan! The setuidFungsi hanya menetapkan efektif UID, bukan UID nyata. Anda harus menggunakan setreuidjika Anda tidak ingin prosesnya bisa mendapatkan hak istimewa kembali. (Dan kode di atas juga tidak berhubungan dengan hak istimewa kelompok tambahan. Ini hanya cocok untuk meluncurkan kode yang sebagian besar tepercaya.)
David Schwartz
@David Schwartz sengaja disederhanakan untuk menunjukkan mekanisme yang digunakan.
tylerl
Jika Anda akan menyederhanakan kode penting keamanan, Anda harus membuatnya sangat jelas bahwa inilah yang Anda lakukan. Dan Anda harus mengatakan hal-hal seperti "itu hanya masalah" padahal tidak.
David Schwartz
2
@ David Sebenarnya, setuid()mengatur pengguna yang nyata dan disimpan; Anda mungkin berpikir seteuid(). Tidak semua sistem memiliki setreuid(), jadi itu tidak dapat digunakan di mana-mana. Semantik yang tepat dari setuid()yang terlibat, tetapi jika Anda memiliki euid 0, Anda akan dapat meninggalkan semua hak pengguna-id tradisional dengan setuid(). Kelalaian terbesar dalam jawaban ini adalah bahwa initgroupsatau setgroupsharus dipanggil juga setgiddan setuid, dan bahwa pernyataan yang lebih menyeluruh harus dilakukan pada akhirnya.
Nicholas Wilson
0

Jika Anda menjalankan executable yang berbeda, yaitu Anda memanggil execveatau execfungsi keluarga lainnya, mungkin secara tidak langsung melalui fungsi seperti systematau popen, dan proses anak harus dijalankan tanpa hak istimewa sejak awal, maka cara paling sederhana adalah untuk mendapatkan shell yang terlibat, dan telepon su. Berikut ini gambaran umum tentang bagaimana kode tersebut terlihat di Perl, menunjukkan kutipan yang diperlukan untuk:

$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;

Jika proses anak perlu memulai sebagai root tetapi kemudian menghapus hak istimewa, lihat kode dalam jawaban ini , yang mengilustrasikan cara menurunkan peringkat hak istimewa dalam suatu proses.

Gilles 'SANGAT berhenti menjadi jahat'
sumber