Zastanawiałem się, czy istnieje sposób na uruchomienie niezaufanego programu w C w piaskownicy w systemie Linux. Coś, co uniemożliwiłoby programowi otwieranie plików lub połączeń sieciowych, forking, exec itp.?
Byłby to mały program, zadanie domowe, które jest przesyłane na serwer i wykonywane na nim testy jednostkowe. Program byłby więc krótkotrwały.
Odpowiedzi:
Użyłem Systrace do piaskownicy niezaufanych programów zarówno w trybie interaktywnym, jak iw trybie automatycznym. Ma
ptrace()
backend oparty na systemie , który pozwala na użycie go w systemie Linux bez specjalnych uprawnień, a także znacznie szybszy i bardziej wydajny backend, który wymaga łatania jądra.Możliwe jest również utworzenie piaskownicy w systemach uniksopodobnych przy użyciu
chroot(1)
, chociaż nie jest to tak łatwe ani bezpieczne. Kontenery Linuksa i więzienia FreeBSD są lepszą alternatywą dla chroot. Inną alternatywą w Linuksie jest użycie struktury bezpieczeństwa, takiej jak SELinux lub AppArmor , którą proponuję dla systemów produkcyjnych.Bylibyśmy w stanie pomóc Ci bardziej, gdybyś powiedział, co dokładnie chcesz zrobić.
EDYTOWAĆ:
Systrace będzie działał w twoim przypadku, ale myślę, że coś opartego na modelu bezpieczeństwa Linuksa, jak AppArmor lub SELinux, jest bardziej standardową, a zatem preferowaną alternatywą, w zależności od twojej dystrybucji.
EDYCJA 2:
Chociaż
chroot(1)
jest dostępny w większości (wszystkich?) Systemach typu Unix, ma sporo problemów:Można go wyrwać. Jeśli zamierzasz faktycznie kompilować lub uruchamiać niezaufane programy w języku C w swoim systemie, jesteś szczególnie narażony na ten problem. A jeśli twoi uczniowie są podobni do moich, ktoś BĘDZIE próbował wydostać się z więzienia.
Musisz stworzyć pełną niezależną hierarchię systemu plików zawierającą wszystko, co jest niezbędne do wykonania zadania. Nie musisz mieć kompilatora w chroocie, ale wszystko, co jest wymagane do uruchomienia skompilowanych programów, powinno być dołączone. Chociaż istnieją narzędzia, które w tym pomagają, nadal nie jest to trywialne.
Musisz zachować chroot. Ponieważ jest niezależny, pliki chroot nie będą aktualizowane wraz z dystrybucją. Będziesz musiał albo regularnie odtwarzać chroot, albo dołączać do niego niezbędne narzędzia aktualizacyjne, co zasadniczo wymagałoby, aby była to pełnowartościowa dystrybucja Linuksa. Będziesz także musiał zsynchronizować dane systemowe i dane użytkownika (hasła, pliki wejściowe itp.) Z systemem hosta.
chroot()
chroni tylko system plików. Nie zapobiega to otwieraniu gniazd sieciowych złośliwemu programowi ani pobieraniu wszystkich dostępnych zasobów przez źle napisany.Problem wykorzystania zasobów jest powszechny wśród wszystkich alternatyw. Przydziały systemu plików zapobiegną zapełnieniu dysku przez programy. Prawidłowe
ulimit
(setrlimit()
w C) ustawienia mogą chronić przed nadużyciem pamięci i wszelkimi bombami widelcowymi, a także położyć kres obciążeniom procesora.nice(1)
może obniżyć priorytet tych programów, tak aby komputer bez problemu mógł być używany do dowolnych zadań uznanych za ważniejsze.źródło
Niedawno napisałem przegląd technik piaskownicy w Linuksie . Myślę, że najłatwiejszym podejściem byłoby użycie kontenerów Linuksa (lxc), jeśli nie masz nic przeciwko rozwidlaniu i tak dalej, co nie ma znaczenia w tym środowisku. Możesz nadać procesowi główny system plików tylko do odczytu, izolowane połączenie sieciowe pętli zwrotnej i nadal możesz go łatwo zabić i ustawić limity pamięci itp.
Seccomp będzie nieco trudny, ponieważ kod nie może nawet przydzielić pamięci.
Selinux to inna opcja, ale myślę, że może to wymagać więcej pracy niż kontener.
źródło
Możesz użyć Qemu do szybkiego testowania zadań. Poniższa procedura zajmuje mniej niż 5 sekund na moim 5-letnim laptopie.
Załóżmy, że uczeń musi opracować program, który pobiera niepodpisane liczby int, każdy w osobnym wierszu, aż nadejdzie wiersz z wartością „-1”. Program powinien następnie uśrednić wszystkie wartości int i wypisać „Średnia:% f”. Oto, jak możesz przetestować program całkowicie izolowany:
Najpierw pobierz
root.bin
z Jslinux, użyjemy tego jako przestrzeni użytkownika (ma kompilator C tcc):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
Chcemy wprowadzić zgłoszenie ucznia
root.bin
, więc skonfiguruj urządzenie pętli:sudo losetup /dev/loop0 root.bin
(do tego też możesz użyć fuseext2, ale nie jest to zbyt stabilne. Jeśli się ustabilizuje, nie będziesz potrzebować do tego rootowania)
Utwórz pusty katalog:
mkdir mountpoint
Mocowanie
root.bin
:sudo mount /dev/loop0 mountpoint
Wprowadź zamontowany system plików:
cd mountpoint
.Napraw prawa:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:chmod +x etc/init.d/rcS
Skopiuj przesłanie do maszyny wirtualnej:
cp ~/student_assignment.c root/assignment.c
Wyjdź z głównego FS maszyny wirtualnej:
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
Otwórz oddzielny terminal i zacznij nasłuchiwać wyjścia gościa:
dd if=/tmp/guest_output bs=1
W innym terminalu:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(Właśnie użyłem tutaj jądra Ubuntu, ale wiele jąder będzie działać)Kiedy wyjście gościa pokazuje "GOTOWE", możesz wysłać klucze do maszyny wirtualnej z zachęty qemu. Na przykład, aby przetestować to przypisanie, możesz to zrobić
Teraz
Average = 12.000000
powinien pojawić się na potoku wyjściowym gościa. Jeśli tak się nie stanie, uczeń poniósł porażkę.quit
Program, który przeszedł test, jest tutaj: https://stackoverflow.com/a/14424295/309483 . Po prostu użyj
tcclib.h
zamiaststdio.h
.źródło
Wypróbuj system Linux w trybie użytkownika . Ma około 1% narzut wydajności w przypadku zadań intensywnie wykorzystujących procesor, ale może być 6 razy wolniejszy w przypadku zadań intensywnie korzystających z operacji we / wy.
źródło
Firejail to jedno z najbardziej wszechstronnych narzędzi do tego - obsługuje seccomp, kontenery systemu plików, możliwości i nie tylko:
https://firejail.wordpress.com/features-3/
źródło
Uruchomienie go na maszynie wirtualnej powinno zapewnić wszystkie wymagane zabezpieczenia i ograniczenia.
QEMU dobrze by się do tego nadawało, a cała praca (pobieranie aplikacji, aktualizacja obrazu dysku, uruchamianie QEMU, uruchamianie aplikacji w nim i zapisywanie danych wyjściowych do późniejszego pobrania) mogłaby zostać utworzona za pomocą skryptów do automatycznych testów.
źródło
Kiedy chodzi o sanboxing oparty na ptrace (strace) check-out:
" sydbox " sandbox i biblioteka programistyczna " pinktrace " (to C99, ale z tego co wiem, istnieją powiązania z Pythonem i Ruby).
Zebrane linki związane z tematem:
http://www.diigo.com/user/wierzowiecki/sydbox
(przepraszam, że nie są to bezpośrednie linki, ale nie ma jeszcze wystarczającej liczby punktów reputacji)
źródło
seccomp i seccomp-bpf osiągają to przy najmniejszym wysiłku: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
źródło
Ta biblioteka powinna dobrze służyć Twojemu celowi
http://sandbox.sourceforge.net
Powodzenia!
źródło
To również wydaje się obiecujące. Piaskownica systemu plików dla Linuksa używająca przechwytywania syscall.
https://github.com/adtac/fssb
źródło
ok dzięki wszystkim odpowiedziom, które bardzo mi pomogły. Ale nie zasugerowałbym żadnego z nich jako rozwiązania dla osoby, która zadała pierwotne pytanie. Wszystkie wymienione narzędzia wymagają wiele pracy, aby przetestować kod uczniów jako nauczyciel, korepetytor, prof. Najlepszym sposobem w tym przypadku byłoby moim zdaniem virtualbox. Ok, emuluje kompletny system x68 i nie ma nic wspólnego ze znaczeniem piaskownicy w ten sposób, ale jeśli wyobrażam sobie mojego nauczyciela programowania, byłoby to dla niego najlepsze. Tak więc „apt-get install virtualbox” w systemach opartych na Debianie, wszyscy inni udają się na http://virtualbox.org/ , utwórz maszynę wirtualną , dodaj iso, kliknij zainstaluj, poczekaj chwilę i miej szczęście. Będzie o wiele łatwiejsze w użyciu, jeśli chodzi o konfigurowanie systemu Linux w trybie użytkownika lub robienie ciężkich rzeczy ...
A jeśli obawiasz się, że twoi uczniowie cię zhakują, myślę, że masz problem z autorytetem i rozwiązanie tego groziłoby im, że pozwiesz ich żywe światło dzienne, jeśli możesz udowodnić tylko jeden kęs męskiego oprogramowania w pracy, którą wykonują ty...
Również jeśli jest klasa i 1% z niej jest tak dobre, jak on mógłby robić takie rzeczy, nie zanudzaj ich tak prostymi zadaniami i daj im jakieś duże, w których muszą kodować więcej. Uczenie się integracyjne jest najlepsze dla wszystkich, więc nie polegaj na starych, zakleszczonych strukturach ...
I oczywiście nigdy nie używaj tego samego komputera do ważnych rzeczy (takich jak pisanie zaświadczeń i egzaminów), których używasz do takich rzeczy, jak przeglądanie sieci i testowanie oprogramowania.
Używaj komputera offline do ważnych rzeczy i komputera online do wszystkich innych rzeczy.
Jednak dla każdego, kto nie jest paranoicznym nauczycielem (nie chcę nikogo urazić, jestem po prostu zdania, że powinieneś nauczyć się podstaw o bezpieczeństwie i naszym społeczeństwie, zanim zaczniesz być nauczycielem programistów ...)
... gdzie byłem ... dla wszystkich innych:
szczęśliwego hakowania !!
źródło