Могут ли скрипты работать, даже если они не установлены как исполняемые?

25

Я могу запустить скрипты (.sh) с и без их установки в качестве исполняемого. Так где именно это имеет значение?

Ashfame
источник

Ответы:

24

Допустим, у вас есть файл, myscriptсодержащий следующее:

#!/bin/bash
echo "Hello, World!"

Если вы сделаете этот файл исполняемым и запустите его с помощью ./myscript, то ядро ​​увидит, что первые два байта - #!это файл сценария. Затем ядро ​​будет использовать оставшуюся часть строки в качестве интерпретатора и передаст файл в качестве первого аргумента. Итак, он работает:

/bin/bash myscript

и bash читает файл и выполняет содержащиеся в нем команды.

Таким образом, для того, чтобы bash (или любой другой интерпретатор, которого требует ваш скрипт) «выполнял» скрипт, ему нужно только иметь возможность прочитать файл.

Таким образом, для сценариев бит выполнения просто делает его более удобным для выполнения. Пока bash является исполняемым, вы всегда можете запустить bash с файлом сценария в качестве аргумента, или запустить bash в интерактивном режиме и скопировать и вставить строку за строкой в ​​ваш терминал, чтобы выполнить команды.

geirha
источник
Спасибо за объяснение в деталях. :) Если я правильно понял, любому пользователю, имеющему доступ к bash, просто нужен доступ для чтения к сценарию, чтобы запустить его, потому что bash примет сценарий в качестве входных данных и ему нужно будет только прочитать его. Я могу остановить это поведение, получив разрешение на чтение сценария для этого пользователя. Правильно? Так, когда это исполняемое разрешение используется и точно имеет значение?
Ashfame
Да, если вы используете «bash myscript», то пользователю нужен только доступ для чтения «myscript» (и, конечно, исполняемый файл для / bin / bash, если в пути есть bash). Однако, если вы сделаете ваш скрипт исполняемым, все будет немного иначе. Это правда, что с точки зрения ядра, это будет снова "/ bin / bash myscript", если первая строка будет #! / Bin / bash, но чтобы достичь этой точки, сначала вам нужно представить скрипт как исполняемый для пользователь или группа. Тем не менее, это верно, если для какого-то пользователя сценарий не является исполняемым, но читаемым, он (а) может по-прежнему «запускать» сценарий с помощью «bash myscript» ....
LGB
@LGB Так что это в значительной степени бесполезно. Хорошая вещь состоит в том, чтобы удалить разрешение на чтение от пользователя для этого сценария. Правильно?
Ashfame
@Ashfame: я бы сказал, что полезно, а не бесполезно. Бит выполнения для обычных файлов не используется (и никогда не предназначался) для ограничения доступа. Кажется, вы ожидаете этого от этого. Если у вас есть двоичный исполняемый файл, вы должны иметь разрешение на его выполнение. Однако, если у вас есть доступ для чтения к нему, вы всегда можете скопировать файл в свой собственный домашний каталог, и в этом случае копия будет принадлежать вам, так что вы можете добавить к нему разрешение на выполнение ... и запустить его. Для каталогов, однако, это имеет немного другое назначение. См. Mywiki.wooledge.org/Permissions
geirha
1
Что мне следует использовать вместо / bin / bash, если я не знаю правильного переводчика? Есть ли команда, которая запускает скрипт в соответствии со строкой Шебанга?
Айвар
16

Убедитесь, что вы не путаете «выполнение сценария оболочки» с «запустите сценарий оболочки с помощью sh».

Это не будет зависеть от прав доступа к файлам file.sh:

sh file.sh

Вы выполняете sh(который разрешает программу /bin/sh), который читает file.shи выполняет свой код.

Права доступа к файлам будут действовать, если вы действительно выполните сам скрипт :

./file.sh

Обратите внимание, что права доступа к файлам не поддерживаются файловыми системами, отличными от Linux, такими как FAT. Таким образом, даже если вы запустите chmod -x file.shфайл, у него останутся прежние права доступа.

Разрешение на выполнение обеспечивается файловой системой. Но программы также могут «выполнять» код, считывая содержимое файла, что обходит права файловой системы на «выполнить».

Lekensteyn
источник
Я понимаю вашу точку зрения. Но тогда это для группы или мира или для обоих?
Ashfame
@Ashfame Если вы установите разрешение для исполняемого файла, сценарий может запускаться непосредственно пользователями, которые имеют это разрешение - независимо от того, имеют ли они его для группы, мира или владельца. Но даже люди, не имеющие разрешения на выполнение, могут выполнить его, вызвав другую программу (например bash) для выполнения - чтобы заблокировать, что вам также придется отозвать их readразрешение.
jg-faustus
If you set the executable permission, the script can be run directly by users who have that permission - whether they have it on a group, world or owner basisНо как разрешение предоставляется разным пользователям путем проверки исполняемого разрешения? И я получил ваше второе замечание. Вы имеете в виду удаление их разрешения на чтение сценария, чтобы они не могли даже обработать его через bash. Правильно?
Ashfame
@Ashfame В точке разрешения на чтение - да. О том, как вы могли бы вызвать что-то вроде sudo chmod g+x myfile.shв терминале, чтобы добавить разрешения на выполнение для группы файла. См. Учебник по разрешениям для файлов . Чтобы управлять разрешениями для нескольких пользователей одновременно, вы должны использовать группы, см., Например, Управление группами .
jg-faustus
что я имел в виду, когда мы добавляли исполняемое разрешение в графическом интерфейсе, а затем для кого? владелец / группа / мир?
Ashfame
1

Не думай об этом так. Могу ли я выполнить этот файл? Подумайте об этом так: кто может выполнить этот файл?

Если компьютер принадлежит вам, а файл - ваш, я уверен, что вы сможете выполнить его. Возможно, вы захотите изучить такие команды, как chmod и chown , а также права доступа к файлам.

Надеюсь, это поможет.

myusuf3
источник
Да, я знаю о них. Это означает, что я (владелец) всегда могу выполнить его. Правильно? Тогда установка файла в качестве исполняемого файла для группы или мира или для обоих?
Ashfame
1

execСистемный вызов в Linux ядра не удается с , EACCESесли файл не является исполняемым

Хотя вы можете сделать sh myprog.sh(который только читает файлы и интерпретирует это), пытаясь запустить программу как ./myprog.shне может работать, так как, когда вы делаете это:

Это можно проверить с помощью main.c:

#define _XOPEN_SOURCE 700
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

int main(void) {
    char *argv[] = {"myprog", NULL};
    char *envp[] = {NULL};
    int ret;
    ret = execve("myprog.sh", argv, envp);
    perror("execve");
    printf("%d\n", errno);
    printf("%d\n", EACCES);
}

и myprog.sh:

#!/bin/sh
echo worked

Если myprog.shэто не исполняемый файл, происходит mainсбой с:

execve: Permission denied
13
13

Проверено в Ubuntu 17.10 gcc -std=c99.

POSIX 7 упоминает, что в:

Функции exec, за исключением fexecve (), должны завершиться ошибкой, если:

[EACCES] В доступе к каталогу, указанному в префиксе пути нового файла образа процесса, отказано в разрешении на поиск, либо в новом файле образа процесса запрещено разрешение на выполнение.

Дополнительную информацию можно найти по адресу: /security/66550/unix-execute-permission-can-be-easily-bypassed-is-it-superfluous-or-whats-the

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
источник