Выполнение сценария bash или двоичного файла c в файловой системе с параметром noexec

Telnet - это необработанный TCP-клиент, поэтому, конечно же, его эквивалентом в Linux является nc localhost 25 ?

10
08.01.2020, 11:27
6 ответов

Поскольку исполняемый файл bash не находится в указанной файловой системе.

-1
27.01.2020, 19:59

Выполнение команды таким образом:

bash hello_world

вы заставляете bashчитать из файла hello_world(, что не запрещено ).

В других случаях ОС пытается запустить этот файл hello_worldи терпит неудачу из-за флага noexec

3
27.01.2020, 19:59

В обоих случаях происходит одно и то же :для непосредственного выполнения файла, должен быть установлен бит выполнения, а файловая система не может быть смонтирована noexec. Но это ничего не мешает читать эти файлы.

Когда скрипт bash запускается как ./hello_worldи файл не является исполняемым (либо нет бита разрешения на выполнение, либо нет exec в файловой системе ), строка #!даже не проверил , потому что система даже не загружает файл. Сценарий никогда не "выполняется" в соответствующем смысле.

В случае с bash./hello_worldопция файловой системы noexec просто не так хороша, как хотелось бы. Запущенная команда bash— это /bin/bash, а /binне находится в файловой системе с noexec. Так что заводится без проблем. Системе все равно, что bash (, или python, или perl, или что-то еще )является интерпретатором. Он просто запускает команду, которую вы дали (/bin/bash), с аргументом, который оказывается файлом. В случае bash или другой оболочки этот файл содержит список команд для выполнения, но теперь мы «прошли» все, что будет проверять биты выполнения файла. Этот чек не несет ответственности за то, что произойдет позже.

Рассмотрим этот случай:

$ cat hello_world | /bin/bash

… или для тех, кому не нравится бессмысленное использование кошек:

$ /bin/bash < hello_world

Последовательность "shbang" #!в начале файла — это всего лишь приятная магия, позволяющая эффективно делать то же самое, когда вы пытаетесь выполнить файл как команду. Вам может быть полезна эта статья LWN.net:Как запускаются программы .

27
27.01.2020, 19:59

Предыдущие ответы объясняют, почему параметр noexecне препятствует запуску скрипта, когда интерпретатор (в вашем случае/bin/bash)явно вызывается из командной строки. Но если бы это было все, эта команда тоже сработала бы:

/lib64/ld-linux-x86-64.so.2 hello_world

Как вы заметили, это не работает. Это потому, что noexecимеет еще один эффект. Ядро не будет разрешать отображаемые в память файлы из этой файловой системы с включенным PROT_EXEC.

Файлы с отображением памяти используются в нескольких сценариях. Два наиболее распространенных сценария — для исполняемых файлов и библиотек. Когда программа запускается с помощью системного вызова execve, ядро ​​внутренне создает отображения памяти для компоновщика и исполняемого файла. Любые другие необходимые библиотеки отображаются в памяти компоновщиком через системный вызов mmapс включенным PROT_EXEC. Если вы попытаетесь использовать библиотеку из файловой системы с noexec, ядро ​​откажется выполнять вызов mmap.

При вызове /lib64/ld-linux-x86-64.so.2 hello_worldсистемный вызов execveтолько создаст сопоставление памяти для компоновщика, а компоновщик откроет исполняемый файл hello_worldи попытается создать сопоставление памяти почти так же, как это было бы сделано для библиотеки. И это тот момент, когда ядро ​​​​отказывается выполнять вызов mmap, и вы получаете ошибку :

.
./hello_world: error while loading shared libraries:./hello_world: failed to map segment from shared object: Operation not permitted

Параметр noexecпо-прежнему позволяет отображать память без разрешения на выполнение (, как это иногда используется для файлов данных ), а также разрешает обычное чтение файлов, поэтому bash hello_worldсработало для вас.

12
27.01.2020, 19:59

Когда вы запускаете скрипт через bash, он просто читает файл и интерпретирует его.

Однако, когда вы передаете имя ядру --, оно действительно проверяет файл на наличие " #!" и загружает интерпретатор, указанный в соответствии с параметром ядра «CONFIG _BINFMT _SCRIPT». Там написано:

Say Y here if you want to execute interpreted scripts starting with "#!" followed by the path to an interpreter.

You can build this support as a module; however, until that module gets loaded, you cannot run scripts. Thus, if you want to load this module from an initramfs, the portion of the initramfs before loading this module must consist of compiled binaries only.

Most systems will not boot if you say M or N here. If unsure, say Y.

Выше приведен текст справки, связанный с этой опцией. Для другого интересного разница. Я написал свой сценарий:

> cat myprog.sh
#!/bin/cat

echo "Hello World"
> chmod +x myprog.sh

Запуск с помощью bash по-прежнему запускает интерпретатор bash:

> bash myprog.sh
Hello World

Однако теперь это делает ядро ​​:

> myprog.sh
#!/bin/cat

echo "Hello World"

Ядро распечатало сценарий, включая 1-ю строку, потому что оно вызвало 'Кот'.

В случае с программой C вы не вызываете интерпретатор для запустить бинарник. Ядро пытается запустить его напрямую. Тем не менее, если вы загрузили все свои исполняемые файлы в память, используя некоторые отладчики, вы все еще можете «запускать» свою программу во время ее загрузки через отладчик.

Опция noexec похожа на отключение бита выполнения в двоичном файле и запрещает ядру запускать двоичный файл «исходно».

Это имеет значение, кстати, если ваша программа имеет бит SetUID установить в программе --загрузка с помощью интерпретатора не установит UID, эта привилегия может быть включена только при загрузке ядра.

FWIW --окна имеют тот же тип механизма.

Если добавить «.sh» в качестве «исполняемого суффикса», например «.exe» или «.vbs», окна автоматически запустит ваш файл в соответствии с тем, как вы настроили Файлы ".sh" для выполнения. Теоретически можно настроить Файлы «.txt» будут автоматически печататься, если вы введете их имя в командной строке.

Точно так же вы можете сделать короткий вызов программы для вывода текста. файлы на экран. Это причина не оставлять себя в системе в общественном месте.

2
27.01.2020, 19:59

в этом документе объясняется, почему

https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md

и

The answer is the same as dev mode -- use /usr/local for all arbitrary code.

конечно, другой способ:

cat xx.sh|sh  #what a boring type

или

mount -i -o remount,exec /home #aaaaaaaaa boring
-3
27.01.2020, 19:59

Теги

Похожие вопросы