การเป็นสมาชิกกลุ่มและกระบวนการ setuid / setgid


10

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

ฉันมีกระบวนการเซิร์ฟเวอร์ที่ต้องดำเนินการเป็นรูทเพื่อเปิดพอร์ตสิทธิพิเศษ หลังจากนั้นจะยกเลิกการเลื่อนระดับไปเป็น uid / gid ที่ไม่มีสิทธิพิเศษเฉพาะ1 - เช่นของผู้ใช้foo(UID 73) ผู้ใช้fooเป็นสมาชิกของกลุ่มbar:

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

ดังนั้นถ้าฉันเข้าสู่ระบบในฐานะfooฉันสามารถอ่านไฟล์ที่/test.txtมีคุณสมบัติเหล่านี้:

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

อย่างไรก็ตามโปรแกรม C ต่อไปนี้ (คอมไพล์std=gnu99) เมื่อรันรูท:

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

รายงานการอนุญาตถูกปฏิเสธเสมอ ฉันคิดว่าสิ่งนี้เกี่ยวข้องกับการเป็นกระบวนการที่ไม่ใช่การเข้าสู่ระบบ แต่เป็นการขัดขวางวิธีที่สิทธิ์ควรทำงาน


1. ซึ่งมักจะเป็น SOP สำหรับเซิร์ฟเวอร์และฉันคิดว่าต้องมีวิธีแก้ปัญหานี้เนื่องจากฉันพบรายงานว่ามีคนทำด้วย Apache - เพิ่ม Apache ลงในกลุ่มเสียงและสามารถใช้ระบบเสียงได้ แน่นอนว่าสิ่งนี้อาจเกิดขึ้นในทางแยกและไม่ใช่กระบวนการดั้งเดิม แต่ในความเป็นจริงกรณีนี้เหมือนกันในบริบทของฉัน (เป็นกระบวนการลูกที่แยกหลังจากการเรียก setuid)


สลับsetuid()/ setgid()โทรไปรอบ ๆ
vonbrand

@vonbrand ROTFLฉันคิดว่าฉันเป็นในการ facepalm มี - แต่ผลเดียวกันดังนั้นฉันจะแก้ไขคำถามในการกำจัดควันสีแดง
goldilocks

1
หากคุณใช้setgid(54)แทนsetgid(73)(เหมือนใน/etc/groupsกลุ่มbarมี gid 54) ใช้งานได้หรือไม่
lgeorget

@ lgeorget แน่นอน แต่นั่นเป็นจุดประสงค์ กระบวนการต้องการ GID ของตัวเองด้วยเหตุผลอื่นเช่นเดียวกันไฟล์เหล่านั้นจะต้องได้รับอนุญาต นั่นเป็นเหตุผลที่จำเป็นต้องมีการเป็นสมาชิกพหูพจน์ของกลุ่ม - เช่นถ้าคุณมีผู้ใช้สองคนที่ต้องทำสิ่งนี้ โปรดทราบว่าคุณไม่สามารถทำได้setuid()อีกหลังจากที่คุณทำ ... แต่ hmmm ... ฉันคิดว่าคุณสามารถทำได้seteuid()...
goldilocks

1
คำถามของฉันคือต้องแน่ใจว่าไม่มีปัญหาที่ซ่อนเร้นอยู่ที่ไหนสักแห่ง :-)
lgeorget

คำตอบ:


14

ปัญหาคือว่าsetuidและsetgid ไม่เพียงพอที่จะให้กระบวนการของคุณข้อมูลประจำตัวทั้งหมดที่ต้องการ การอนุญาตของกระบวนการขึ้นอยู่กับ

  • UID ของมัน
  • GID ของมัน
  • กลุ่มเสริม
  • ความสามารถของมัน

ดูman 7 credentialsเพื่อรับภาพรวมโดยละเอียดเพิ่มเติม ดังนั้นในกรณีของคุณปัญหาคือคุณตั้งค่า UID และ GID อย่างถูกต้อง แต่คุณไม่ได้ตั้งกลุ่มเสริมของกระบวนการ และกลุ่มbarมี GID 54, 73 ไม่ดังนั้นจึงไม่ได้รับการยอมรับว่าเป็นกระบวนการของคุณ

คุณควรทำ

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

1
นั่นเป็นคำถามที่น่าสนใจที่สมควรได้รับการโหวตมากขึ้นเพราะจริง ๆ แล้วมันจะมีประโยชน์กับคนจำนวนมาก :-)
lgeorget

ดังนั้นฉันจึงมีปัญหาที่คล้ายกันกับพอร์ตอนุกรม ฉันนำสิ่งนี้ไปใช้กับdialoutกลุ่มและใช้งานได้เป็นครั้งแรก
tl8

0

ตกลง trawled รอบ ๆ เน็ตเล็กน้อย ตอนแรกฉันคิดว่าAPUEจะตอบทุกคำถาม แต่ผิดพลาด และสำเนาของฉัน (รุ่นเก่า) ทำงานอยู่ดังนั้น ... บทที่ 5 ของUnix และ Linux Administration Handbookดูมีแนวโน้ม แต่ฉันไม่ได้รับมัน

แหล่งข้อมูลเล็ก ๆ ที่ฉันพบ (google สำหรับ "daemon writing unix") ทั้งหมดพูดคุยเกี่ยวกับขั้นตอนสำคัญเช่นวิธีแยกตัวออกจาก tty เป็นต้น แต่ไม่มีอะไรเกี่ยวกับ UID / GID น่าแปลกที่แม้แต่คอลเล็กชั่น HOWTO ที่http://tldp.org ก็ดูเหมือนจะมีรายละเอียด ข้อยกเว้นเพียงอย่างเดียวคือ Jason Short's Let's Write a Linux Daemon - ตอนที่ 1 รายละเอียดทั้งหมดเกี่ยวกับวิธีที่ SUID / SGID และงานที่ยุ่งเหยิงคือเฉินแว็กเนอร์และคณบดีของSUID ทำการศึกษาอย่างชัดเจน (บทความใน USENIX 2002) แต่ระวังด้วย, Linux มี UID พิเศษ, FSUID (ดูหมายเหตุ Uncompatibility Unixของ Wolter : ฟังก์ชั่นการตั้งค่า UIDสำหรับการอภิปราย)

การกำหนดกระบวนการไม่เหมาะกับคนใจร้อน การพิจารณาความปลอดภัยทั่วไปจะได้รับในดีวีลเลอร์ของโปรแกรมรักษาความปลอดภัยสำหรับ Linux และ Unix HOWTO - การสร้างซอฟแวร์รักษาความปลอดภัย Systemdสัญญาว่าจะลดความซับซ้อนมากที่สุดของที่ (และดังนั้นการลดห้องพักสำหรับความผิดพลาดที่นำไปสู่ปัญหาความปลอดภัย) โปรดดูที่คู่มือภูต


1
คำถามไม่ได้เกี่ยวกับการ daemonization คุณได้สับสนบิต SUID (ให้สิทธิ์แก่เจ้าของโปรแกรมที่ปฏิบัติการได้) setuid()ซึ่งทำให้กระบวนการเปลี่ยนเป็น UID โดยพลการ โดยทั่วไปแล้ว SUID นั้นมีจุดประสงค์เพื่ออนุญาตให้มีการเพิ่มระดับสิทธิ์ (ไม่ใช่สิทธิ์พิเศษ -> สิทธิพิเศษ) ในขณะที่setuid()สามารถทำสิ่งตรงกันข้ามได้เท่านั้น
goldilocks
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.