Использование xargs в операторе case

Не -владелец не может прочитать файл, потому что setuid и setgid влияют только на действующие разрешения при выполнении файла ; в противном случае используются права доступа к файлу.Вот пример программы, которую можно попробовать:

readme.c

#include <stdio.h>

int main(int argc, char **argv) {
  FILE *f;
  int i;
  char c;

  if(argc>1) {
    f=fopen(argv[1],"rb");
    for(i=1; i++<100;) {
      c=getc(f);
      printf("%x%s", (int)c, i%50?" ":"\n");
    }
    fclose(f);
  }
}

Скомпилируйте его и измените его права доступа как кто-то, кроме того, с кем вы хотите протестировать (Я использовалroot):

# gcc -Wall -o readme readme.c
# chown root:root readme
# chmod ug+s,o-rw readme

Проверьте разрешения и попробуйте прочитать файл в качестве тестового пользователя:

erik ~ $ ls -la readme
-rwsr-s--x 1 root root 8064 May  4 12:05 readme
erik ~ $ cat readme
cat: readme: Permission denied

Теперь попробуйте запустить программу и заставить ее прочитать себя:

erik ~ $./readme readme
7f 45 4c 46 2 1 1 0 0 0 0 0 0 0 0 0 3 0 3e 0 1 0 0 0 fffffff0 5 0 0 0 0 0 0 40 0 0 0 0 0 0 0 40 18 0 0 0 0 0 0 0
0 0 0 40 0 38 0 9 0 40 0 1d 0 1c 0 6 0 0 0 4 0 0 0 40 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 40 0 0 0 0 0 0 0 fffffff8 1 0

Вы увидите, что проблем не возникло, потому что действующие разрешения изменились на пользователя с разрешениями на чтение.

Почему это происходит? На ум приходит несколько причин. Во-первых, никому не нужно иметь права на чтение для запуска исполняемого файла, потому что ядро ​​(, которое загружает программу ), уже имеет полные права на любые действия. Вам нужно иметь права на чтение только в том случае, если вы хотите просмотреть содержимое исполняемого файла, обычно для того, чтобы вы могли скопировать файл. Возможно, если назвать несколько возможных примеров, исполняемый файл содержит конфиденциальные данные, которые пользователи не должны видеть (, что настоятельно не рекомендуется, но это произошло! )или система использует это как эшелонированную защиту, чтобы люди не могли найти эксплойты.

1
11.05.2020, 02:31
2 ответа

case...in...esac являются конструкциями вsh-подобно языкам, поэтомуxargs(отдельная команда из оболочки, а не конструкция оболочки )должна вызывать оболочку для этого:

echo this | xargs -I'{}' sh -c '
  case $1 in
    (this) echo "is a test";;
  esac' sh '{}'

В любом случае вам нужно убедиться, что {}(, который в конечном итоге расширяется с помощью xargsдо содержимого каждой строки после обработки кавычек и пробелов ), не передается в код . ] для sh, встроенного скрипта (или в аргументе кода для любого интерпретатора, не только sh для этого имеет значение ), так как в противном случае это сделало бы его уязвимостью для внедрения кода.

Вместо этого здесь {}передается в качестве аргумента встроенному сценарию (, который извлекается в сценарии с помощью $1), поэтому его никак нельзя интерпретировать как шелл-код.

Если вы хотите запустить конструкцию caseв вашей текущей оболочке(zshздесь )в каждой строке вывода команды (, которая xargs -I'{}', кстати, работает только в том случае, если эти строки не t содержат обратную косую черту, одинарные кавычки, двойные кавычки и не заканчиваются пробелами ), вы можете сделать:

while IFS= read <&3 -r line; do
  case $line in
    (this)...;;
  esac 3<&-
done 3< <(a-command)

Или

for line (${(f)"$(a-command)"}) case $line in
  (this)...;;
esac

(пропускают пустые строки ).

3
28.04.2021, 23:15

Я бы подумал, что проблема в том, что оператор caseсостоит из нескольких строк. Так вы можете добиться большего успеха:

yourcommand | while read LINE ; do
  case "$LINE" in; this) echo "is a test";; esac
done
0
28.04.2021, 23:15

Теги

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