Отключить функцию system () и exec () в C и Pascal - PullRequest
3 голосов
/ 02 ноября 2011

Есть ли способ отключить функции system() и exec() в C / C ++ и Pascal, используя любой аргумент компилятора или изменяя заголовок / файл модуля?(Это Windows)

Я пытался использовать -Dsystem=NONEXIST для gcc и g ++, но #include <cstdio> вызывает ошибку компиляции.

РЕДАКТИРОВАТЬ: Конечно, я знаю, что они могут использовать #undef system дляобойти защиту, поэтому я попытался закомментировать строку функции system в stdlib.h, но это тоже не сработало.

EDIT2 (комментарий): это система, в которую пользователи отправляютих программы и сервер компилируют и запускают его с различными входными данными, затем сравнивают выходные данные программы с предварительно рассчитанными стандартными выходными данными, чтобы проверить, верна ли программа.Теперь некоторые пользователи отправляют код, такой как system("shutdown -s -t 0");, для выключения сервера.

Сервер работает под управлением Windows, поэтому у меня нет среды chroot.Также серверное приложение с закрытым исходным кодом, поэтому я ничего не могу сделать, чтобы контролировать выполнение программы, представленной пользователем.Что я могу сделать, это изменить аргумент командной строки компилятора и изменить заголовочные файлы.

Ответы [ 6 ]

4 голосов
/ 02 ноября 2011

Ну, вы можете попробовать:

#define system DontEvenThinkAboutUsingThisFunction
#define exec   OrThisOneYouClown

в заголовочном файле, но я вполне уверен, что любая обезьяна кода, достойная их соли, могла бы обойти такую ​​"защиту".

Мне было бы интересно понять , почему вы думали, что это необходимо (может быть лучшее решение, если мы лучше поняли проблему).

Единственное, что приходит на ум, это то, что вы хотите предоставить некоторый онлайн-компилятор / бегун, родственный проекту Euler. Если это , то вы можете найти код для строки system<whitespace>( в качестве опции, но даже тогда определенная сторона может просто:

#define InoccuousFunction system

чтобы обойти вашу оборону.

Если это является случаем, вы можете подумать об использовании чего-то вроде chroot, чтобы никто не мог даже получить доступ к любому опасные двоичные файлы, такие как shutdown (и этот конкретный зверь на самом деле не должен запускаться обычным пользователем в любом случае) - другими словами, ограничьте их среду так, чтобы только вещей, которые они могут даже видеть, были gcc и его род.

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

2 голосов
/ 02 ноября 2011

Одна из возможностей - создать собственную версию таких функций и связать их с каждой программой, которую вы компилируете / связываете на сервере. Если символ найден в ваших объектах, он будет иметь приоритет.

Просто убедитесь, что вы все их получите;)

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

РЕДАКТИРОВАТЬ : конечно, по моей логике, пользователь мог бы также предоставить свою собственную версию функции, которая выполняет динамическую загрузку библиотеки и поиск символов, чтобы найти оригинальную функцию. Тебе действительно нужно просто поставить ее в песочницу.

1 голос
/ 02 ноября 2011

Для сред Unixoid существует Geordi , который использует большую помощь из операционной системы для песочницы кода, который должен быть выполнен.

В основном вы хотите запускать код в очень ограниченной среде; Linux предоставляет специальный флаг процесса для того, что отключает любые системные вызовы, которые открывают доступ к ресурсам, которых у процесса не было в тот момент, когда был установлен флаг (то есть он запрещает открывать новые файлы, но любые файлы, которые уже открыты, могут быть доступ нормальный).

Я думаю, что в Windows должен быть похожий механизм.

0 голосов
/ 11 сентября 2018

Вы можете использовать что-то вроде этого

#include<stdlib.h>
#include<unistd.h>
#define system  <stdlib.h>
#define exec   <unistd.h>

В этом случае, даже если пользователь хочет поменять значения макросов, которые он не может. Если они пытаются поменять значения макросов следующим образом

#define <stdlib.h> system
#define <unistd.h> exec

они не могут, потому что C не разрешит этот тип имени в макросах. Даже если каким-то образом они меняют эти значения, мы включили эти заголовочные файлы, которые приведут к ошибке времени компиляции.

0 голосов
/ 02 ноября 2011

Вы никогда не можете (как вы узнали) полагаться на пользовательский ввод, чтобы быть в безопасности.system и execXX вряд ли будут вашими единственными проблемами.

Это означает, что у вас есть следующие опции:

  1. Запустите программу в каком-то виде chroot ed jail (не уверен, как это сделать в windows)
  2. Сканируйте код перед компиляцией, чтобы убедиться в отсутствии «недопустимых» функций.
  3. Сканируйте исполняемый двоичный файл после компиляции, чтобы убедиться, что он не использует «запрещенную» библиотечную функцию.
  4. Запретитькомпоновщик от ссылок на любые внешние библиотеки, включая стандартную библиотеку C (libc) в unix.Затем вы создаете свой собственный "libc", который явно разрешает определенные функции.

Номер 3 в Unix может использовать такие утилиты, как readelf или objdump, которые могут проверять наличие связанных символов.Вероятно, это также можно сделать с помощью библиотеки дескрипторов двоичных файлов.

В Number 4 потребуется поиграться с флагами компилятора, но, вероятно, это самый безопасный из перечисленных выше вариантов.

0 голосов
/ 02 ноября 2011

Не совсем (из-за таких хитростей, как вызов некоторой библиотечной функции, которая сама вызывает system, или из-за того, что функциональность порождающих процессов может быть выполнена с помощью только системных вызовов fork & execve, которые остаются доступными ...).

Но почему вы спрашиваете это ?

...