스크립트는 실행 가능하지만 읽을 수는 없습니까?


65

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


답변:


68

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


2
예. 그러나 그의 경우에는 해결책이 있습니까?
Olivier Pons

13
하나의 가능성은 스크립트를 포함하고 인터프리터를 명시 적으로 호출하는 간단한 C 프로그램을 갖는 것입니다. AC 프로그램은 실행을 위해 읽기 권한이 필요하지 않습니다.
Arcege

1
엄밀히 말하면, 커널은이 경우 차별하지 않고 는 것 (실행 파일이 진 것처럼 같은 방식으로) 실제로 쉘을 실행합니다. 그러나 입력 파일 (스크립트 파일 내용)을 읽을 수 없으므로 셸 자체가 즉시 중단 됩니다 .
Jozef

34

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

$ 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.


매우 흥미 롭습니다 (hktrace).
fthinker

1
쉘 스크립트를 이진 형식으로 변환 할 수 있습니까?
ashim

4
사실, 당신은 그것을 막을 수 있다고 생각합니다. 현재 리눅스 커널 버전은 프로세스를 덤프 불가능으로 설정합니다. 즉, 사용자가 바이너리를 읽을 수 없다면 일반 사용자는 더 이상 ptrace 할 수 없습니다.
thejh

6

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


3
확실히 가능하다. OpenBSD를 사용하면 읽기 권한없이 스크립트를 실행할 수 있습니다. 후드에서 인터프리터가 사용할 중복 파일 디스크립터를 작성하여이를 수행합니다.
eradman

@eradman 나는 그것을 (예제, 설명 및 내 말과 함께) 대답에 넣었습니다 .
mosvy

3

당신은 생각 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) 루트로 실행됩니다 (또는 원하는 다른 사람, 정확한 사용자 래퍼 파일이 동일한 사용자가 소유하는 한 중요하지 않습니다.)


4755은 무슨 뜻인가요? 나는 이것에 익숙하지 않기 때문에 그것이 무엇을 의미하는지 알고 싶습니다. 755 부분을 이해합니다. 감사합니다
Kevdog777

2
4설정한다 setuid를 비트. manpagezchmod 매뉴얼 페이지에 있는 Modes 섹션을 참조하십시오 .
quodlibetor

그래, 나는 여전히 이해하지 못하지만 755비트 를 이해하는 데 시간이 걸렸다.
Kevdog777

그렇습니다, 실제로 chmod 755는 0775 8 진수와 같습니다. 그 주위에 많은 혼란이 있습니다 ..이 페이지 ( manpagez.com/man/1/chmod )에는 이해할 수없는 끔찍한 가로 스크롤이 있습니다 ...
erm3nda

2

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

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


1

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


0

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.


-2

예, 루트 사용자 인 경우 읽기 권한없이 파일을 실행할 수 있습니다

# echo "echo hello" > test
# chmod 100 test
# ll test
---x------ 1 root root 10 Nov 29 12:13 test
# ./test
hello

그러나 다른 사용자로 로그인하면이 파일을 실행할 수 없습니다

$ ./test
-bash: ./test: Permission denied

3
이것은 실제로 질문에 대답하지 못하므로 root는 여전히 권한없이 파일을 읽을 수 있습니다.
wjandrea

-5

스크립트를 읽을 수는 없지만 실행 가능하게하려면 다음 3 가지 주요 옵션이 있습니다.

첫 번째 옵션

openssl 명령을 사용하여 수동으로 암호화하십시오. 그리고 나중에 스크립트를 실행하려면 openssl을 수동으로 다시 실행하고 암호를 제공하여 암호를 해제해야합니다.

openssl을 사용한 암호화 :

고양이 yourscript.sh | openssl aes-128-cbc -a -salt -k yourpassword> yourscript.enc

openssl을 이용한 복호화 :

고양이 yourscript.enc | openssl aes-128-cbc -a -d -salt -k yourpassword> yourscript.dec

yourscript.dec은 원본 스크립트 yourscript.sh와 동일합니다.

두 번째 옵션

www.Enscryption.com 과 같은 사이트 를 사용하여 스크립트를 자동으로 암호화하고 스크립트의 암호화 된 버전을 실행 가능하게 만드십시오. 이 사이트는 openssl의 암호화 기능과 다른 난독 화 방법을 모두 사용하여 침입자가 스크립트를 들어 올리거나 숨기고 싶은 비밀을 공개하기가 매우 어렵습니다. 이 사이트를 사용하면 쉘 스크립트와 명령 행 perl, python, ruby ​​스크립트를 암호화 할 수 있습니다. 나는 PHP도 생각한다.

세 번째 옵션

shc 와 같은 도구를 사용하십시오 . 2012 년 이후로 업데이트되지 않은 것 같습니다.하지만 과거에는 사용했습니다. OS가 컴파일에 사용한 OS와 다른 경우, 사용하려는 각 OS에 대해 스크립트를 컴파일해야합니다.

요약:

코드를 숨기는 것이 당신에게 매우 중요하다면, 권한을 가진 사람 만이 루트를 가진 사람이 접근 할 수 있기 때문에 도움이 될 것입니다. 그것은 단지 사실입니다. 누군가가 코드를 무단으로 보지 못하게하려면 openssl 명령 주위에 스크립트를 작성해야합니다. 스크립트를 실행하기 전에 비밀번호를 묻는 메시지가 표시되고 비밀번호가 제공된 후 임시 파일에 쓰지 않고 스크립트를 실행하도록하십시오. 이것이 너무 많은 일처럼 들리면 옵션 2와 3으로 충분합니다.


"shc"링크는 이전의 한 페이지를 가리 킵니다. 이 페이지 / 서비스와 관련이 있습니까?
phk

3
스크립트를 암호화하면 키 없이는 실행할 수 없습니다. 키를 실행하기 위해 사용자에게 키를 보낸 경우 해당 내용을 볼 수 있습니다. 이
anwers
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.