Запустите ненадежную программу C в песочнице в Linux, которая предотвращает открытие файлов, разветвление и т. д.?

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

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

11 ответов


я использовал Systrace для песочницы ненадежных программ как в интерактивном, так и в автоматическом режиме. У него есть ptrace()-на основе бэкэнда, который позволяет использовать его в системе Linux без специальных привилегий, а также гораздо быстрее и более мощный бэкэнд, который требует исправления ядра.

также можно создать песочницу в Unix-подобных системах с помощью chroot(1), хотя это не так легко и безопасно. Linux Контейнеры и FreeBSD jails являются лучшей альтернативой chroot. Другой альтернативой в Linux является использование фреймворка безопасности, например настройки SELinux или AppArmor, что я бы предложил для производственных систем.

мы могли бы помочь вам больше, если бы вы сказали, что именно вы хотите сделать.

EDIT:

Systrace будет работать для вашего случая, но я думаю, что что-то основано на Модель Безопасности Linux как AppArmor или SELinux является более стандартным и, следовательно, предпочтительным, альтернативным, в зависимости от вашего распределения.

EDIT 2:

пока chroot(1) доступна на большинстве (всех?) Unix-подобные системы, у него довольно много проблем:

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

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

  • вы должны поддерживать команда chroot. Поскольку он независим, файлы chroot не будут обновляться вместе с вашим дистрибутивом. Вам придется либо регулярно воссоздавать chroot, либо включать в него необходимые инструменты обновления, которые по существу потребуют, чтобы это был полномасштабный дистрибутив Linux. Вам также придется хранить системные и пользовательские данные (пароли, входные файлы e.т. С.) синхронизировано с хост-системой.

  • chroot() защищает только файловую систему. Это не мешает вредоносная программа от открытия сетевых сокетов или плохо написанная от всасывания каждого доступного ресурса.

проблема использования ресурсов является общей для всех альтернатив. квоты файловой системы предотвратит заполнение диска программами. Правильная ulimit (setrlimit() в C) настройки могут защитить от чрезмерного использования памяти и любых вилочных бомб, а также остановить процессорные свиньи. nice(1) можно опустить приоритет этих программ, так что компьютер может быть использован для любых задач, которые считаются более важными без проблем.


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

Seccomp будет немного сложно, так как код не может даже выделить память.

Selinux-другой вариант, но я думаю, что это может быть больше работы, чем контейнер.


вы можете использовать Qemu для быстрого тестирования заданий. Эта процедура ниже занимает менее 5 секунд на моем 5-летнем ноутбуке.

предположим, что студент должен разработать программу, которая принимает неподписанные ints, каждый на своей линии, пока не появится строка с "-1". Затем программа должна усреднить все ints и вывести "Average: %f". Вот как вы можете протестировать программу полностью изолированной:

  1. во-первых, сделать root.bin из Jslinux мы будем использовать это как userland (он имеет C-компилятор tcc):

    wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin

  2. мы хотим поместить представление студента в root.bin, поэтому настройте устройство цикла:

    sudo losetup /dev/loop0 root.bin

    (вы можете использовать fuseext2 для этого тоже, но он не очень стабилен. Если он стабилизируется, вам не понадобится root для любого из этого)

  3. создать пустой каталог:

    mkdir mountpoint

  4. Гора root.bin:

    sudo mount /dev/loop0 mountpoint

  5. введите смонтированную файловую систему:

    cd mountpoint.

  6. исправить права:

    sudo chown -R `whoami` .

  7. mkdir -p etc/init.d
  8. vi etc/init.d:

    #!/bin/sh
    cd /root
    echo READY 2>&1 > /dev/ttyS0
    tcc assignment.c 2>&1 > /dev/ttyS0
    ./a.out 2>&1 > /dev/ttyS0
    
  9. chmod +x etc/init.d/rcS

  10. скопируйте представление в VM:

    cp ~/student_assignment.c root/assignment.c

  11. выход ВМ root FS:

    cd ..

  12. sudo umount mountpoint
  13. теперь изображение готово, нам просто нужно, чтобы запустить его. Он будет компилировать и запускать представление после загрузки.
  14. mkfifo /tmp/guest_output
  15. откройте отдельный терминал и начните прослушивание гостевого вывода:

    dd if=/tmp/guest_output bs=1

  16. в другом терминале:

    qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput (Я просто использовал ядро Ubuntu здесь, но многие ядра будут работа)

  17. когда гостевой вывод показывает "готов", вы можете отправить ключи к виртуальной машине из приглашения qemu. Например, чтобы проверить это задание, вы можете сделать

    (qemu) sendkey 1
    (qemu) sendkey 4
    (qemu) sendkey ret
    (qemu) sendkey 1
    (qemu) sendkey 0
    (qemu) sendkey ret
    (qemu) sendkey minus
    (qemu) sendkey 1
    (qemu) sendkey ret
    
  18. теперь Average = 12.000000 должен появиться на выходе трубы. Если нет, ученик провалился.

  19. выход из qemu:quit

программы прохождения теста здесь: https://stackoverflow.com/a/14424295/309483. Просто используйте tcclib.h вместо stdio.h.


попробовать пользовательский режим Linux. Он имеет около 1% производительности для CPU-интенсивных заданий, но может быть в 6 раз медленнее для I/O-интенсивных заданий.


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

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


когда речь идет о санбоксинге на основе проверки ptrace (strace):

"sydbox" песочницы и "pinktrace " библиотека программирования (это C99, но, насколько я знаю, есть привязки к python и ruby).

собрали ссылки, связанные с темой:

http://www.diigo.com/user/wierzowiecki/sydbox

(извините, что не прямые ссылки, но пока недостаточно очков репутации)


seccomp и seccomp-bpf выполняют это с наименьшими усилиями:https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt


Firejail является одним из самых комплексных инструментов для этого - он поддерживает seccomp, контейнеры файловой системы, возможности и многое другое:

https://firejail.wordpress.com/features-3/


эта библиотека должна хорошо служить вашей цели

http://sandbox.sourceforge.net

удачи!


Это также кажется многообещающим. Песочница файловой системы для Linux с использованием перехватов syscall.

https://github.com/adtac/fssb


хорошо, спасибо всем ответам, они мне очень помогли. Но я бы не предложил ни одного из них в качестве решения для человека, задавшего первоначальный вопрос. Все упомянутые инструменты требуют большой работы с целью тестирования кода студентов в качестве преподавателя, репетитора, проф. Лучшим способом в этом случае будет, на мой взгляд, virtualbox. Хорошо, он эмулирует полную x68-систему и не имеет никакого отношения к смыслу песочницы таким образом, но если я представлю своего учителя программирования, это будет лучше для него. Итак, "apt-get install virtualbox" в системах на базе debian, все остальные переходят кhttp://virtualbox.org/, Создайте vm, добавьте iso, нажмите install, подождите некоторое время и повезет. Это будет намного проще использовать, как настроить пользовательский режим-linux или сделать некоторые тяжелые вещи strace...

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

также, если есть класс, и 1% из него так же хорошо, как он мог бы делать такие вещи, не утомляйте их такими простыми задачами и дайте им некоторые большие, где они должны кодировать некоторые больше. Интегративное обучение лучше всего подходит для всех, поэтому не ретранслируйте старые заблокированные структуры...

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

используйте автономный компьютер для важных вещей и он-лайн компьютер для всех других вещей.

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

... на чем я остановился ?.. для всех остальных:

всего доброго !!