Um script pode ser executável, mas não legível?

65

É possível executar um script se não houver permissão para lê-lo? No modo raiz, criei um script e quero que o outro usuário execute esse script, mas não o leia. Fiz chmodpara proibir a leitura e gravação, mas permiti executar, no entanto, no modo de usuário, vi a mensagem que diz: permissão negada.

como ele
fonte

Respostas:

68

A questão é que o roteiro não é o que está funcionando, mas o intérprete ( bash, perl, python, etc.). E o intérprete precisa ler o script. Isso é diferente de um programa "regular", como ls, porque o programa é carregado diretamente no kernel, como faria o intérprete. Como o próprio kernel está lendo o arquivo do programa, não precisa se preocupar com o acesso de leitura. O intérprete precisa ler o arquivo de script, pois um arquivo normal precisaria ser lido.

Arcege
fonte
2
Sim, mas no caso dele existe uma solução?
Olivier Pons
13
Uma possibilidade seria ter um programa C simples que incorpore o script e chame o intérprete explicitamente. O programa AC não precisa ter permissões de leitura para executar.
Arcege 22/03/12
11
Estritamente falando, o kernel não discrimina neste caso e , de fato, executa o shell (da mesma maneira que se o arquivo executável fosse um binário). No entanto, o próprio shell falhará imediatamente porque não pode ler o arquivo de entrada (o conteúdo do arquivo de script).
Jozef
34

Isso é possível apenas para binários.

$ chown foo:foo bar
$ chmod 701 bar

Como usuário não privilegiado:

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

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Agora, aqui está o kicker. Embora o arquivo seja ilegível por meios convencionais, você não pode impedir a leitura do arquivo. Este é realmente um desafio em http://smashthestack.org/ (nível 13). Há um utilitário conhecido chamado hktraceque permite que você leia o arquivo usando ptrace.

kwarrick
fonte
Muito interessante (hktrace).
Fthinker 16/03/12
11
é possível converter shell script em formato binário?
Ashim
4
Na verdade, você pode impedir, eu acho. As versões atuais do kernel do linux definem o processo como não despejável, o que significa que nenhum usuário normal pode rastrear mais, se o usuário não tiver permissão para ler o binário.
thejh 15/05
6

Isso não é possível, pelo menos no Linux (outros Unices podem permitir); pense nisso, quando você executa o script, o shell precisa lê-lo para saber o que fazer.

Renan
fonte
3
Certamente é possível; O OpenBSD permite que qualquer script seja executado sem permissão de leitura. Sob o capô, ele faz isso criando um descritor de arquivo duplicado para o intérprete usar.
eradman
@eradman Eu coloquei isso (junto com um exemplo, explicação e algumas observações minhas) em uma resposta .
mosvy 15/10
3

Acho que você pode fazer isso com setuid.

Só que você não pode, porque a maioria das distros (aparentemente) foi setuiddesativada porque é uma enorme falha de segurança. Ele está desativado no meu, então eu realmente não sei se essa resposta funcionará, eu estou postando de qualquer maneira, porque acho que deveria .

De qualquer forma, se eu quisesse fazer o que você queria - e tivesse uma distribuição setuidhabilitada para scripts -, faria algo como:

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

Ou seja, eu escreveria outro script cujo único objetivo é chamar o script somente leitura de raiz, alterá-lo para pertencer ao root e conceder a permissão setuid. (Juntamente com o status de não gravável do atendente por todos os outros.)

Como a função myscript-nonroot é legível por todos, ela pode ser lida e executada e, quando você obtém dois na linha em que realmente executa seu script ( bash myscript), ela está sendo executada como root (ou quem quiser, o usuário exato não importa, desde que o arquivo wrapper seja de propriedade do mesmo usuário.)

quodlibetor
fonte
O que significa 4755? Eu sou novo nisso, então gostaria de saber o que isso significa. Eu entendo a parte 755. Graças
Kevdog777
2
o 4define o bit setuid . Veja a seção Modes na página de manual do chmod em manpagez .
quodlibetor
Ok, ainda não entendi direito, mas demorei um pouco para entender o 755pouco.
Kevdog777
sim, na verdade chmod 755é o mesmo que 0775 octal. há muita confusão em torno disso .. Esta página ( manpagez.com/man/1/chmod ) tem um deslocamento horizontal awfull e unneded que eu não consigo entender ...
erm3nda
2

Há meia verdade nas declarações anteriores. Você pode configurar um script para que não seja legível pelo usuário, mas ainda executável. O processo é um pouco demorado, mas é possível abrir uma exceção no / etc / sudoer, para que o usuário possa executar o script como você mesmo temporariamente sem ser solicitada uma senha. Este método: - contorna o patch setuid para outras distribuições. - permite que você conceda permissões elevadas temporariamente para um script específico sem conceder ao usuário direitos de sudo para tudo.

Siga as instruções nesta postagem: Permissão de arquivo executar apenas

santana
fonte
1

Nesta situação, usei o sudo com uma opção NOPASSWD para que os usuários possam executar o script sem poder lê-lo.

user33577
fonte
0

Funciona no OpenBSD

Como já mencionado em um comentário de @eradman, isso é possível no OpenBSD.

Como raiz:

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

Como usuário regular:

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

Isso funciona passando /dev/fd/3(ou seja o que for o código aberto para o script) para o intérprete. Esse truque não funcionaria no Linux, onde /dev/fd/Nnão há dispositivos de caracteres especiais que retornam um valor dup(2)de fd quando abertos, mas links simbólicos "mágicos" para o arquivo / dentry original, que abrem o arquivo do zero [1]. Ele poderia ser implementado no Free / NetBSD ou Solaris ...

Mas não é o que parece ser

Basicamente, conceder a xpermissão (executar) significa também conceder a rpermissão (ler) em qualquer arquivo que tenha um 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

ktracenão é o único caminho; se o intérprete for executável dinamicamente vinculado como perlou python, um LD_PRELOADhack ed que substitui a read(2)função pode ser usado.

E não, torná-lo setuid não impedirá que um usuário comum veja seu conteúdo; ela poderia simplesmente executá-lo ptrace(2), o que fará com que os bits setuid sejam ignorados:

Como raiz:

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

Como usuário regular:

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
       "

(desculpe se esta não é a maneira mais direta de demonstrá-lo)

[1] isso pode ser emulado no Linux usando binfmt_misc, mas o intérprete terá que ser modificado ou um wrapper terá que ser usado; veja a última parte desta resposta para um exemplo deliberadamente ridiculamente inseguro.

[2] ou, em geral, qualquer arquivo que não cause execve()retorno ENOEXEC.

mosvy
fonte
-2

Sim, se você é usuário root, pode executar o arquivo sem permissão de leitura

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

Mas se você fizer login com outro usuário, não poderá executar este arquivo

$ ./test
-bash: ./test: Permission denied
gaurav goyal
fonte
3
Isso realmente não responde à pergunta, porque o root ainda pode ler o arquivo mesmo sem permissão.
Wjandrea 22/03
-5

Para tornar seus scripts ilegíveis e ainda executáveis, você tem três opções principais:

Primeira opção

Use o comando openssl para criptografá-lo manualmente. E no futuro, quando você quiser executar o script, precisará executar o openssl manualmente novamente e fornecer a senha para descriptografar.

Criptografia com openssl:

gato herscript.sh | openssl aes-128-cbc -a -sal -k sua senha> YOURScript.enc

Descriptografia com openssl:

gato herscript.enc | openssl aes-128-cbc -a -d -salt -k sua senha> YOURScript.dec

herscript.dec será igual ao seu script original herscript.sh

Segunda opçao

Use um site como www.Enscryption.com para criptografar automaticamente seu script e tornar a versão criptografada do script executável. Este site usa os recursos de criptografia do openssl e alguns outros métodos de ofuscação para dificultar a invasão de intrusos em seu script ou desvendar segredos que você deseja ocultar. Com este site, você pode criptografar scripts de shell e scripts de linha de comando perl, python, ruby. Eu acho que php também.

Terceira opção

Use uma ferramenta como shc . Parece que não foi atualizado desde 2012. mas eu o usei no passado. Você deve compilar seu script para cada sistema operacional no qual deseja usá-lo, se o sistema operacional for diferente daquele em que você o compilou.

Resumo:

Se ocultar seu código é de grande importância para você, confiar apenas em permissões e propriedade ajudará você, pois qualquer pessoa com root pode acessá-lo. Isso é apenas um fato. O que você pode fazer, se realmente deseja impedir a visualização não autorizada de seu código por alguém, é escrever um script em torno do comando openssl. Faça com que, antes da execução do script, ele solicite uma senha E, depois que a senha for fornecida, execute o script sem gravá-lo em um arquivo temporário. Se isso parecer muito trabalho, as opções 2 e 3 devem ser suficientes para seus propósitos.

AncientMinds
fonte
O link "shc" também aponta para a página anterior. Por acaso, você está afiliado a esta página / serviço?
Php
3
Se você codificar seu script, ele não poderá ser executado sem a chave. Se você enviou a chave a um usuário para executá-la, poderá ver seu conteúdo. Este anwers é tão estúpido ...
erm3nda