Второй набор не разрешен

0

Если я вызову setuid в цикле, чтобы стать root и сбросить uid, это работает только один раз. У меня есть следующий код:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int my_func(int i) {
    int current_uid = getuid();
    int ret;
    fprintf(stderr,
                    "###  i=%d   ###:  My UID is: %d. My GID is: %d,   before 'system(id)'\n",
                    i, current_uid, getgid());
    system("/usr/bin/id");

    fprintf(stderr,"\n\n###  i=%d   ###:  before 'setuid(0)'\n", i);
    if (setuid(0)) {
        perror("setuid");
        return 1;
    }
    fprintf(stderr,"after 'setuid(0)'\n\n");

    //I am now root!
    fprintf(stderr,
                    "###  i=%d   ###:  I an now root:  My UID is: %d. My GID is: %d,   before 'system(id)'\n",
                    i, getuid(), getgid());
    system("/usr/bin/id");


    //Time to drop back to regular user priviledges
    fprintf(stderr,"\n\nbefore 'setuid(%d)'\n",current_uid);
    ret=setuid(current_uid);
    fprintf(stderr,
                    "###  i=%d   ###:  My UID is: %d. My GID is: %d,   before 'system(id)\n",
                    i, getuid(), getgid());
    system("/usr/bin/id");
}

int main(void) {
    int i;
    for (i=0;i<3;i++) {
        my_func(i);
        sleep(5);
        fprintf(stderr,"\n\n");
    }
    return 0;
}

Я установил бит SUID и запустил эту программу, когда обычный пользователь поднялся. Выход:

rose @condor: /home/rose/Txt/src/Test/C/Setuid (5) $ ll/usr/local/bin/multiple_setuid_test -rws - x - x 1 корень root 13589 11. Dez 08:41/USR/локальные/бен /multiple_setuid_test *

rose @condor: /home/rose/Txt/src/Test/C/Setuid (6) $/usr/local/bin/multiple_setuid_test

я = 0 ###: Мой UID: 1203. Мой GID: 100, до 'system (id)'

uid = 1203 (rose) gid = 100 (пользователей) Gruppen = 100 (пользователей), 4 (adm), 6 (диск), 7 (lp), 10 (колесо), 14 (uucp), 18 (аудио), 19 (CDROM), 27 (видео), 35 (игр), 60 (MySQL), 250 (Portage), 1001 (haldaemon), 1002 (plugdev), 1008 (сканер), 1027 (vboxusers), +1028 (КМК), 1029 (QEMU), 1036 (GSM), +1039 (пульс -a ступа), 1040 (пульс), тысяча сорок один (tuntap)

я = 0 ###: before 'setuid (0)'

после 'setuid (0)'

я = 0 ###: Я теперь root: мой UID: 0. Мой GID: 100, до 'system (id)'

uid = 0 (root) gid = 100 (пользователи) Gruppen = 0 (root), 4 (adm), 6 (диск), 7 (lp), 10 (колесо), 14 (uucp), 18 (аудио), 19 (CDROM), 27 (видео), 35 (игр), 60 (MySQL), 100 (пользователи), 250 (Portage), 1001 (haldaemon), 1002 (plugdev), 1008 (сканер), 1027 (vboxusers), 1028 (КМК), 1029 (QEMU), 1036 (GSM), 1039 (пульс -a ступа), 1040 (пульс), тысячу сорок одна (tuntap)

до 'setuid (1203)'

я = 0 ###: Мой UID: 1203. Мой GID: 100, до 'system (id)

uid = 1203 (rose) gid = 100 (пользователей) Gruppen = 100 (пользователей), 4 (adm), 6 (диск), 7 (lp), 10 (колесо), 14 (uucp), 18 (аудио), 19 (CDROM), 27 (видео), 35 (игр), 60 (MySQL), 250 (Portage), 1001 (haldaemon), 1002 (plugdev), 1008 (сканер), 1027 (vboxusers), +1028 (КМК), 1029 (QEMU), 1036 (GSM), +1039 (пульс -a ступа), 1040 (пульс), тысяча сорок один (tuntap)

я = 1 ###: Мой UID: 1203. Мой GID: 100, до 'system (id)'

uid = 1203 (rose) gid = 100 (пользователей) Gruppen = 100 (пользователей), 4 (adm), 6 (диск), 7 (lp), 10 (колесо), 14 (uucp), 18 (аудио), 19 (CDROM), 27 (видео), 35 (игр), 60 (MySQL), 250 (Portage), 1001 (haldaemon), 1002 (plugdev), 1008 (сканер), 1027 (vboxusers), +1028 (КМК), 1029 (QEMU), 1036 (GSM), +1039 (пульс -a ступа), 1040 (пульс), тысяча сорок один (tuntap)

я = 1 ###: before 'setuid (0)'

setuid: операция не разрешена

я = 2 ###: Мой UID: 1203. Мой GID: 100, до 'system (id)'

uid = 1203 (rose) gid = 100 (пользователей) Gruppen = 100 (пользователей), 4 (adm), 6 (диск), 7 (lp), 10 (колесо), 14 (uucp), 18 (аудио), 19 (CDROM), 27 (видео), 35 (игр), 60 (MySQL), 250 (Portage), 1001 (haldaemon), 1002 (plugdev), 1008 (сканер), 1027 (vboxusers), +1028 (КМК), 1029 (QEMU), 1036 (GSM), +1039 (пульс -a ступа), 1040 (пульс), тысяча сорок один (tuntap)

я = 2 ###: before 'setuid (0)'

setuid: операция не разрешена

Роза @кондор: /home/rose/Txt/src/Test/C/Setuid (7) $ uname -a Кондор Linux 3.12.4 # 1 SMP Mon Dec 9 11:37:38 CET 2013 x86_64 Intel (R) Core (TM) 2 CPU 6600 @2.40GHz GenuineIntel GNU/Linux

Любые намеки приветствуются.

Теги:

2 ответа

2

Linux (как и другие unixes) хранит два значения: ваш реальный идентификатор пользователя, который задается setuid, соответствует вашему логину и не изменяется s-бит, а ваш эффективный идентификатор пользователя, который задается seteuid, и изменяется, когда вы выполняете программу с установленным s-битом. Чтобы разрешить использование setuid(), ваш реальный или эффективный идентификатор пользователя должен быть равен нулю, но если вы используете setuid() для удаления привилегий (изменение от 0 до чего-либо еще), ваш эффективный идентификатор пользователя также будет изменен, Таким образом, ваш первый setuid (1203) также устанавливает эффективный идентификатор пользователя на 1203, что еще больше предотвратит возврат привилегий.

Чтобы изменить несколько раз и от root до корня, вы должны использовать вызов setreuid() для замены обоих - setreuid (1203, 0) изменит ваш реальный идентификатор пользователя на 1203, а действительный идентификатор пользователя - на 0, что позволит вам установить uid до 0.

Обратите внимание, что если одно из двух uids равно 0, у вас есть привилегии root. С uid = 1203 и euid = 0 создаваемые вами файлы будут принадлежать вам (идентификатор пользователя 1203), но у вас все равно будет доступ root. Поэтому очень внимательно проверяйте свою программу на предмет безопасности.

Если вам нужно иметь корневой доступ каждый раз в течение всей вашей программы, гораздо безопаснее создавать pipe(), fork() для дочернего процесса, который сохраняет права root, откатывает привилегии в родительском процессе и отправляет некоторую команду вниз pipe для ребенка, чтобы выполнить, когда вам нужно что-то сделать как root. Таким образом, вы должны провести аудит безопасности только дочернего процесса, который, по-видимому, намного меньше, чем вся ваша программа.

  • 0
    На самом деле у Linux есть четыре: реальная, эффективная, сохраненная и файловая система. Вы можете использовать setresuid(uid,euid,suid) и setresgid(gid,egid,sgid) для переключения между реальным, эффективным и сохраненным идентификаторами пользователя. Вы можете сохранить root как сохраненную идентификацию, а затем переключаться между любыми реальными и эффективными идентификациями, пока вы сначала переключаетесь на root. Идентификация файловой системы используется редко и в основном следует эффективной идентификации. Для получения дополнительной информации см. Справочные страницы: man7.org/linux/man-pages/man2/setresuid.2.html и man7.org/linux/man-pages/man7/credentials.7.html
0

Как только вы откажетесь от прав root, используя setuid для изменения для пользователя, не являющегося пользователем root, у вас больше нет привилегий, необходимых для повторного использования setuid.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню