스크립트는 실행 가능하지만 읽을 수는 없습니까? 스크립트를 만들었고 다른 사용자가이 스크립트를

읽을 권한이 없으면 스크립트를 실행할 수 있습니까? 루트 모드에서 스크립트를 만들었고 다른 사용자가이 스크립트를 실행하지만 읽지 않기를 원합니다. chmod읽기 및 쓰기 는 금지했지만 실행은 허용했지만 사용자 모드에서는 권한이 거부되었습니다.



답변

문제는 스크립트 인터프리터 (실행되는 것이 아니다, 그러나이다 bash, perl, python, 등). 통역사는 스크립트를 읽어야합니다. 이것은 ls인터프리터처럼 프로그램이 커널에 직접로드된다는 점에서 와 같이 “일반적인”프로그램과 다릅니다 . 커널 자체가 프로그램 파일을 읽고 있기 때문에 읽기 액세스에 대해 걱정할 필요가 없습니다. 일반 파일을 읽어야하므로 인터프리터는 스크립트 파일을 읽어야합니다.


답변

이것은 바이너리에만 가능합니다.

$ chown foo:foo bar
$ chmod 701 bar

권한이없는 사용자로서 :

$ ls -lha bar
-rwx-----x 1 foo foo 7.0K 2012-03-15 03:06 bar

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

자, 여기 키커가 있습니다. 일반적인 방법으로는 파일을 읽을 수 없지만 실제로 파일 읽기를 막을 수는 없습니다. 이것은 실제로 http://smashthestack.org/ (레벨 13) 에 대한 도전입니다 . hktrace을 사용하여 파일을 읽을 수 있는 잘 알려진 유틸리티 가 있습니다 ptrace.


답변

최소한 Linux에서는 불가능합니다 (다른 Unices에서도 가능). 스크립트를 실행할 때 쉘은 무엇을해야하는지 알기 위해 스크립트를 읽어야합니다.


답변

당신은 생각 setuid합니다.

대부분의 배포판 setuid은 방대한 보안상의 허물이기 때문에 (분명히) 비활성화했기 때문에 불가능합니다. 내 기능이 비활성화되어 있으므로 실제로이 답변이 효과가 있다는 것을 모르겠습니다. 어쨌든 게시 해야 한다고 생각 합니다 .

어쨌든, 내가하고 싶은 일을하고 싶고 setuid스크립트 를 사용할 수 있는 배포판을 가지고 있다면 다음과 같이 할 것입니다.

$ chmod 700 myscript
$ cat > myscript-nonroot
#!/bin/sh
bash myscript
^D
$ sudo chown root:root myscript-nonroot
$ sudo chmod 4755 myscript-nonroot # make SURE this isn't world-writable!

즉, 읽기 전용 스크립트를 호출하고 루트가 소유하도록 스크립트를 변경하고 setuid 권한을 부여하는 것이 유일한 목적인 다른 스크립트를 작성하려고합니다. (다른 모든 사람이 수행 할 수있는 기록 불가능한 상태와 함께.)

myscript-nonroot 함수는 모든 사람이 읽을 수 있기 때문에 읽고 실행할 수 있으며 실제로 스크립트를 실행하는 두 줄을 얻었을 때 ( bash myscript) 루트로 실행됩니다 (또는 원하는 다른 사람, 정확한 사용자 래퍼 파일이 동일한 사용자가 소유하는 한 중요하지 않습니다.)


답변

이전 진술에는 반 사실이 있습니다. 사용자가 스크립트를 읽을 수는 없지만 여전히 실행 가능하도록 스크립트를 설정할 수 있습니다. 프로세스는 약간 작성되었지만 / etc / sudoer에서 예외를 작성하면 사용자가 비밀번호를 묻지 않고 스크립트를 임시로 실행할 수 있습니다. 이 방법 :-다른 배포판의 setuid 패치를 가져옵니다. -사용자에게 모든 권한을 부여하지 않고 특정 스크립트에 대해 일시적으로 높은 권한을 부여 할 수 있습니다.

이 게시물의 지침을 따르십시오 :
파일 권한 실행 만


답변

이 상황에서 sudo를 NOPASSWD 옵션과 함께 사용하여 사용자가 스크립트를 읽을 수없이 스크립트를 실행할 수 있습니다.


답변

OpenBSD에서 작동합니다

@eradman 의 의견 에서 이미 언급했듯이 OpenBSD에서 가능합니다.

루트로 :

hzy# cat <<'EOT' >/tmp/foo; chmod 001 /tmp/foo
#! /bin/sh
: this is secret
echo done
EOT

일반 사용자로서 :

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ /tmp/foo
done

그것은 /dev/fd/3통역사에게 (또는 열려있는 fd를 스크립트 에 전달하여) 작동합니다 . 그 비결은 할 수 없습니다 리눅스에서 작동 /dev/fd/N이는 반환 특수 문자 장치가 아닙니다 dup(2)열린 FD의, 그러나 처음부터 파일을 열 원본 파일 / dentry에 “마법”심볼릭 링크, [1]. 그것은 수있는 무료 / NetBSD의 또는 Solaris에서 구현 될 …

그러나 그것이 깨지기 쉬운 것은 아닙니다.

기본적으로 x(실행) 권한을 부여한다는 r것은 shebang이있는 모든 파일에 대해 (읽기) 권한을 부여하는 것입니다 [2] :

hzy$ cat /tmp/foo
cat: /tmp/foo: Permission denied
hzy$ ktrace -ti /tmp/foo
done
hzy$ kdump | tail -n8
 70154 sh       GIO   fd 10 read 38 bytes
       "#! /bin/sh
        : this is secret
        echo done
       "
 70154 sh       GIO   fd 1 wrote 5 bytes
       "done

ktrace유일한 방법은 아닙니다. 인터프리터가 perlor 와 같이 동적으로 실행 가능한 링크 인 경우 함수 를 재정의 python하는 LD_PRELOADed 핵을 read(2)대신 사용할 수 있습니다.

그리고 setuid로 설정한다고해서 일반 사용자가 내용을 볼 수있는 것은 아닙니다. 그녀는 간단히 아래 ptrace(2)에서 실행할 수 있으며 setuid 비트는 무시됩니다.

루트로 :

hzyS# cat <<'EOT' >/tmp/bar; chmod 4001 /tmp/bar
#! /bin/sh
: this is secret
id
EOT

일반 사용자로서 :

hzyS$ ktrace -ti /tmp/bar
uid=1001(duns) euid=0(root) gid=1001(duns) groups=1001(duns)
hzyS$ kdump
    ... nothing, the kernel disabled the ktrace ...
hzyS$ cc -Wall -xc - -o pt <<'EOT'
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <signal.h>

int main(int ac, char **av){
        int s; pid_t pid;
        if((pid = fork()) == 0){
                ptrace(PT_TRACE_ME, 0, 0, 0);
                execvp(av[1], av + 1);
        }
        while(wait(&s) > 0 && WIFSTOPPED(s)){
                s = WSTOPSIG(s);
                ptrace(PT_CONTINUE, pid, (caddr_t)1, s == SIGTRAP ? 0 : s);
        }
}
EOT
hzyS$ ./pt ktrace -ti /tmp/bar
uid=1001(duns) gid=1001(duns) groups=1001(duns)
hzyS$ kdump | tail -5
 29543 sh       GIO   fd 10 read 31 bytes
       "#! /bin/sh
        : this is secret
        id
       "

(이것이 그것을 설명하기 가장 어려운 방법이 아닌 경우 죄송합니다)

[1]을 사용하여 Linux에서 에뮬레이션 할 수 binfmt_misc있지만 인터프리터를 수정하거나 래퍼를 사용해야합니다. 의도적 으로 엄청나게 안전하지 않은 예를 보려면 이 답변 의 마지막 부분을 참조하십시오 .

[2] 또는 일반적으로을 execve()반환 하지 않는 파일입니다 ENOEXEC.