Telnet - это необработанный TCP-клиент, поэтому, конечно же, его эквивалентом в Linux является nc localhost 25
?
Поскольку исполняемый файл bash не находится в указанной файловой системе.
Выполнение команды таким образом:
bash hello_world
вы заставляете bash
читать из файла hello_world
(, что не запрещено ).
В других случаях ОС пытается запустить этот файл hello_world
и терпит неудачу из-за флага noexec
В обоих случаях происходит одно и то же :для непосредственного выполнения файла, должен быть установлен бит выполнения, а файловая система не может быть смонтирована 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:Как запускаются программы .
Предыдущие ответы объясняют, почему параметр 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
сработало для вас.
Когда вы запускаете скрипт через 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» будут автоматически печататься, если вы введете их имя в командной строке.
Точно так же вы можете сделать короткий вызов программы для вывода текста. файлы на экран. Это причина не оставлять себя в системе в общественном месте.
в этом документе объясняется, почему
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