setuid(0) и система дает сбой

У меня есть программа, работающая на C. Для этого нужно выполнить команду «iptables», используя system.

Я старался

setuid(0); 
system("iptables .... ");

setuid и система не сосуществуют. со страницы системного руководства

Не используйте system() из программы с привилегиями set-user-ID или set-group-ID, потому что странные значения для некоторых переменных среды могут быть использованы для нарушения целостности системы. Вместо этого используйте семейство функций exec(3), но не execlp(3) или execvp(3). system() на самом деле не будет работать должным образом из программ с привилегиями set-user-ID или set-group-ID в системах, в которых /bin/sh является bash версии 2, поскольку bash 2 сбрасывает привилегии при запуске. (Debian использует модифицированный bash, который не делает этого при вызове как sh.)

как я могу победить свою проблему?

Спасибо


person cateof    schedule 07.06.2011    source источник


Ответы (3)


Что-то вроде этого может помочь. Это не проверено, но должно работать.

    char * const argv[] = {"/sbin/iptables", "-L", NULL};

    pid = fork();
    switch (pid) {
            case -1:
                    /* handle error */
            case 0:
                    execv("/sbin/iptables", argv);
                    /* handle error if you get here */
            break;
            default:
                    waitpid(pid, &status, 0);
                    /* check waitpid return code */
            break;
    }
person cnicutar    schedule 07.06.2011
comment
@downvoter Буду признателен за отзывы, которые помогут мне улучшить этот ответ :-) - person cnicutar; 10.05.2014

system() будет работать в сочетании с setuid(), но в этом проблема: серьезная угроза безопасности. Проблема в том, что system() запускает оболочку (bash, sh и т. д.), используя любую существующую среду, и когда вы намереваетесь запустить «iptables», мой PATH может указывать на мою собственную версию iptables, которую я мог бы легко убедить вас работать за меня, как root. Кажется, вы можете решить эту проблему, используя полный путь к iptables, но другие переменные среды (например, LD_PRELOAD_PATH) можно использовать, чтобы убедить инструменты загружать мошеннические общие библиотеки — опять же, запуская вещи от имени root, которые не были предназначены.

Для того, что вам нужно делать безопасно, вы должны использовать одну из функций семейства exec() и взять под контроль ее операционную среду. Все остальное требует нарушения безопасности. http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.html кажется подходящим местом для получения дополнительной информации.

person mah    schedule 07.06.2011

Почему вам нужно использовать system()? справочная страница точно говорит вам, что делать:

Вместо этого используйте семейство функций exec(3), но не execlp(3) или execvp(3).

Вас, вероятно, заинтересуют fork(2) и wait(2), а также системные вызовы.

person Carl Norum    schedule 07.06.2011