Чи може сценарій бути виконаним, але не читабельним?


65

Чи можливо виконати скрипт, якщо немає дозволу на його читання? У кореневому режимі я створив сценарій і хочу, щоб інший користувач виконав цей скрипт, але не читав його. Я chmodзаборонив читати і писати, але дозволяв виконувати, проте в користувальницькому режимі я побачив повідомлення, яке говорить: у дозволі відмовлено.


Пов’язано: виконайте сценарії, не розшифровуючи їх .
Скотт

Відповіді:


68

Питання полягає в тому , що сценарій не те , що працює, але перекладач ( bash, perl, pythonі т.д.). І перекладачеві потрібно прочитати сценарій. Це відрізняється від "звичайної" програми, наприклад ls, тим, що програма завантажується безпосередньо в ядро, як би перекладач. Оскільки саме ядро ​​читає програмний файл, йому не потрібно турбуватися про доступ до читання. Інтерпретатору потрібно прочитати файл сценарію, оскільки його слід прочитати звичайний файл.


2
Так, але в його випадку є рішення?
Олів'є Понс

13
Однією з можливостей було б мати просту програму C, яка вбудовує скрипт і чітко викликає інтерпретатора. Програмі змінного струму не потрібно мати дозволи на читання для виконання.
Арседж

1
Строго кажучи, ядро не розрізняє в цьому випадку , і це буде насправді запустити оболонку (так само, як якщо виконуваний файл був бінарним). Однак сама оболонка негайно вийде з ладу, оскільки вона не може прочитати вхідний файл (вміст файлу сценарію).
Юзеф

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
чи можна конвертувати скрипт оболонки у двійковий формат?
ашим

4
Насправді, ви можете це запобігти, я думаю. Поточні версії ядра Linux встановлюють процес, який не можна дублювати, що означає, що жоден звичайний користувач не може його більше відстежувати, якщо користувачеві заборонено читати двійкові файли.
thejh

6

Це неможливо, принаймні в Linux (це можуть дозволити інші Unices); подумайте про це, коли ви запустите скрипт, оболонці потрібно прочитати його, щоб знати, що робити.


3
Це, безумовно, можливо; OpenBSD дозволяє виконувати будь-який сценарій без дозволу читання. Під кришкою це робиться, створюючи дескриптор файлу дублікатів для інтерпретатора.
ерадман

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

Що означає, що я би написав інший скрипт, єдиною метою якого є зателефонувати в скрипт, який доступний лише для читання root, змінити його у власність root та надати йому дозвіл встановлення. (Поряд із статусом супутнього непридатного для запису всіх інших.)

Оскільки функція myscript-nonroot читається всіма, її можна прочитати та виконати, і до того моменту, коли ви отримаєте два рядки, де ви фактично виконуєте свій скрипт ( bash myscript), він запускається як root (або хто ще хоче, точний користувач не має значення, якщо файл обгортки належить одному користувачеві.)


Що означає 4755? Я новачок у цьому, тому хотів би знати, що це означає. Я розумію частину 755. Спасибі
Kevdog777

2
то 4встановлює УИП біт. Дивіться розділ Режими на сторінці chmod man на manpagez .
quodlibetor

Гаразд, я все ще не зовсім розумію, але мені знадобилося певний час, щоб зрозуміти 755біт.
Kevdog777

Так, насправді chmod 755це 775 восьмільників. навколо цього багато плутанини .. На цій сторінці ( manpagez.com/man/1/chmod ) є приголомшливий і без необмеженої горизонтальної прокрутки, яку я не можу зрозуміти ...
erm3nda

2

У попередніх твердженнях є половина правди. Ви можете налаштувати сценарій так, щоб він не читався користувачем, але все-таки виконувався. Процес трохи промальовано, але це можливо, зробивши виняток у / etc / sudoer, щоб користувач міг тимчасово запускати скрипт як сам, не вимагаючи ввести пароль. Цей метод: - обходить встановлений патч для інших дистрибутивів. - дозволяє надати підвищені дозволи до певного сценарію, не надаючи користувачеві права на sudo на все.

Дотримуйтесь інструкцій у цій публікації: Дозвіл файлів виконується лише


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 сценарію). Цей трюк не буде працювати в Linux, де /dev/fd/Nне спеціальні пристрої символів, які повертають a dup(2)fd при відкритті, але "магія" посилається на оригінальний файл / зубний ряд, який відкриває файл з нуля [1]. Він може бути реалізований у Free / NetBSD або Solaris ...

Але це не те, що це тріщини

В основному, надання xдозволу на виконання (виконання) означає також надання rдозволу на (читання) будь-якому файлу, у якому є шебанг [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не єдиний спосіб; якщо інтерпретатор є динамічно пов'язаним виконуваним файлом, наприклад, perlабо python, LD_PRELOADзамість нього read(2)може бути використаний ed-хак, який замінює функцію.

І ні, якщо налаштувати його не завадить звичайному користувачеві бачити його вміст; вона може просто запустити його під ptrace(2), що призведе до ігнорування встановлених бітів:

Як корінь:

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

Так, якщо ви користувач root, ви можете виконати файл без дозволу читання

# 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

Щоб зробити ваші сценарії нечитабельними, але вони доступні для виконання, у вас є три основні варіанти:

Перший варіант

Використовуйте команду openssl, щоб її вручну зашифрувати. І в майбутньому, коли ви хочете запустити скрипт, вам доведеться знову запустити openssl вручну та надати пароль для розшифровки.

Шифрування за допомогою openssl:

кішка вашаcript.sh | openssl aes-128-cbc -a -salt -k yourpassword> tvojecript.enc

Розшифрування за допомогою openssl:

кішка tvojecript.enc | openssl aes-128-cbc -a -d -salt -k yourpassword> tvojecript.dec

tvojcript.dec буде таким самим, як і ваш оригінальний скрипт tvojecript.sh

Другий варіант

Використовуйте веб-сайт на зразок www.Enscryption.com, щоб автоматично зашифрувати ваш сценарій і зробити зашифровану версію сценарію виконуваною. Цей веб-сайт використовує як можливості шифрування openssl, так і деякі інші методи обфускування, щоб зробити зловмисникам досить важко зазірнути у ваш сценарій або розкрити секрети, які ви хочете приховати. За допомогою цього сайту ви можете зашифрувати сценарії оболонки та командний рядок сценаріїв perl, python, ruby. Я думаю, що і php.

Третій варіант

Використовуйте такий інструмент, як shc . Схоже, він не оновлювався з 2012 року, але я його використовував і раніше. Ви повинні скласти свій скрипт для кожної ОС, на якій ви хочете використовувати його, якщо ОС відрізняється від тієї, яку ви використовували для її складання.

Підсумок:

Якщо приховування вашого коду має велике значення для вас, покладаючись лише на дозволи та право власності, вам допоможе, оскільки до нього може потрапити кожен, хто має root. Це просто факт. Що ви можете зробити, якщо ви дійсно хочете, щоб запобігти несанкціонованому перегляду вашого коду ким-небудь, - це написати сценарій навколо команди openssl. Зробіть так, щоб перед запуском скрипту з'явиться запит на пароль І після введення пароля він запустить скрипт, не записуючи його у тимчасовий файл. Якщо це звучить як занадто багато роботи, то варіантів 2 і 3 повинно бути достатньо для ваших цілей.


Посилання "shc" також вказує на одну сторінку від раніше. Ви будь-яким випадком пов’язані з цією сторінкою / послугою?
phk

3
Якщо ви зашифруєте свій сценарій, він не зможе запуститися без ключа. Якщо ви надіслали ключ користувачеві для запуску, він зможе побачити його вміст. Цей анверс такий дурний ...
erm3nda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.