В чем разница между system() и execve()

Я использую линукс и с.

Сначала я подключаю bin/zsh к sh

Во-вторых, я вхожу в систему как root и запускаю следующую программу.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 char *v[3];
 if(argc < 2) {
  printf("Please type a file name.\n");
  return 1;
 }
 v[0] = "/bin/cat"; v[1] = argv[1]; v[2] = 0;
 /* Set q = 0 for system(), and q = 1 for execve */
 int q = 0;
 if (q == 0){
   char *command = malloc(strlen(v[0]) + strlen(v[1]) + 2);
   sprintf(command, "%s %s", v[0], v[1]);
   system(command);
 }
 else execve(v[0], v, 0);
 return 0 ; 
}

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

Как это:

./a.out text;\`echo \”Not right\”>text\`”

Теперь я могу написать "Неправильно" в файл "текст". У меня есть только права на чтение этого файла

введите здесь описание изображения

Права на чтение и запись этих файлов. введите здесь описание изображения

В-четвертых, я изменил q на 1. Это означает, что на этот раз вместо этого я использую execve.

И сделать то же самое, что и выше. Но на этот раз я не могу изменить содержимое файла.

Почему? Я гуглю в инете, но не могу найти разницы между system и execve.


person littletiger    schedule 19.10.2014    source источник
comment
Вы имеете в виду, в чем разница кроме факта system запускает команду и затем возвращает вызывающему, в то время как execve заменяет данные вызывающего процесса на вызываемый процесс, тем самым не имея состояния возврата для вызывающего (поскольку вызывающего больше нет)?   -  person WhozCraig    schedule 19.10.2014
comment
Вы имеете в виду, что execve использует привилегию обычного пользователя, но система использует привилегию root?   -  person littletiger    schedule 19.10.2014
comment
Команда, которую вы говорите, позволяет вам перезаписывать файл без необходимого разрешения, имеет несбалансированные (и странные) кавычки. Он не будет делать то, что вы имеете в виду, как есть (часть echo не будет запускаться вашей программой как есть). Что-то не так с вашими тестами, execve или система ничего не меняет в отношении privs. (Добавьте printf прямо перед return в main, чтобы увидеть разницу между system и execve.)   -  person Mat    schedule 19.10.2014
comment
Я делаю лабораторный тест, используя system() и execve(), чтобы увидеть, можно ли атаковать систему. Эхо-часть действительно изменила файл, в котором у обычного пользователя нет прав на запись. Но я не могу понять, почему.   -  person littletiger    schedule 19.10.2014
comment
@littletiger Можете ли вы отредактировать, чтобы исправить точную командную строку. Должны ли кавычки быть несоответствующими?   -  person luser droog    schedule 19.10.2014
comment
@luserdroog Вы видите командную строку? Прикладываю скриншот.   -  person littletiger    schedule 19.10.2014
comment
Да. Спасибо, что исправили это. Вы уверены в разрешениях? Каков результат ls -l text до и после изменения?   -  person luser droog    schedule 19.10.2014
comment
Прикладываю скриншот ls -l. Я забыл сказать, что я установил chmod 4755 на a.out.   -  person littletiger    schedule 19.10.2014
comment
Обратите внимание, что разрешения относятся к фактическим файлам, а не к ссылке. Чтобы отменить связь с файлом, не имеет значения, есть ли у вас разрешение на запись для него, у вас должно быть разрешение на запись для содержащей его папки.   -  person mafso    schedule 19.10.2014


Ответы (2)


system вызывает оболочку для анализа строки и обработки кавычек, интерполяции переменных и прочего. execve ничего из этого не делает. Он заменяет программу вызываемой программой и передает строки аргументов точно так, как указано; т.е. он не будет интерпретировать кавычки.

person luser droog    schedule 19.10.2014

Вы сказали, что сделали chmod 4755 a.out. Это означает, что вы устанавливаете бит setuid, и тогда программа всегда будет работать с привилегиями root и имеет доступ на запись к text. Строка с обратной кавычкой передается оболочке, которая интерпретирует ее как команду для записи в text.

Причина, по которой execve не записывает в текст, заключается в том, что он не интерпретирует свои аргументы как команду оболочки и ` не имеет особого значения.

person Per Johansson    schedule 19.10.2014