ปล่อยสิทธิพิเศษของกระบวนการ


12

ฉันมีกระบวนการที่เริ่มต้นโดย damon ที่เรียกใช้ในฐานะ root ตอนนี้ฉันต้องการ "ลดระดับ" สิทธิ์ของกระบวนการนี้ให้กับผู้ใช้ทั่วไปของคุณ เป็นไปได้ไหม ถ้าใช่เป็นอย่างไร

PS: การเรียกใช้ unix บนเครื่อง mac

คำตอบ:


5

กระบวนการต้องเรียก setuid (2) คุณควรตรวจสอบการใช้ภายใน chroot (8) หากยังไม่ได้ดำเนินการ เท่าที่ฉันรู้ไม่มีทางรูทที่จะเปลี่ยน uid ของกระบวนการอื่นได้

หากเหตุผลที่คุณใช้เป็นรูทคือการผูกพอร์ตผมขอแนะนำให้ใช้มันเป็นผู้ใช้ปกติบนพอร์ตที่สูงกว่าและใช้ ipfw (8) บน OS X เพื่อส่งต่อพอร์ต 80/443 / etc ไปยังพอร์ตที่สูงกว่า:

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


ฉันใส่ setuid (uid) ในโปรแกรมของฉันที่รันเป็น root แต่ฉันต้องการให้มันทำงานแบบผู้ใช้ปกติและไม่มีอะไรเกิดขึ้นเช่นมันยังคงทำงานเป็น root
Samantha Catania

คุณอาจต้องจับข้อผิดพลาดจากนั้น (บางทีคุณอาจได้รับ EINVAL สำหรับ uid) setuid ที่ไม่น่าจะเกิดขึ้นมันเสียบนเครื่องของคุณคุณสามารถตรวจสอบได้โดยดูว่า apache ทำงานเป็น _www โปรแกรมเมอร์ docs: developer.apple.com/library/mac/#documentation/Darwin/Reference/…
polynomial

คุณพูดถูกมันมีข้อผิดพลาดทางไวยากรณ์จาก uid แม้ว่ามันจะถูกต้องก็ตาม นี่เป็นรูปแบบที่ถูกต้อง setuid (500) หรือไม่
ซาแมนธาคาตาเนีย

พบปัญหา: ฉันกำลังพยายามเรียกใช้คำสั่งผ่านระบบ () แต่ฉันเพิ่งเรียกใช้คำสั่งที่ทำงาน & แก้ไขปัญหาของฉัน; ขอบคุณสำหรับความช่วยเหลือ
Samantha Catania

ไม่นี่ไม่ใช่คำแนะนำที่ดี: การโทรsetuid()คนเดียวไม่เพียงพอ
นิโคลัสวิลสัน

13

sudo tcpdump -Z ใช้กลุ่มเริ่มต้น (3), setgid (2) และ setuid (2) เพื่อปล่อยสิทธิ์รูทของกระบวนการของตัวเอง

# 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
แก้ไข. initgroups, setgid, setuid(ที่ผ่านมา) เป็นอย่างแม่นยำกระบวนทัศน์ทางด้านขวาบนยูนิกซ์และควรได้รับการปฏิบัติตาม นอกจากนี้ฟังก์ชั่น "droproot" ที่รับผิดชอบจะตรวจสอบว่ามีการตั้งค่า uid และ gid จริง ๆ แม้ว่าฟังก์ชันหลักทั้งสามจะกลับมาประสบความสำเร็จ
Nicholas Wilson

3

คุณสามารถเรียกใช้คำสั่งในฐานะผู้ใช้รายอื่นโดยใช้su:

 su USERNAME -c COMMAND

จะทำงานที่มีสิทธิ์ที่จะปรับตัวลดลงCOMMANDUSER


โปรดทราบว่าโดยค่าเริ่มต้นsuจะใช้ตัวแปลเชลล์ของผู้ใช้เป้าหมายเพื่อรันคำสั่ง ในทางตรงกันข้ามพฤติกรรมเริ่มต้นของsudoคือการปฏิบัติต่อCOMMANDเป็นโปรแกรมแบบสแตนด์อโลนที่เรียกใช้สภาพแวดล้อมปัจจุบัน แน่นอนพฤติกรรมเริ่มต้นเหล่านี้สามารถเปลี่ยนแปลงได้ด้วยสวิตช์และตัวแปรสภาพแวดล้อมต่างๆ


ดูเหมือนว่าsuจะไม่ทำงานหาก USERNAME ไม่มีการกำหนดเชลล์ (หรือ/bin/false) ในขณะที่ sudo ทำงาน
Aif

1
@Aif หากผู้ใช้ไม่ได้รับอนุญาตให้เรียกใช้คำสั่งแบบโต้ตอบพฤติกรรมเริ่มต้นsuจะแสดงให้เห็นว่า อย่างไรก็ตามหนึ่งสามารถแทนที่ที่ใช้-sสวิตช์ โปรดทราบว่าจุดประสงค์suคือเพื่อเลียนแบบพฤติกรรมของผู้ใช้ที่กำหนดซึ่งโดยปกติจะได้รับอิทธิพลจากเปลือกของเขา / เธอ ในทางตรงกันข้ามsudoจะ (โดยค่าเริ่มต้น) ละเว้นการตั้งค่าเปลือกของผู้ใช้เป้าหมาย
rozcietrzewiacz

ไม่ได้โปรดอย่าใช้สิ่งต่าง ๆ โดยใช้เชลล์เพียงเพื่อปล่อยสิทธิพิเศษ สิ่งนี้ทำให้การควบคุมของผู้โจมตีมีมากเกินไปอ่านไฟล์ปรับแต่งต่าง ๆ ที่คุณไม่ต้องการสัมผัส
นิโคลัสวิลสัน

2

ในการลบสิทธิ์คุณต้องมีผู้ใช้ที่ไม่ใช่รูทเพื่อเลื่อนไป จากนั้นเป็นเรื่องของการสลับไปใช้ผู้ใช้นั้น:

#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); 

โปรดทราบว่าสิ่งนี้จะกระทำภายในโปรแกรมเองแทนที่จะเป็นสคริปต์ตัวตัดคำ หลายโปรแกรมต้องการสิทธิ์รูทสำหรับวัตถุประสงค์เฉพาะ (เช่นผูกเข้ากับพอร์ตที่มีหมายเลขต่ำ) แต่ไม่ต้องการรูทหลังจากนั้น ดังนั้นโปรแกรมเหล่านี้จะเริ่มต้นเป็นรูท แต่จากนั้นให้ลบสิทธิ์เมื่อไม่ต้องการใช้อีกต่อไป

หากคุณไม่ต้องการสิทธิ์รูทเลยเพียงแค่เรียกใช้ในฐานะรูท เช่น:

# 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
โปรดทราบว่านี่จะช่วยให้กระบวนการกู้คืนสิทธิพิเศษได้หากต้องการ! setuidฟังก์ชั่นเพียงชุดที่มีประสิทธิภาพ UID ไม่ได้โพสต์จริง คุณควรใช้setreuidหากคุณไม่ต้องการให้กระบวนการได้รับสิทธิ์คืน (และรหัสด้านบนไม่ได้จัดการกับสิทธิ์พิเศษของกลุ่มเพิ่มเติมเหมาะสำหรับการเปิดใช้รหัสที่เชื่อถือได้ส่วนใหญ่เท่านั้น)
David Schwartz

@David รหัส Schwartz ถูกทำให้ง่ายขึ้นโดยเจตนาเพื่อแสดงกลไกที่ใช้
tylerl

หากคุณกำลังจะลดความซับซ้อนของรหัสรักษาความปลอดภัยที่สำคัญคุณต้องทำให้มันมากชัดเจนว่านี่คือสิ่งที่คุณกำลังทำ และคุณควรพูดว่า "มันเป็นเรื่องของ" เมื่อมันไม่ใช่
David Schwartz

2
@David จริง ๆ แล้วsetuid()ตั้งค่า userids จริงและบันทึกไว้; seteuid()คุณอาจจะคิดของ ระบบบางระบบไม่มีsetreuid()ดังนั้นจึงไม่สามารถใช้งานได้ทุกที่ ความหมายที่แท้จริงของsetuid()กำลัง compliced แต่ถ้าคุณมี EUID 0, setuid()คุณจะสามารถที่จะลดสิทธิพิเศษในการใช้รหัสแบบดั้งเดิมทั้งหมดที่มี การละเลยที่ใหญ่ที่สุดในคำตอบนี้ก็คือว่าinitgroupsหรือsetgroupsจะต้องเรียกว่าเช่นเดียวกับsetgidและsetuidและที่ยืนยันอย่างละเอียดมากขึ้นควรจะทำในตอนท้าย
Nicholas Wilson

0

หากคุณกำลังดำเนินการปฏิบัติการที่แตกต่างกันเช่นคุณกำลังเรียกexecveหรืออื่น ๆ ของexecฟังก์ชั่นของครอบครัวอาจจะทางอ้อมผ่านฟังก์ชั่นเช่นsystemหรือpopenและกระบวนการเด็กควรทำงานโดยไม่มีสิทธิ์ตั้งแต่เริ่มต้นวิธีที่ง่ายที่สุดคือการรับ suเปลือกที่เกี่ยวข้องและการโทร ต่อไปนี้เป็นภาพรวมของโค้ดที่ดูเหมือนใน Perl โดยแสดงข้อความที่ต้องการสำหรับ:

$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;

หากกระบวนการลูกต้องเริ่มจากรูท แต่ปล่อยสิทธิพิเศษในภายหลังดูรหัสในคำตอบนี้ซึ่งแสดงวิธีการดาวน์เกรดสิทธิ์ในกระบวนการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.