Làm thế nào để ngăn chặn chgrp khỏi xóa bit setuid bit?


8

Chúng tôi có hình ảnh Linux dựa trên RH; trên đó tôi phải "áp dụng" một số "kho lưu trữ đặc biệt" để nâng cấp chúng lên phiên bản phát triển mới nhất của sản phẩm.

Người tạo kho lưu trữ cho rằng trong hình ảnh cơ sở của chúng tôi, một số quyền là sai; vì vậy chúng tôi được yêu cầu chạy

sudo chgrp -R nobody /whatever

Chúng tôi đã làm điều đó; và sau này, khi ứng dụng của chúng tôi đang chạy, các vấn đề tối nghĩa đã xuất hiện.

Những gì tôi tìm thấy sau này: lệnh gọi chgrp sẽ xóa thông tin bit setuid trên các nhị phân của chúng tôi trong / bất cứ điều gì.

Và vấn đề thực tế là: một số nhị phân của chúng ta phải cài đặt bit setuid đó để hoạt động đúng.

Câu chuyện dài: có cách nào để chạy lệnh "chgrp" đó mà không giết các bit setuid của tôi không?

Tôi chỉ chạy như sau trên Ubuntu cục bộ của tôi; dẫn đến kết quả tương tự:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

-> hiển thị cho tôi tên tệp với nền đỏ -> vì vậy, yep, setuid

chgrp -R myuser .
ls -al blub 

-> hiển thị cho tôi tên tệp không có nền đỏ -> setuid đã biến mất


1
Các 4XXXbit được gọi là setuid bit ( s), không dính. Chú ý là tbit và mục đích của nó hơi khác một chút: en.wikipedia.org/wiki/Sticky_bit
zuazo

2
(1) Bạn đang thiết lập setuidbit, không phải stickybit. (2) Không xóa setuidbit khi bạn làm chgrphoặc chownsẽ là một vấn đề bảo mật.
Satō Katsura

1
Hành vi này thay đổi giữa các bản phân phối. Nhưng như đã giải thích ở đây , sự thay đổi của bit setuid phụ thuộc vào hành vi tòa nhà bên dưới.
zuazo

Cảm ơn tất cả mọi người. Bạn đã đúng, đây là về bit setuid! Cảm ơn bạn đã giúp đỡ. Và tôi cũng chấp nhận rằng đây là "công trình như thiết kế". Bây giờ tôi chỉ cần tìm cách lành mạnh nhất để làm những gì cần phải làm mà không cần phải giết những bit đó. Tôi xem xét sử dụng gefacl để tạo kết xuất văn bản, làm lại cấu hình văn bản và sau đó áp dụng cái đó. Điều đó sẽ cho tôi toàn quyền kiểm soát những gì sẽ xảy ra.
GhostCat

Câu trả lời:


7

Nếu bạn muốn thực hiện chgrp -R nobody /whatevertrong khi vẫn giữ bit setuid, bạn có thể sử dụng hai findlệnh này

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

Các find ... -perm 04000tùy chọn chọn lưu các tập tin với các thiết lập bit setuid. Lệnh đầu tiên sau đó áp dụng chgrpvà sau đó a chmodđể khôi phục bit setuid đã bị loại bỏ. Cái thứ hai áp dụng chgrpcho tất cả các tệp không có bit setuid.

Trong mọi trường hợp, bạn không muốn gọi chgrphoặc chmodtrên các liên kết tượng trưng vì điều đó sẽ ảnh hưởng đến mục tiêu của họ thay vào đó, do đó ! -type l.


Lưu ý rằng chgrpcũng xóa bit setgid (và các khả năng trên Linux) cũng có thể cần được khôi phục.
Stéphane Chazelas

@ StéphaneChazelas bạn nói đúng, nhưng như setgid không ai nhắc đến, tôi không lo lắng về việc cung cấp giải pháp cho nó. Tuy nhiên, giải pháp này có thể mở rộng một cách tầm thường, với lần thứ bafind
roaima

Chà, nó không thể là phát hiện thứ 3, bạn phải bao gồm các trường hợp u + g, một mình, g một mình. Trong mọi trường hợp, bạn sẽ có thể làm điều đó trong một lần findgọi. Tôi không thích những dòng dài trong SE khi bạn phải cuộn văn bản. Tôi thêm vào! -type l làm cho nó đi qua rìa
Stéphane Chazelas

Chà, một findcách tiếp cận với -exec +có thể khó thực hiện một cách đáng tin cậy nếu điều đó kết thúc việc chia chmod/ chgrps thành nhiều lệnh.
Stéphane Chazelas

1
Thật ra, tôi nghĩ find . ! -type l -exec chgrp nobody {} + \( -perms -6000 -exec chmod gu+s {} + -o -perms -4000 -exec chmod u+s {} + -o -perms -2000 -exec chmod g+s {} + \)nên ổn thôi. Bởi vì chgrptrận đấu cho các tập tin hơn, cho mỗi tập tin nó nên được thực hiện trước khi các chmods.
Stéphane Chazelas

5

Việc xóa các bit SUID và SGID trên chgrp(hoặc chown) là hoàn toàn hợp lý. Đây là một biện pháp an toàn để ngăn chặn các vấn đề an ninh. Đối với SGID (trên các tệp thực thi, tôi đoán) có nghĩa là chạy chương trình này với nhóm chủ sở hữu nhóm hiệu quả .

Nếu bạn thay đổi chủ sở hữu nhóm, thì về mặt bảo mật và kiểm soát truy cập, đây là một thứ hoàn toàn khác, tức là thay vì chạy với nhóm hiệu quả uvw, chương trình hiện chạy với nhóm hiệu quả xyz.

Do đó, bạn phải khôi phục bit SUID hoặc SGID một cách rõ ràng khi thay đổi quyền sở hữu.

Phụ lục: Theo yêu cầu rằng chgrp (hoặc chown) chỉ nên xóa SGID (hoặc SUID, resp.)

Bằng cách chowning hoặc chgrping, bạn thay đổi cài đặt bảo mật cho một tệp thực thi và đây là lý do đủ để xóa bất kỳ thuộc tính nâng cao đặc quyền nào. Sức mạnh của Unix đến từ sự đơn giản về khái niệm và bảo mật Unix đã khá phức tạp. Cuối cùng, việc loại bỏ SUID và SGID trên bất kỳ thay đổi quyền sở hữu nào chỉ đơn giản là một mạng lưới an toàn - xét cho cùng, trong lịch sử của Unix / Linux, có khá nhiều lỗ hổng do cài đặt SUID hoặc SGID sai.

Vì vậy, không có lý do sâu xa hơn tại sao Unix hành xử theo cách này, nó chỉ là một quyết định thiết kế bảo thủ.


1
Điều này giải thích hoàn hảo tại sao chủ sở hữu thay đổi sẽ xóa bit SUID và nhóm thay đổi sẽ xóa bit SGID. Nhưng câu hỏi là về bit SUID trong hoạt động thay đổi nhóm không ảnh hưởng đến người dùng mà SUID chạy. Vì vậy, phải có một lời giải thích khác nhau.
Ben Voigt

1
@BenVoigt: nó giải thích nó khá tốt. Cả chown và chgrp đều gọi tòa nhà chown (), nó sẽ xóa suid và sgid trên các tập tin thông thường bất kể là gì.
Joshua

1
@Joshua: Đó là một mô tả. Giải thích là "để tránh trường hợp thay vì chạy với nhóm hiệu quả uvw, giờ đây chương trình sẽ chạy với nhóm hiệu quả xyz", nhưng điều đó không áp dụng cho trường hợp đang thảo luận.
Ben Voigt

Nó làm. Bằng cách chowning hoặc chgrping, bạn thay đổi cài đặt bảo mật và đây là lý do đủ để xóa các thuộc tính nâng cao đặc quyền. Rất có thể là điều này nếu không thì tấn công người không sẵn sàng.
phản hồi

4

Việc xóa bit setuid, setgid(ít nhất là trên Linux) trên các thư mục không được thực hiện bởi kernel dựa trên lệnh chown()gọi hệ thống được thực hiện bởi chgrp, chứ không phải bởi chgrpchính nó. Vì vậy, cách duy nhất là khôi phục nó sau đó.

Nó cũng xóa các khả năng bảo mật.

Vì vậy, trên GNU Linux:

chown_preserve_sec() (
  newowner=${1?}; shift
  for file do
    perms=$(stat -Lc %a -- "$file") || continue
    cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
    chown -- "$newowner" "$file" || continue
    [ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
    chmod -- "$perms" "$file"
  done
)

Và chạy (như root):

chown_preseve_sec :newgroup file1 file2...

để thay đổi nhóm trong khi cố gắng duy trì các quyền.

Đệ quy, bạn có thể làm:

# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)

chgrp -RP nobody .

# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z  "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-

(tất cả đều cho rằng không có gì khác làm rối tung các tệp cùng một lúc).


1

Như thường lệ trong quản trị viên, có nhiều cách để đi.

Giải pháp tôi đưa ra là như thế này:

cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null

# A) change lines starting with      # group: root
# to                                 # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new

# B) change lines with               group::x.y
# to                                 group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new
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.