การใช้ CmndAlias ALL
จะไม่ปลอดภัย
มี 1000 วิธีการที่จะทำงานอยู่โดยไม่ต้องทำservice network restart
sudo service network restart
นี่คือตัวอย่างของสิ่งที่ผู้ใช้ซนอาจลอง:
$ echo "service network restart" > /tmp/hax
$ chmod a+x /tmp/hax
$ sudo /tmp/hax
หากคุณให้ALL
นามแฝงคำสั่งแก่ผู้ใช้แล้วลองสร้างบัญชีดำพวกเขาจะสามารถหาวิธีแก้ไขได้ตลอดเวลา บัญชีดำทุบตีและพวกเขาจะใช้หลาม Blacklist python และพวกเขาจะใช้ Perl Blacklist Perl และพวกเขาจะใช้ PHP ไม่มีใครต้องการมัน!
หากคุณไม่ต้องการให้ใครทำอะไรคุณควรทำอย่างที่โธมัสพูดและสร้างบัญชีขาวของสิ่งที่อนุญาตให้ทำ
การตั้งค่ารายการที่อนุญาตด้วยข้อยกเว้น
ตัวอย่างของบัญชีขาวที่มีข้อยกเว้นสามารถพบได้ที่ด้านล่างของman sudoers
:
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except for root on the HPPA
machines. Note that this assumes passwd(1) does not take multiple user names
on the command line.
(อันที่จริงตัวอย่างนี้จาก manpage ไม่ปลอดภัยและสามารถนำไปใช้ในการเปลี่ยนรหัสผ่านของ root ได้! ดูความคิดเห็นด้านล่างเพื่อดูวิธีการ)
เราสามารถพยายามที่จะปรับตัวเข้ากับที่กับกรณีของคุณที่จะนำเสนอทุกservice
คำสั่งไปยังกลุ่มพนักงาน แต่ไม่รวมservice network
คำสั่งที่คุณกังวล:
%staff ALL = /usr/sbin/service *, \
! /usr/sbin/service *network*, \
! /usr/sbin/service *NetworkManager*
( ALL
ในตำแหน่งนั้นหมายถึง Host_Alias ไม่ใช่ Cmnd_Alias - สับสนใช่มั้ย)
ผู้ใช้จะไม่สามารถทำงานได้sudo bash
หรือsudo tee
หรือหรือsudo wget
sudo /path/to/malicious_script
คุณสามารถยกเว้นบัญชีผู้ใช้ของผู้ดูแลระบบของคุณถ้าคุณระมัดระวัง เพียงเจาะจง!
หมายเหตุ: ฉันเพิ่มคำ*
ก่อนหน้าnetwork
ข้างบนในกรณีที่มีการเพิ่มการตั้งค่าสถานะที่ไม่เป็นอันตรายในservice
เครื่องมือในอนาคต สมมติว่ามีการ--verbose
เพิ่มการตั้งค่าสถานะในอนาคตจากนั้นผู้ใช้จะสามารถเรียกใช้สิ่งต่อไปนี้:
$ sudo service --verbose network restart
ดังนั้นเราจำเป็นต้อง*
ใช้แฟล็กใด ๆ ก่อนชื่อบริการ ข้อเสียเปรียบอย่างหนึ่งคือการทำเช่นนี้อาจปิดกั้นบริการอื่น ๆ ที่คุณไม่ได้สนใจผู้ใช้เช่นบริการที่เรียกว่าsafe-network
หรือnetwork-monitor
จะถูกปฏิเสธ
อนุญาตให้ผู้ใช้แก้ไขไฟล์โดยใช้สิทธิ์กลุ่ม
ด้านล่างคุณสามารถค้นหาความพยายามหลายอย่างโดยใช้rnano
ผ่านsudo
เพื่อให้ผู้ใช้แก้ไขไฟล์หรือไฟล์ แต่จริงๆแล้วมันซับซ้อนและอันตรายกว่าที่ควรจะเป็น
วิธีที่ง่ายกว่าและปลอดภัยกว่าคือเปลี่ยนสิทธิ์ของกลุ่มในไฟล์เฉพาะที่คุณต้องการเปิดสิทธิ์การแก้ไข นี่คือตัวอย่างบางส่วน:
### Give steve the ability to edit his nginx config:
$ chgrp steve /etc/nginx/sites-available/steves_dodgy_project
$ chmod g+rw /etc/nginx/sites-available/steves_dodgy_project
### Let all members of the staff group edit the group_website config:
$ chgrp staff /etc/nginx/sites-available/group_website
$ chmod g+rw /etc/nginx/sites-available/group_website
หากคุณต้องการการควบคุมที่ละเอียดยิ่งขึ้น (ตัวอย่างเช่น: การเข้าถึงสำหรับผู้ใช้เพียง 3 คน แต่ไม่ใช่พนักงานทุกคน) คุณสามารถสร้างกลุ่มใหม่โดยใช้addgroup
คำสั่งและเพิ่มผู้ใช้เพียงไม่กี่คน
อนุญาตให้ผู้ใช้แก้ไขไฟล์ผ่าน sudo
ส่วนที่เหลือของคำตอบนี้กลายเป็นการตรวจสอบว่าการปล่อยช่องโหว่ในsudo
การกำหนดค่าของคุณนั้นง่ายเพียงใดเมื่อพยายามให้ความยืดหยุ่นแก่ผู้ใช้ ฉันจะไม่แนะนำให้ทำสิ่งต่อไปนี้!
หากคุณต้องการให้สิทธิ์ผู้ใช้ของคุณในการแก้ไขไฟล์เฉพาะคุณสามารถลองใช้rnano
:
%staff ALL = /bin/rnano /etc/nginx/sites-available/host
rnano
จะให้พวกเขาแก้ไขไฟล์ที่ระบุเท่านั้น นั่นคือสิ่งสำคัญที่จะป้องกันไม่ให้ผู้ใช้ที่เป็นอันตรายจากการแก้ไขการบริการที่แตกต่างกันพุ่งพรวด (ตัวอย่าง/etc/init.d/urandom
) service network restart
และการเพิ่มสายไปที่จะทำงาน
แต่น่าเสียดายที่ผมไม่ได้หาวิธีที่จะ จำกัด การrvim
พอ (ผู้ใช้ยังสามารถเปิดไฟล์ใด ๆ ที่ใช้:e
) nano
ดังนั้นเราจะติดอยู่กับ
น่าเสียดายที่การอนุญาตให้ผู้ใช้แก้ไขไฟล์หลายไฟล์ทำได้ยากกว่า ...
ให้ผู้ใช้แก้ไขไฟล์หลาย ๆ ไฟล์ (ยากกว่าที่ควรจะเป็น)
1. วิธีที่ไม่ปลอดภัย
ระวังสัญลักษณ์แทน! หากคุณเสนอความยืดหยุ่นที่มากเกินไป (หรือความยืดหยุ่นใด ๆ ) ก็สามารถนำไปใช้ประโยชน์ได้:
%staff ALL = /bin/rnano /etc/nginx/sites-available/* # UNSAFE!
ในกรณีนี้ผู้ใช้ที่เป็นอันตรายจะสามารถแก้ไขสคริปต์บริการพุ่งพรวดอื่น ๆ แล้วเรียกใช้:
$ sudo rnano /etc/nginx/sites-available/../../../any/file/on/the/system
(Sudo ทำการป้องกัน.
และ..
ขยายคำสั่งจริง ๆ แต่น่าเสียดายที่ไม่ได้อยู่ในอาร์กิวเมนต์)
ฉันหวังว่าสิ่งนี้จะได้ผล แต่ก็ยังไม่ปลอดภัย:
%staff ALL = /bin/rnano /etc/nginx/sites-available/[A-Za-z0-9_-]* # UNSAFE!
เนื่องจากsudo
ในปัจจุบันมีเฉพาะรูปแบบแบบกลมที่*
จะจับคู่อะไร - มันไม่ใช่ regexp!
(แก้ไข: ฉันได้พิจารณาแล้วว่าคุณสามารถหลีกเลี่ยงสิ่งที่กล่าวมาข้างต้นในสถานการณ์ของคุณได้เนื่องจากไม่มีโฟลเดอร์ย่อยอยู่ข้างใต้sites-available
เราต้องการให้ถ่านหนึ่งตัวถูกจับคู่หลังจากโฟลเดอร์และ/..
ควรล้มเหลวหลังจากชื่อไฟล์อย่างไรก็ตามนี่ไม่ใช่ โซลูชันที่ใช้การได้เพราะrnano
ยอมรับข้อโต้แย้งหลาย ๆ ข้อและโดยทั่วไปแล้วสิ่งนี้จะยังไม่ปลอดภัยในโฟลเดอร์ที่มีโฟลเดอร์ย่อย!)
แม้ว่าเราจะไม่มีโฟลเดอร์ย่อยและเราไม่รวมสายใด ๆ ที่มี/../
กฎที่นำเสนอ*
glob ยังสามารถใช้ประโยชน์เพราะrnano
ยอมรับข้อโต้แย้งหลาย ๆ (ขี่จักรยานผ่านพวกเขาใน<C-X>
และพื้นที่ที่เป็นที่ยอมรับกันอย่างมีความสุขโดย*
glob
$ rnano /etc/nginx/sites-available/legal_file /then/any/file/on/the/system
2. กดซองจดหมาย (ไม่ปลอดภัยที่สุด)
แล้วถ้าเราปฏิเสธบรรทัดใด ๆ ที่มีช่องว่างหรือพยายามเข้าถึง/..
ล่ะ จากนั้นโซลูชันที่ใช้งานได้ขั้นสุดท้ายอาจเป็นเช่นนี้:
# I tried hard to make this safe, but in the end I failed again.
# Please don't use this unless you are really smart or really stupid.
%staff ALL = /bin/rnano /etc/nginx/sites-available/*, \
! /bin/rnano */..*, \
! /bin/rnano /etc/nginx/sites-available/, \
! /bin/rnano */., \
! /bin/rnano * *
# CONCLUSION: It is still NOT SAFE if there are any subfolders, due to
# the bug in rnano described below.
เรายอมรับทุกสิ่งที่ "ภายใต้" โฟลเดอร์ แต่เราก็ปฏิเสธการโทรใด ๆrnano
หาก/..
หรือ/.
หรือ
ถูกส่งผ่านหรือหากโฟลเดอร์ถูกกำหนดเป้าหมายโดยตรง (ในทางเทคนิคแล้วการ/.
ยกเว้นทำให้การ/..
ยกเว้นซ้ำซ้อน แต่ฉันทิ้งไว้ทั้งสองอย่างเพื่อความชัดเจน)
ฉันพบโฟลเดอร์และต้องการ/.
การยกเว้นเนื่องจากไม่เช่นนั้นผู้ใช้สามารถกำหนดเป้าหมายโฟลเดอร์เองได้ ตอนนี้คุณอาจคิดว่าrnano
จะบล็อกหากชี้ไปที่โฟลเดอร์ แต่คุณจะผิด อันที่จริงแล้วเวอร์ชั่นของฉัน (2.2.6-1ubuntu1) เริ่มต้นด้วยคำเตือนเล็กน้อยและไฟล์ว่างเปล่าจากนั้น<C-X>
ขอให้ฉันใส่ชื่อไฟล์ใด ๆ ที่ฉันต้องการบันทึกไว้เพื่อเปิดเวกเตอร์การโจมตีใหม่! อย่างน้อยก็ปฏิเสธที่จะเขียนทับไฟล์ที่มีอยู่ (ในการทดสอบเดียวที่ฉันทำ) อย่างไรก็ตามเนื่องจากไม่มีวิธีในการขึ้นบัญชีดำโฟลเดอร์ย่อยด้วย sudo เราต้องสรุปว่าวิธีนี้ไม่ปลอดภัยอีกครั้ง ขออภัยผู้ใช้!
การค้นพบนี้ทำให้ฉันสงสัยว่าnano
โหมด "ถูก จำกัด " ของทั่วถึง พวกเขาบอกว่าโซ่มีความแข็งแกร่งพอ ๆ กับลิงก์ที่อ่อนแอที่สุด ฉันเริ่มรู้สึกถึงการรวมกันของsudo
เวทมนตร์ดำบัญชีดำและrnano
อาจไม่ปลอดภัยกว่าสายโซ่เดซี่
3. แนวทางที่ปลอดภัย แต่ จำกัด
Globs ถูก จำกัด มาก - พวกเขาไม่ให้เราจับคู่คลาสของตัวละครหลาย ๆ ครั้ง คุณสามารถแก้ไขไฟล์ได้หลายไฟล์หากชื่อไฟล์ทั้งหมดของคุณมีความยาวเท่ากัน (ในกรณีนี้host
ตามด้วยหลักเดียว):
%staff ALL = /bin/rnano /etc/nginx/sites-available/host[0-9] # SAFE
แต่ถ้าคุณต้องการให้ผู้ใช้สามารถแก้ไขไฟล์ต่าง ๆ ได้คุณอาจต้องระบุไฟล์แต่ละไฟล์อย่างชัดเจน:
%staff ALL = /bin/rnano /etc/nginx/sites-available/hothost \
/bin/rnano /etc/nginx/sites-available/coldhost \ # SAFE
/bin/rnano /etc/nginx/sites-available/wethost \
/bin/rnano /etc/nginx/sites-available/steves_dodgy_project
อย่าถูกล่อลวงให้ใช้งาน*
ณ จุดใด ๆ ดูหัวข้อที่ 1 และ 2 ข้างต้นเพราะเหตุใด! ข้อควรจำ: สลิปขนาดเล็กหนึ่งอันสามารถประนีประนอมกับบัญชี superuser ทั้งหมดและทั้งระบบ
4. เขียนตัวตรวจสอบอาร์กิวเมนต์ของคุณเอง (ความปลอดภัยเป็นความรับผิดชอบของคุณแล้ว)
ฉันหวังว่าพวกเขาจะเพิ่มการสนับสนุน regexp sudo
ในอนาคต มันสามารถแก้ปัญหาได้มากมายหากใช้อย่างถูกต้อง แต่เราอาจต้องการความสามารถในการตรวจสอบคุณสมบัติของอาร์กิวเมนต์ (เพื่ออนุญาตเฉพาะไฟล์โฟลเดอร์เท่านั้นหรือเฉพาะธงบางอย่าง)
แต่มีอีกทางเลือกหนึ่งในการสร้างความยืดหยุ่นใน sudo ผ่านเจ้าชู้:
%staff ALL = /root/bin/staffedit *
จากนั้นเขียนstaffedit
สคริปต์ของคุณเองหรือเรียกใช้งานได้เพื่อตรวจสอบว่าข้อโต้แย้งที่ส่งโดยผู้ใช้นั้นถูกกฎหมายหรือไม่และดำเนินการตามคำขอของพวกเขาหากเป็น
networking
และnetwork-manager
? นอกจากนี้ทำไมผู้ใช้ของคุณมีsudo
การเข้าถึง? พวกเขาไม่ควรเว้นเสียแต่ว่าคุณต้องการให้พวกเขามีสิทธิพิเศษเต็ม