setuid(0) не выполняется для программы, принадлежащей root

Мне нужно написать код, который может получить привилегии root и выполнять операции на системном уровне. Вот что я написал (это не настоящий код, просто чтобы проверить, правильно ли я делаю что-то или нет):

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
    int current_uid = getuid();
    printf("My UID is: %d. My GID is: %d\n", current_uid, getgid());
    system("/usr/bin/id");
    if (setuid(0))
    {
        perror("setuid");
        return 1;
    }
    //I am now root!
    printf("My UID is: %d. My GID is: %d\n", getuid(), getgid());
    system("/usr/bin/id");
    //Time to drop back to regular user privileges
    setuid(current_uid);
    printf("My UID is: %d. My GID is: %d\n", getuid(), getgid());
    system("/usr/bin/id");
    return 0;
}

После выполнения gcc -o setuid setuid.c я запускаю ls -al для этого, чтобы получить следующие результаты:

tarun@staging:~$ ls -al setuid
-rwxr-xr-x 1 tarun tarun 9792 2009-10-03 18:09 setuid
adam@staging:~$

Попытка запустить приложение приводит к:

tarun@staging:~$ ./setuid
My UID is: 1000. My GID is: 1000
uid=1000(tarun) gid=1000(tarun) groups=1000(tarun),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),125(sambashare),999(bumblebee)
setuid: Operation not permitted

Я меняю владельца на root и соответствующим образом устанавливаю липкие биты:

tarun@staging:~$ su - root
Password:
staging:~# cd /home/tarun
staging:/home/tarun# chown root.root setuid
staging:/home/tarun# chmod +s setuid
staging:/home/tarun# ls -al setuid
-rwsr-sr-x 1 root root 9792 2009-10-03 18:09 setuid
staging:/home/tarun# exit
logout
tarun@staging:~$

Выполнение программы теперь дает:

adam@staging:~$ ./setuid
My UID is: 1000. My GID is: 1000
uid=1000(tarun) gid=1000(tarun) groups=1000(tarun),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),125(sambashare),999(bumblebee)
setuid: Operation not permitted

Хотя в идеале он должен был выполниться полностью и изменить мой uid на 0. Что я делаю неправильно?


person Tarun Verma    schedule 08.02.2015    source источник
comment
Мне кажется странным, что ваш файл датирован 2009 годом, в любом случае шаги, которые вы выполнили, должны работать, и они действительно сработали на моей машине.   -  person Rafael Almeida    schedule 08.02.2015
comment
@ Рафаэль, я думаю, это проблема с моей системой. Посмотрим, смогу ли я понять, что с этим не так.   -  person Tarun Verma    schedule 08.02.2015
comment
Проверьте вывод mount, чтобы увидеть, включен ли suid. Возможно, раздел смонтирован с помощью nosuid.   -  person Rafael Almeida    schedule 08.02.2015
comment
Спасибо, оказалось, что файловая система, которую я использую, имеет тип ecryptfs, который применяет nosuid и nodev, чтобы избежать атак с повышением привилегий. Я не думаю, что смогу его выключить. Как-нибудь обойти это?   -  person Tarun Verma    schedule 08.02.2015
comment
Добавлена ​​ссылка, которая должна помочь вам приручить eCryptFS.   -  person Roman Nikitchenko    schedule 08.02.2015


Ответы (3)


Нет проблем с вашим кодом, просто проверьте правильность последовательности setuid / 'sgid':

sudo chmod 6775 setuid
sudo chown root:root setuid

Вы должны установить как минимум SUID, SGID и разрешения на выполнение (маска 6555). Также в этом случае обычно устанавливается запись пользователя/группы (маска 6775). Конечно, в целях безопасности вы можете ограничить это маской записи пользователя (6755).

И, пожалуйста, убедитесь, что вы не сбрасываете разрешения во время повторной компиляции:

$ ls -al
-rwsrwsr-x 1 root  root  8772 Feb  8 17:52 setuid

На всякий случай, если вам (или будущим читателям) понадобится такое руководство: Что такое SUID и как установить SUID в Linux/Unix?

Что касается проблем с eCryptfs: вот статья, которая должна вам помочь: https://wiki.archlinux.org/index.php/ECryptfs

person Roman Nikitchenko    schedule 08.02.2015
comment
Я ценю ваш ответ, но он все еще не работает. ls -al дает желаемый результат, но ./setuid по-прежнему не дает мне root-прав :-/ - person Tarun Verma; 08.02.2015
comment
Пожалуйста, проверьте UID и SGID. Вы не в группе 0. - person Roman Nikitchenko; 08.02.2015

Липкий бит имеет совершенно другую функцию. Для файла в наши дни он в значительной степени не определен, а для каталога он не позволяет не-владельцам (кроме root) удалять файлы в каталоге независимо от разрешений каталога.

Вы ищете установленный бит UID:

  chown root setuid
  chmod +s setuid

Очевидно, что вы должны быть root, чтобы установить разрешение SUID для файла, принадлежащего root. Однако, поскольку бит setUID существует, я подозреваю, что вы можете приложить усилия, которые не требуются.

person David Hoelzer    schedule 08.02.2015

Изменять

chown root.root setuid

to

chown root setuid

or

chown root.tarun setuid
person alk    schedule 08.02.2015
comment
Примечание. Некоторые файловые системы требуют, чтобы при монтировании была установлена ​​разрешенная опция setuid. Чтобы разрешить setuid-операции. Проверьте точку монтирования. - person jim mcnamara; 08.02.2015