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

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


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);
            }
...
}

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.


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"

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.