chgrp가 "setuid 비트"를 지우는 것을 방지하는 방법은 무엇입니까?

chgrp가 "setuid 비트"를 지우는 것을 방지하는 방법은 무엇입니까?

RH 기반 Linux 이미지가 있습니다. 우리 제품의 최신 개발 버전으로 업그레이드하려면 일부 "특별 아카이브"를 "적용"해야 합니다.

아카이브를 생성한 사람은 기본 이미지 내에서 일부 권한이 잘못되었다고 생각했습니다. 그래서 우리는 도망치라고 했어요

sudo chgrp -R nobody /whatever

우리는 그렇게 했습니다. 나중에 애플리케이션이 실행될 때 모호한 문제가 발생했습니다.

나중에 발견한 것:chgrp~ 할 것이다분명한/whatever 내의 바이너리에 대한 setuid 비트 정보.

실제 문제는 다음과 같습니다. 일부 바이너리~ 해야 하다제대로 작동하려면 해당 setuid 비트를 설정해야 합니다.

간단히 말해서: "chgrp" 명령을 실행할 수 있는 방법이 있습니까?없이내 setuid 비트를 죽여?

방금 로컬 우분투에서 다음을 실행했습니다. 동일한 결과로 이어집니다.

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

--> 빨간색 배경의 파일 이름을 보여줍니다. --> 그렇습니다. setuid입니다.

chgrp -R myuser .
ls -al blub 

--> 빨간색 배경 없이 파일 이름을 표시합니다. --> setuid가 사라졌습니다.

답변1

chgrp -R nobody /whateversetuid 비트를 유지하면서 구현하려면 다음 두 find명령을 사용할 수 있습니다.

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

find ... -perm 04000옵션은 setuid 비트가 설정된 파일을 선택합니다. 그런 다음 첫 번째 명령은 chgrp및 a를 적용하여 chmod삭제된 setuid 비트를 복원합니다. 두 번째는 chgrpsetuid 비트가 없는 모든 파일에 적용됩니다.

어쨌든 대상에 영향을 미치기 때문에 chgrp또는 심볼릭 링크를 호출하고 싶지 않으므로 .chmod! -type l

답변2

chgrp(또는 ) 에서 SUID 및 SGID 비트를 지우는 것은 chown완벽하게 합리적입니다. 보안 문제를 예방하기 위한 안전 조치입니다. SGID의 경우 (실행 파일에서)는 다음을 의미합니다.그룹 소유자의 유효 그룹으로 이 프로그램을 실행하십시오..

그룹 소유자를 변경하면 보안 및 액세스 제어 측면에서 이것은 완전히 다른 것입니다. 즉, uvw이제 프로그램은 유효 그룹으로 실행하는 대신 유효 그룹으로 실행됩니다 xyz.

따라서 소유권 변경 시 SUID 또는 SGID 비트를 명시적으로 복원해야 합니다.

부록: chgrp(또는 chown)가 SGID(또는 SUID, resp.)만 지워야 한다는 주장에 대해

chowning 또는 ing을 수행 하면 chgrp실행 파일의 보안 설정이 변경되며 이는 권한 상승 속성을 지우기에 충분한 이유가 됩니다. Unix의 힘은 개념적 단순성에서 비롯되며 Unix 보안은 이미 상당히 까다롭습니다. 이를 위해 소유권 변경 시 SUID 및 SGID를 제거하는 것은 단순한 안전망입니다. 결국 Unix/Linux의 역사에는 잘못된 SUID 또는 SGID 설정으로 인해 상당한 취약점이 있었습니다.

따라서 Unix가 이런 식으로 동작하는 더 깊은 이유는 없으며 단지 보수적인 디자인 결정일 뿐입니다.

답변3

setuid디렉터리가 아닌 위치에서 비트 setgid(적어도 Linux에서는)를 지우는 작업은 자체적 으로 수행되는 것이 아니라 에서 chown()시스템 호출을 수행할 때 커널에 의해 수행됩니다 . 따라서 유일한 방법은 나중에 복원하는 것입니다.chgrpchgrp

또한 보안 기능도 삭제합니다.

따라서 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
)

그리고 (로 root) 실행하세요:

chown_preseve_sec :newgroup file1 file2...

권한을 유지하면서 그룹을 변경합니다.

재귀적으로 다음을 수행할 수 있습니다.

# 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=-

(동시에 파일을 엉망으로 만드는 것이 없다고 가정합니다.)

답변4

평소와 같이 관리에는 여러 가지 방법이 있습니다.

내가 마련한 솔루션은 다음과 같습니다.

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

관련 정보