Tại sao bit setuid hoạt động không nhất quán?


8

Tôi đã viết mã:

// a.c
#include <stdlib.h>
int main () {
  system("/bin/sh");
  return 0;
}

được biên dịch bằng lệnh:

gcc a.c -o a.out

thêm bit setuid vào nó:

sudo chown root.root a.out
sudo chmod 4755 a.out

Trên Ubuntu 14.04, khi tôi chạy với tư cách là người dùng chung, tôi có quyền root.

nhưng trên Ubuntu 16.04, tôi vẫn có vỏ của người dùng hiện tại.

Tại sao nó khác nhau?

Câu trả lời:


9

Điều thay đổi là /bin/shtrở thành bashhoặc ở lại dashcó thêm một cờ -pbắt chước hành vi của bash.

Bash yêu cầu -pcờ không bỏ đặc quyền setuid như được giải thích trong trang man của nó :

Nếu shell được bắt đầu với id người dùng (nhóm) hiệu quả không bằng id người dùng thực (nhóm) và tùy chọn -p không được cung cấp, không có tệp khởi động nào được đọc, các hàm shell không được kế thừa từ môi trường, SHELLOPTS Các biến BASHOPTS, CDPATH và GLOBIGNORE, nếu chúng xuất hiện trong môi trường, sẽ bị bỏ qua và id người dùng hiệu quả được đặt thành id người dùng thực . Nếu tùy chọn -p được cung cấp khi gọi, hành vi khởi động là như nhau, nhưng id người dùng hiệu quả không được đặt lại.

Trước đây, dashkhông quan tâm đến điều này và cho phép thực thi setuid (bằng cách không làm gì để ngăn chặn nó). Nhưng Ubuntu 16.04 của dashmanpage 's đã một tùy chọn bổ sung mô tả, tương tự như bash:

-p private
Đừng cố thiết lập lại uid hiệu quả nếu nó không khớp với uid. Điều này không được đặt theo mặc định để giúp tránh sử dụng không chính xác bởi các chương trình gốc setuid thông qua hệ thống (3) hoặc popen (3).

Tùy chọn này không tồn tại ở thượng nguồn (có thể không phản ứng với bản vá được đề xuất * ) cũng như Debian 9 nhưng hiện diện trong Debian buster có bản vá từ năm 2018.

LƯU Ý: như được giải thích bởi Stéphane Chazelas, đã quá muộn để gọi "/bin/sh -p"vào system()system()chạy bất cứ thứ gì được đưa ra /bin/shvà do đó setuid đã bị loại bỏ. Câu trả lời của derobert giải thích cách xử lý việc này, trong đoạn mã trước system().

* thêm chi tiết về lịch sử ở đâyở đó .


system("bash -p")chạy sh -c "bash -p"để các đặc quyền đã bị loại bỏ khi bashđược thực thi.
Stéphane Chazelas

ồ được rồi Tôi sẽ loại bỏ phần "giải pháp" được xử lý tốt hơn bằng câu trả lời của derobert.
AB


Có vẻ như Ubuntu đã sửa lỗi dash trong wily (15.10). bug.launchpad.net/ubfox/+source/dash/+orms/1215660
Đánh dấu Plotnick

1
Lưu ý rằng Debian đã từng đi theo hướng khác. Nó được sử dụng để vá bash để không bỏ đặc quyền. Cho dù đó là một cải tiến là có thể tranh cãi. Bây giờ, những người muốn thực hiện system()với các đặc quyền nâng cao (mà, được cho phép, họ không nên ở nơi đầu tiên) cuối cùng đã làm một setresuid()điều tồi tệ hơn rất nhiều vì khi đó cái vỏ không biết nó thật tuyệt vời nên không kích hoạt chế độ không tin tưởng vào môi trường của nó.
Stéphane Chazelas

8

Có lẽ shell đang thay đổi ID người dùng hiệu quả của nó trở lại ID người dùng thực sự như là một phần của khởi động vì lý do này hay lý do khác. Bạn có thể xác minh điều này bằng cách thêm:

/* needs _GNU_SOURCE; non-Linux users see setregid/setreuid instead */
uid_t euid = geteuid(), egid = getegid();
setresgid(egid, egid, egid);
setresuid(euid, euid, euid);

trước khi bạn system(). (Trên thực tế, ngay cả trên Linux, có lẽ bạn chỉ cần thiết lập những người thực sự; những người đã lưu sẽ ổn khi để yên. Đây chỉ là vũ lực để gỡ lỗi. Tùy thuộc vào lý do bạn thiết lập id, tất nhiên bạn có thể cần để lưu ID thật ở đâu đó.)

[Ngoài ra, nếu đây không chỉ là một bài tập học cách setid hoạt động, thì có rất nhiều vấn đề bảo mật phải lo lắng, đặc biệt là khi gọi shell. Có nhiều biến môi trường, ví dụ, ảnh hưởng đến hành vi của shell. Thích một cách tiếp cận đã tồn tại như sudonếu có thể.]


Tôi tập trung vào lý do tại sao nó thay đổi, trong khi bạn cung cấp cách tránh vấn đề. +1
AB

Tất nhiên, nếu bạn thực sự làm cần nơi nào đó để lưu các ID sản, ID tiết kiệm được là một kinh khủng nơi thuận tiện để làm điều đó. Đặc biệt nếu ID hiệu quả không phải là root: root.
Kevin
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.