it-swarm-eu.dev

Může být skript spustitelný, ale ne čitelný?

Je možné skript spustit, pokud k jeho čtení není povoleno? V kořenovém režimu jsem vytvořil skript a chci, aby tento uživatel tento skript provedl, ale nečetl jej. Udělal jsem chmod, abych zakázal čtení a zápis, ale umožnil spuštění, ale v uživatelském režimu jsem viděl zprávu, která říká: oprávnění odepřeno.

69
ashim

Problém je v tom, že skript není spuštěný, ale interpret (bash, Perl, python, atd.). A tlumočník musí číst skript. To se liší od „běžného“ programu, jako je ls, v tom, že program je načten přímo do jádra, jak by interpretoval. Jelikož samotné jádro čte programový soubor, nemusí se starat o přístup ke čtení. Tlumočník musí číst soubor skriptu, protože normální soubor bude třeba číst.

70
Arcege

To je možné pouze u binárních souborů.

$ chown foo:foo bar
$ chmod 701 bar

Jako neprivilegovaný uživatel:

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

$ cat bar
cat: bar: Permission denied

$ ./bar
baz

Teď je tu kicker. I když je soubor nečitelný běžnými prostředky, nemůžete ve skutečnosti zabránit čtení souboru. To je vlastně výzva pro http://smashthestack.org/ (level 13). Existuje známý nástroj s názvem hktrace, který vám umožní číst soubor pomocí ptrace.

35
kwarrick

To není možné, přinejmenším v Linuxu (to mohou dovolit i jiné úřady); přemýšlejte o tom, když spustíte skript, musí ho Shell přečíst, aby věděl, co dělat.

6
Renan

S předchozími tvrzeními je polovina pravdy. Skript můžete nastavit tak, aby jej uživatel nemohl číst, ale aby byl stále spustitelný. Tento proces je trochu vyčerpaný, ale je to proveditelné uděláním výjimky v/etc/sudoer, takže uživatel může skript dočasně spustit jako sám, aniž by byl vyzván k zadání hesla. Tato metoda: - obchází setuid patch pro další distros. - umožňuje dočasně udělit zvýšená oprávnění ke konkrétnímu skriptu, aniž by uživatel měl sudo práva na všechno.

Postupujte podle pokynů na tomto příspěvku: Pouze oprávnění ke spuštění soubor

3
santana

Myslím, že to můžete udělat s setuid.

S výjimkou, že to nemůžete, protože většina distros (zjevně) má zakázáno setuid, protože je to obrovská bezpečnostní díra. Je to zakázáno na mém, takže vlastně nevím, že tato odpověď bude fungovat, přesto ji zveřejňuji, protože si myslím, že to mělo by.

Kdybych chtěl dělat to, co jsi chtěl dělat - a měl jsem distro s povoleným skriptem setuid - udělal bych něco jako:

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

Což znamená, že bych napsal další skript, jehož jediným účelem je volat skript jen pro čtení root, změnit jej tak, aby byl ve vlastnictví root, a dát mu povolení setuid. (Spolu s nepřetržitým stavem, který nelze zapisovat, všichni ostatní.)

Vzhledem k tomu, že funkce myscript-nonroot je čitelná pro všechny, lze ji přečíst a spustit a v době, kdy dostanete dva řádky, kde skutečně provedete skript (bash myscript) je spuštěn jako root (nebo kdokoli jiný chcete, na přesném uživateli nezáleží, pokud je soubor wrapper vlastněn stejným uživatelem.)

3
quodlibetor

V této situaci jsem použil Sudo s možností NOPASSWD, aby uživatelé mohli skript spouštět, aniž by ho mohli číst.

2
user33577

Funguje to na OpenBSD

Jak již bylo uvedeno v comment @ @ adadman, je to možné na OpenBSD.

Jako root:

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

Jako běžný uživatel:

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

To funguje tak, že předáte /dev/fd/3 (Nebo cokoli, co je otevřený fd skriptu) tlumočníkovi. Tento trik by nefungoval v systému Linux, kde /dev/fd/N Nejsou speciální znaková zařízení, která vracejí dup(2) fd když se otevře, ale "magický" symbol se spojí s původním souborem/dentry, který soubor otevře od nuly [1]. To by mohlo být implementováno do Free/NetBSD nebo Solaris ...

Ale to není to, co je rozbité

V zásadě udělení oprávnění x (spuštění) znamená také udělení oprávnění r (čtení) pro každý soubor, který má 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 není jediný způsob; Pokud je interpret dynamicky propojitelný spustitelný soubor jako Perl nebo python, mohl by se místo toho použít hack LD_PRELOAD ed, který přepíše funkci read(2).

A ne, to, že bude nastaveno, nezabrání běžnému uživateli vidět jeho obsah; mohla to jednoduše spustit pod ptrace(2), což způsobí ignorování bitů setuid:

Jako root:

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

Jako běžný uživatel:

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
       "

(promiňte, pokud to není nejpřímější způsob, jak to prokázat)

[1] to by mohlo být emulováno na Linuxu pomocí binfmt_misc, Ale tlumočník bude muset být upraven nebo musí být použit obal; viz poslední část tato odpověď pro příklad záměrně , směšně nezabezpečený.

[2] nebo obecně jakýkoli soubor, který nezpůsobí, že execve() vrátí ENOEXEC.

0
mosvy