Lật đổ cờ thực thi trên các hệ thống Linux. Tại sao điều này có thể?


23

Trong khi đọc , tôi tìm thấy khai thác sau:

% 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)

Đoạn mã này cho thấy rằng chúng ta có thể bỏ qua các quyền thực thi của hệ thống tệp một cách tầm thường như một người dùng không có đặc quyền bình thường. Tôi đã chạy nó trên Ubuntu 12.04.

Trong khi trình tải Linux là một đối tượng được chia sẻ theo tệp (1), nó cũng có một điểm vào cho phép nó được thực thi trực tiếp. Khi được thực thi theo cách này, trình tải Linux hoạt động như một trình thông dịch cho các nhị phân ELF.

Tuy nhiên, trên máy OpenBSD của tôi, việc khai thác này không hiệu quả, vì bạn không thể thực thi trình tải như một chương trình. Trang hướng dẫn OpenBSD cho biết: "ld.so chính nó là một đối tượng được chia sẻ ban đầu được tải bởi kernel.".

Hãy thử điều này trên Solaris 9, và bạn sẽ nhận được một segfault. Tôi không chắc chắn những gì xảy ra ở nơi khác.

Do đó, câu hỏi của tôi là:

  • Tại sao trình tải Linux (khi được thực thi trực tiếp) không kiểm tra các thuộc tính hệ thống tệp trước khi diễn giải nhị phân ELF?
  • Tại sao thực hiện một cơ chế được thiết kế không cho phép thực thi các tệp, nếu nó bị bỏ qua một cách tầm thường? Tôi đã bỏ lỡ một cái gì đó?

1
Không có lý do chính đáng, nhưng nếu bạn đã từng quản lý để xóa hệ thống của mình libc(tôi đã làm một lần, nâng cấp hộp Arch), bạn sẽ rất biết ơn vì điều này.
new123456

1
@ new123456 trời ơi, kênh IRC sau lần nâng cấp đó thật đau đớn.
Rob

Đó là trình tải chứ không phải trình liên kết.
OrangeDog

Câu trả lời:


33

Mục tiêu của sự executecho phép không phải là để ngăn chặn việc thực thi nói chung . Đó là (1) để báo cho các progam biết tập tin nào được thực thi và (2) để ngăn chặn việc thực thi với tư cách là người dùng đặc quyền , khi bit setuid (v.v.) được chỉ định.

Các hack linker là một khai thác ít hơn nó có vẻ. Bạn có thể thực thi bất kỳ tệp không thể thực thi nào mà bạn có quyền đọc dễ dàng hơn:

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

Xem cuộc thảo luận này trên diễn đàn Arch Linux .

Tóm tắt:

Đánh dấu các tập tin nên được thực hiện

Khi bạn viết một kịch bản shell, bạn có thể đánh dấu nó là tệp thực thi chmod +x. Điều này gợi ý cho trình bao của bạn rằng bạn dự định nó có thể được thực thi (nếu không thì tất cả các trình bao đều biết, đó chỉ là một tệp văn bản đơn giản khác). Shell sau đó có thể hiển thị nó trong hoàn thành tab khi bạn nhập ./Tab.

Tương tự: các something.dthư mục (ví dụ init.d) chứa các tập lệnh shell khởi động hoặc điều khiển thường được thực thi tự động bởi trình nền. Bạn có thể muốn đặt một bình luận hoặc tệp README trong thư mục dưới dạng tệp văn bản thuần túy. Hoặc bạn có thể muốn tạm thời vô hiệu hóa một trong các tập lệnh. Bạn có thể làm như vậy bằng cách xóa bit thực thi cho tệp cụ thể đó. Điều này nói với daemon bỏ qua nó.

Ngăn chặn thực thi đặc quyền

Các setuidchút có nghĩa là khi bạn thực hiện các tập tin, nó được thực hiện như một người dùng nào đó (ví dụ như root).

Các bài viết diễn đàn giải thích nó tốt:

Bạn muốn một tập tin thực thi được setuid cho một số người dùng, nhưng bạn chỉ muốn những người từ một nhóm cụ thể có thể thực thi nó như setuid. Họ vẫn có thể thực thi nó bằng cách sao chép, nhưng cờ setuid bị mất, vì vậy họ sẽ tự thực hiện nó, thay vì người dùng sở hữu tệp gốc.


2
Cảm ơn - Tôi đã bỏ qua thực tế là người dùng có thể sao chép bất kỳ tệp nào anh ta có thể đọc và do đó chọn quyền tùy ý.
Edd Barrett

Làm thế nào về các tập tin với quyền thực thi nhưng không có quyền đọc?
Lie Ryan

@LieRyan Còn họ thì sao?
Brendan dài

@BrendanLong: Rõ ràng bạn không thể sao chép chúng, vì vậy bạn không thể thay đổi quyền của họ. (Nhưng tại sao bạn muốn, tôi không thể nói - điều duy nhất bạn có thể làm với bản sao dù sao là bỏ quyền thực thi)
MSalters

9

Nếu bạn đã đọc quyền truy cập vào một tập tin, bạn luôn có thể tạo một bản sao của nó.

Nếu bạn có thể tạo một bản sao cá nhân, bạn luôn có thể đánh dấu bản sao đó có thể thực thi được.

Điều này không giải thích được bahaviour của ld-linux nhưng nó chỉ ra rằng nó có thể không phải là một lỗ hổng bảo mật rất hữu ích.

Nếu bạn muốn bảo mật chặt chẽ hơn, hãy xem xét SELinux


Thật là quá đúng.
Edd Barrett

Đó chỉ là một câu hỏi về khái niệm. Tôi cho rằng bạn cũng có thể thiết lập nonexec trên các hệ thống tập tin.
Edd Barrett

2

Nhìn vào câu hỏi hơi khác một chút: như Mechanical Snail nói, quyền thực thi trên một tệp không nhằm ngăn chặn việc thực thi. Tuy nhiên, tùy chọn hệ thống tập tin "noexec" không ngăn chặn việc thực thi và không dễ bị phá vỡ (không được hỗ trợ bởi tất cả các hệ thống tập tin, nhưng chắc chắn bởi các hệ thống linux phổ biến nhất). Nếu quản trị viên muốn ngăn người dùng chạy các chương trình của riêng họ, họ có thể chỉ định tùy chọn noexec trên các thư mục nhà và tmp, và bất kỳ ai khác mà người dùng có thể tạo tệp.

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

Rõ ràng nó đã từng có thể phá vỡ tùy chọn noexec bằng cách sử dụng thủ thuật trình tải được đề cập trong câu hỏi, nhưng nó đã được sửa trong kernel một vài phiên bản trở lại.

Từ http://linux.die.net/man/8/mount :

noexec

Không cho phép thực thi trực tiếp bất kỳ nhị phân nào trên hệ thống tệp được gắn. (Cho đến gần đây, vẫn có thể chạy nhị phân bằng cách sử dụng lệnh như /lib/ld*.so / mnt / binary. Thủ thuật này không thành công kể từ Linux 2.4.25 / 2.6.0.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.