การล้มการตั้งค่าสถานะการเรียกใช้งานบนระบบ Linux ทำไมเป็นไปได้


23

ในขณะที่อ่านสิ่งนี้ฉันพบการใช้ประโยชน์ดังต่อไปนี้:

% cp /usr/bin/id ~
% chmod -x ~/id
% ls -al ~/id
-rw-r--r-- 1 edd edd 22020 2012-08-01 15:06 /home/edd/id
% ~/id
zsh: permission denied: /home/edd/id
% /lib/ld-linux.so.2 ~/id
uid=1001(edd) gid=1001(edd) groups=1001(edd),1002(wheel)

ตัวอย่างนี้แสดงให้เห็นว่าเราสามารถก้าวเท้าเลี่ยงการดำเนินการของระบบไฟล์ได้ในฐานะผู้ใช้ที่ไม่มีสิทธิพิเศษ ฉันทำสิ่งนี้บน Ubuntu 12.04

ในขณะที่ตัวโหลด Linux เป็นวัตถุที่ใช้ร่วมกันตามไฟล์ (1) แต่ก็มีจุดเข้าใช้งานที่อนุญาตให้เรียกใช้โดยตรง เมื่อดำเนินการในลักษณะนี้ตัวโหลด Linux ทำหน้าที่เป็นล่ามสำหรับ ELF ไบนารี

อย่างไรก็ตามในเครื่อง OpenBSD ของฉันการหาประโยชน์นี้ไม่ได้มีประสิทธิภาพเพราะคุณไม่สามารถเรียกใช้ตัวโหลดเป็นโปรแกรม หน้าคู่มือ OpenBSD พูดว่า: "ld.so เป็นวัตถุที่ใช้ร่วมกันซึ่งเคอร์เนลถูกโหลดครั้งแรก"

ลองสิ่งนี้บน Solaris 9 แล้วคุณจะได้รับ segfault ฉันไม่แน่ใจว่าเกิดอะไรขึ้นที่อื่น

คำถามของฉันคือ:

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

1
ไม่มีเหตุผลที่ดี แต่ถ้าคุณเคยลบระบบของคุณlibc(ฉันเคยทำการอัพเกรดกล่อง Arch) คุณจะรู้สึกขอบคุณสำหรับการเล่นโวหารเล็ก ๆ น้อย ๆ นี้
new123456

1
@ new123456 โอ้พระเจ้าช่อง IRC หลังจากการอัปเกรดนั้นเจ็บปวดมากที่จะต้องได้รับ
Rob

มันเป็นตัวโหลดไม่ใช่ตัวลิงก์
หยุดทำร้ายโมนิก้า

คำตอบ:


33

เป้าหมายของการexecuteได้รับอนุญาตเป็นไม่ได้ที่จะดำเนินการป้องกันโดยทั่วไป มันเป็น (1) เพื่อบอก progams ว่าไฟล์ใดที่จะถูกเรียกใช้และ (2) เพื่อป้องกันการดำเนินการในฐานะผู้ใช้ที่มีสิทธิ์เมื่อมีการระบุบิต setuid (ฯลฯ )

ตัวเชื่อมโยงแฮ็คมีการใช้ประโยชน์น้อยกว่าที่คิด คุณสามารถเรียกใช้งานไฟล์ที่ไม่สามารถเรียกใช้งานได้ซึ่งคุณมีสิทธิ์อ่านได้ง่ายขึ้น:

$ cp unexecutable_file ~/runme
$ chmod +x ~/runme
$ ~/runme

ดูการสนทนานี้ในฟอรั่ม Arch ลินุกซ์

สรุป:

การทำเครื่องหมายไฟล์ที่ควรดำเนินการ

เมื่อคุณเขียนเชลล์สคริปต์คุณสามารถทำเครื่องหมายว่าสามารถเรียกใช้งานchmod +xได้ คำแนะนำนี้มีไว้สำหรับเชลล์ของคุณที่คุณต้องการให้สามารถเรียกใช้งานได้ (ไม่เช่นนั้นเชลล์จะรู้ว่าเป็นเพียงไฟล์ข้อความธรรมดา) ./Tabเปลือกแล้วสามารถแสดงได้ในแท็บเสร็จเมื่อคุณพิมพ์

ในทำนองเดียวกัน: something.dไดเรกทอรี (เช่นinit.d) มีการเริ่มต้นหรือควบคุมเชลล์สคริปต์ที่โดยทั่วไปแล้วจะดำเนินการโดย daemons คุณอาจต้องการใส่ความคิดเห็นหรือไฟล์ README ในไดเรกทอรีเป็นไฟล์ข้อความธรรมดา หรือคุณอาจต้องการปิดใช้งานสคริปต์ใดสคริปต์หนึ่งชั่วคราว คุณสามารถทำได้โดยการล้างบิตเรียกใช้งานสำหรับไฟล์นั้น ๆ นี่เป็นการบอก daemon ให้ข้ามมัน

ป้องกันการเรียกใช้สิทธิพิเศษ

setuidบิตหมายความว่าเมื่อคุณเรียกใช้ไฟล์ก็จะถูกดำเนินการในฐานะที่เป็นผู้ใช้ที่ระบุ (เช่น root)

โพสต์ฟอรัมอธิบายได้ดี:

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


2
ขอบคุณ - ฉันมองข้ามความจริงที่ว่าผู้ใช้สามารถคัดลอกไฟล์ใดก็ได้ที่เขาสามารถอ่านได้และเลือกการอนุญาตโดยพลการ
Edd Barrett

วิธีการเกี่ยวกับไฟล์ที่มีสิทธิ์ดำเนินการ แต่ไม่มีสิทธิ์อ่าน?
Lie Ryan

@LieRyan แล้วพวกเขาล่ะ?
Reinstate Monica

@BrendanLong: คุณไม่สามารถคัดลอกสิ่งเหล่านั้นได้ดังนั้นคุณจึงไม่สามารถเปลี่ยนการอนุญาตได้ (แต่ทำไมคุณต้องการฉันไม่สามารถพูดได้ - สิ่งเดียวที่คุณสามารถทำได้กับการคัดลอกต่อไปคือการปล่อยสิทธิ์ดำเนินการ)
MSalters

9

หากคุณมีสิทธิ์อ่านเพื่อเข้าถึงไฟล์คุณสามารถทำสำเนาได้ตลอดเวลา

หากคุณสามารถทำสำเนาส่วนบุคคลคุณสามารถทำเครื่องหมายสำเนาที่ปฏิบัติการได้

สิ่งนี้ไม่ได้อธิบายถึงประโยชน์ของ ld-linux แต่ไม่ได้ระบุว่ามันอาจจะเป็นช่องโหว่ด้านความปลอดภัยที่มีประโยชน์มาก

หากคุณต้องการความปลอดภัยที่เข้มงวดมากขึ้นให้พิจารณาSELinux


นี่เป็นเรื่องจริง
Edd Barrett

มันเป็นเพียงคำถามเชิงแนวคิด ฉันคิดว่าคุณสามารถตั้ง nonexec บน filesystems ได้เช่นกัน
Edd Barrett

2

ดูคำถามที่ต่างออกไปเล็กน้อย: อย่างเครื่องกลเมชพูดว่าการอนุญาตให้เรียกใช้ไฟล์ไม่ได้มีวัตถุประสงค์เพื่อป้องกันการดำเนินการ อย่างไรก็ตามตัวเลือกระบบไฟล์ "noexec" จะป้องกันการดำเนินการและไม่ได้หลบเลี่ยงได้ง่าย ๆ (ไม่รองรับระบบไฟล์ทั้งหมด แต่แน่นอนโดย linux ที่ได้รับความนิยมสูงสุด) หากผู้ดูแลระบบต้องการป้องกันผู้ใช้ที่รันโปรแกรมด้วยตนเองพวกเขาสามารถระบุตัวเลือก noexec บนโฮมและไดเรกทอรี tmp และอื่น ๆ ที่ผู้ใช้อาจสร้างไฟล์ได้

$ mount -o noexec /dev/sdd1 /test
$ cd /test
$ cp /usr/bin/id .
$ ./id
-bash: ./id: Permission denied

เห็นได้ชัดว่ามันเคยเป็นไปได้ที่จะหลีกเลี่ยงตัวเลือก noexec โดยใช้เคล็ดลับการโหลดที่กล่าวถึงในคำถาม แต่ที่ได้รับการแก้ไขในเคอร์เนลไม่กี่รุ่นกลับ

จาก http://linux.die.net/man/8/mount :

noexec

ไม่อนุญาตให้เรียกใช้งานไบนารีโดยตรงบนระบบไฟล์ที่เมาท์ (จนกระทั่งเมื่อไม่นานมานี้มีความเป็นไปได้ที่จะรันไบนารีโดยใช้คำสั่งเช่น /lib/ld*.so / mnt / binary เคล็ดลับนี้ล้มเหลวตั้งแต่ Linux 2.4.25 / 2.6.0)

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