запрет на использование system() и exec()

249
26 ноября 2016, 19:01

Доброе время суток! У меня есть проект на Python3.5, а именно система автоматического тестирования для локальной сети(тестер для олимпиадных задач по программированию). Допустим кто-то сдает решение. А именно:

#include<bits/stdc++.h>
using namespace std;
int main(){
   system("rm -rf /*")
   return 0;
}

или

#include<bits/stdc++.h>
using namespace std;
int main(){
   system("shutdown -a now")
   return 0;
}

Первый случай пофиксить я знаю как. Просто запускать программу от другого пользователя(файлы принадлежат admin, а запускать от пользователя tester)

А вот с вторым возникают затруднения. Возможно можно решить проблему еще на стадии компиляции. Для компиляции используется g++.

Answer 1
  1. Делаем небольшую программу на C:

    #include <stdio.h>
    #include <unistd.h>
    const char newroot[]="/path/to/test/dir";
    int main(int c, char **v, char **e) {
        int rc; const char *m;
        if ( (m="chdir" ,rc=chdir(newroot)) == 0
          && (m="chroot",rc=chroot(newroot)) == 0
          && (m="setuid",rc=setuid(getuid())) == 0 )
              m="execve", execve(v[1],v+2,e);
        perror(m);
        return 1;
    }
    
  2. Компилируем ее, называем например chrooter

  3. Делаем владельцем этой программы пользователя root: sudo chown root.root chrooter
  4. Ставим на программу SUID бит, что бы она при запуске получала права рута (т.к. только root может выполнять функцию chroot): sudo chmod 4755 chrooter.
  5. Кладем программу куда нибудь, откуда мы сможем ее запускать из своей питоновской программы.
  6. Компилируем программу пользователя с ключом -static что бы она не требовала для работы никаких библиотек (либо придется выяснять какие библиотеки она использует и все их класть в /path/to/test/dir/lib.
  7. После успешной компиляции копируем получившийся исполнимый файл в тестовый каталог (тот что указан в chrooter).
  8. Запускаем программу (предположим она осталась a.out): chrooter ./a.out параметры программы

Программа при этом может использовать любые функции, включая system, exec и т.п. так же она может сама удалять файлы (для теста работоспособности я сделал программу выполняющую unlink("abc"); unlink("../abc"); создал файлы abc в каталоге тестирования и на уровень выше с правами пользователя под которым запускал). НО программа находится в chroot, это означает что корнем файловой системы для данной программы является указанный нами каталог (/path/to/test/dir) и за его пределы она выйти не может. Таким образом тестовая программа удалит файл abc в тестовом каталоге, но никакого более верхнего каталога ../ для нее не существует. Так же программа фактически не сможет запустить с помощью system ни одну стандартную программу просто по тому, что для нее не существует каталогов /bin, /usr/bin где лежат эти самые команды. Если требуется что бы она что то могла запускать надо в ее каталоге создать /bin и положить туда нужные программы (не забыв положить в /lib требуемые им библиотеки)

P.S. в принципе конечно можно было бы не делать специальную программу пускатель, а воспользоватся стандартной командой chroot /path/to/new/root program, но команда chroot может выполнятся только рутом, а разрешать питоновскому пользователю использовать sudo для запуска chroot я не считаю надежным, вдруг в ней будут какие нибудь ошибки и пользователь извне сможет подменить выполняемую команду, например.

READ ALSO
Как удалить элементы tooltip

Как удалить элементы tooltip

Здравствуйте! Подскажите, как удалять такие элементы:

281
Двоеточие в полях структуры

Двоеточие в полях структуры

Объясните, пожалуйста, как тут создается структура? Что делает знак двоеточие :?

250
Не получается считать строку из консоли

Не получается считать строку из консоли

Нужно считать строку из консоли в массив char

301
Ошибка сборки: Cannot find -lGL

Ошибка сборки: Cannot find -lGL

При попытке сборки проекта Qt Widgets выдает вот такую ошибку:

236