Отключить функции system() и exec() в C и Pascal

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

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

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

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

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


person hexchain    schedule 02.11.2011    source источник
comment
Что вы имеете в виду под отключением? Просто не использовать их?   -  person Kiril Kirov    schedule 02.11.2011
comment
Почему? Для песочниц этого было бы ошеломляюще недостаточно. Чтобы проверить, использует ли их какой-то код, просто посмотрите на него (или проверьте вывод компилятора, если он запутан).   -  person    schedule 02.11.2011
comment
@hexchain: почему ты спрашиваешь? таким образом люди могут помочь вам лучше   -  person AndersK    schedule 02.11.2011
comment
Какую операционную систему ты используешь? Если Linux (или другие системы, где вы можете использовать LD_PRELOAD), вы можете использовать LD_PRELOAD для загрузки библиотеки, содержащей фиктивные заглушки для этих функций.   -  person Some programmer dude    schedule 02.11.2011
comment
Это система, в которой пользователи отправляют свои программы, а сервер компилирует и запускает их с различными входными данными, а затем сравнивает вывод программы с предварительно рассчитанным стандартным выводом, чтобы убедиться, что программа верна. Теперь некоторые пользователи отправляют код типа system("shutdown -s -t 0"); для выключения сервера.   -  person hexchain    schedule 02.11.2011
comment
@hexchain, для этого и нужна песочница: en.wikipedia.org/wiki/Sandbox_%28computer_security %29   -  person avakar    schedule 02.11.2011
comment
@hexchain: Так что найдите и забаньте/провалите/уволите этих людей. :)   -  person GManNickG    schedule 02.11.2011
comment
@hexchain: Тогда применяется мой первый пункт. Если вам нужна песочница, вам нужно гораздо больше, чем это, и несколько инструментов и подходов, которые могут быть использованы для песочницы, будут исключать такие вызовы функций в качестве удобного побочного эффекта (мы просто не могли ничего предложить, потому что вы не сказали нам, что вы хотите). действительно хотите). Пожалуйста, прекратите принимать код прямо сейчас и сначала устраните проблемы с безопасностью (на самом деле, не просто избавьтесь от текущих симптомов!).   -  person    schedule 02.11.2011
comment
Pascal не имеет стандартной системы функций или exec, и большинство компиляторов Pascal не реализуют вызовы unix в Windows. Какой компилятор вы используете?   -  person Marco van de Voort    schedule 02.11.2011


Ответы (6)


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

#define system DontEvenThinkAboutUsingThisFunction
#define exec   OrThisOneYouClown

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

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

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

#define InoccuousFunction system

чтобы обойти вашу защиту.

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

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

person paxdiablo    schedule 02.11.2011
comment
Спасибо за ваш ответ. Сервер работает под управлением системы Windows, поэтому у меня нет среды chroot. Кроме того, серверное приложение имеет закрытый исходный код, поэтому я ничего не могу сделать, чтобы контролировать выполнение программы, отправленной пользователем. - person hexchain; 02.11.2011
comment
@hexchain: если вы не можете контролировать, как они отправляются, то вы довольно хорошо толкаете фекалии в гору :-) Возможно, вы могли бы изучить возможность запуска этих вещей на виртуальных машинах, которые можно сохранять и восстанавливать между каждой операцией. Если не считать обретения той силы, которой, как вы говорите, вам не хватает, я не знаю, как еще вы можете защитить себя. - person paxdiablo; 02.11.2011

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

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

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

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

person axw    schedule 02.11.2011
comment
Запуск скомпилированного приложения с уменьшенными свойствами — лучшее решение. Даже если system() нельзя вызвать из приложения, приложение все равно сможет вызывать системные вызовы ОС с помощью сгенерированных или жестко запрограммированных инструкций по сборке. - person Alexey Frunze; 02.11.2011

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

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

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

person Simon Richter    schedule 02.11.2011

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

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

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

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

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

person shubham jha    schedule 11.09.2018

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

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

person Basile Starynkevitch    schedule 02.11.2011

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

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

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

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

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

person doron    schedule 02.11.2011