Ich habe mich gefragt, ob es eine Möglichkeit gibt, ein nicht vertrauenswürdiges C-Programm unter einer Sandbox unter Linux auszuführen. Etwas, das das Programm daran hindern würde, Dateien oder Netzwerkverbindungen zu öffnen oder Forking, Exec usw.?
Es wäre ein kleines Programm, eine Hausaufgabe, die auf einen Server hochgeladen wird und auf der Unit-Tests ausgeführt werden. Das Programm wäre also nur von kurzer Dauer.
Antworten:
Ich habe Systrace verwendet, um nicht vertrauenswürdige Programme sowohl interaktiv als auch im automatischen Modus zu sandboxen . Es verfügt über ein
ptrace()
Backend auf Basis, das die Verwendung auf einem Linux-System ohne besondere Berechtigungen ermöglicht, sowie über ein weitaus schnelleres und leistungsfähigeres Backend, das das Patchen des Kernels erfordert.Es ist auch möglich, eine Sandbox auf Unix-ähnlichen Systemen mit zu erstellen
chroot(1)
, obwohl dies nicht ganz so einfach oder sicher ist. Linux-Container und FreeBSD-Jails sind eine bessere Alternative zu Chroot. Eine andere Alternative unter Linux ist die Verwendung eines Sicherheitsframeworks wie SELinux oder AppArmor , das ich für Produktionssysteme vorschlagen würde.Wir könnten Ihnen mehr helfen, wenn Sie genau sagen würden, was Sie tun möchten.
BEARBEITEN:
Systrace würde für Ihren Fall funktionieren, aber ich denke, dass etwas, das auf dem Linux-Sicherheitsmodell basiert, wie AppArmor oder SELinux, eine standardisiertere und daher bevorzugte Alternative ist, abhängig von Ihrer Distribution.
EDIT 2:
Während
chroot(1)
es auf den meisten (allen?) Unix-ähnlichen Systemen verfügbar ist, gibt es einige Probleme:Es kann ausgebrochen werden. Wenn Sie tatsächlich nicht vertrauenswürdige C-Programme auf Ihrem System kompilieren oder ausführen, sind Sie für dieses Problem besonders anfällig. Und wenn Ihre Schüler so etwas wie meine sind, wird jemand versuchen, aus dem Gefängnis auszubrechen.
Sie müssen eine vollständige unabhängige Dateisystemhierarchie mit allem erstellen, was für Ihre Aufgabe erforderlich ist. Sie müssen keinen Compiler in der Chroot haben, aber alles, was zum Ausführen der kompilierten Programme erforderlich ist, sollte enthalten sein. Es gibt zwar Dienstprogramme, die dabei helfen, aber es ist immer noch nicht trivial.
Sie müssen die Chroot pflegen. Da es unabhängig ist, werden die Chroot-Dateien nicht zusammen mit Ihrer Distribution aktualisiert. Sie müssen entweder die Chroot regelmäßig neu erstellen oder die erforderlichen Update-Tools hinzufügen, was im Wesentlichen erfordern würde, dass es sich um eine vollständige Linux-Distribution handelt. Sie müssen auch die System- und Benutzerdaten (Kennwörter, Eingabedateien usw.) mit dem Hostsystem synchronisieren.
chroot()
schützt nur das Dateisystem. Es verhindert nicht, dass ein Schadprogramm Netzwerk-Sockets öffnet oder ein schlecht geschriebenes Programm jede verfügbare Ressource aufnimmt.Das Problem der Ressourcennutzung ist allen Alternativen gemeinsam. Dateisystemkontingente verhindern, dass Programme die Festplatte füllen. Die richtigen Einstellungen
ulimit
(setrlimit()
in C) können vor Überbeanspruchung des Speichers und Gabelbomben schützen und CPU-Schweinen Einhalt gebieten.nice(1)
kann die Priorität dieser Programme verringern, sodass der Computer problemlos für alle Aufgaben verwendet werden kann, die als wichtiger erachtet werden.quelle
Ich habe einen Überblick über Sandbox-Techniken unter Linux geschrieben kürzlich . Ich denke, Ihr einfachster Ansatz wäre die Verwendung von Linux-Containern (lxc), wenn Sie nichts dagegen haben, zu forken und so weiter, was in dieser Umgebung nicht wirklich wichtig ist. Sie können dem Prozess ein schreibgeschütztes Root-Dateisystem, eine isolierte Loopback-Netzwerkverbindung geben und ihn trotzdem problemlos beenden und Speichergrenzen usw. festlegen.
Seccomp wird etwas schwierig, da der Code nicht einmal Speicher zuordnen kann.
Selinux ist die andere Option, aber ich denke, es könnte mehr Arbeit als ein Container sein.
quelle
Mit Qemu können Sie Aufgaben schnell testen. Dieser Vorgang dauert auf meinem 5 Jahre alten Laptop weniger als 5 Sekunden.
Nehmen wir an, der Schüler muss ein Programm entwickeln, das vorzeichenlose Ints in seiner eigenen Zeile verwendet, bis eine Zeile mit "-1" eintrifft. Das Programm sollte dann alle Ints mitteln und "Average:% f" ausgeben. So können Sie das Programm vollständig isoliert testen:
root.bin
Holen Sie sich zuerst von Jslinux, wir werden das als Userland verwenden (es hat den tcc C-Compiler):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
Wir möchten die Einreichung des Schülers einfügen
root.bin
, also richten Sie das Loop-Gerät ein:sudo losetup /dev/loop0 root.bin
(Sie könnten auch fuseext2 dafür verwenden, aber es ist nicht sehr stabil. Wenn es sich stabilisiert, benötigen Sie für nichts davon root)
Erstellen Sie ein leeres Verzeichnis:
mkdir mountpoint
Montieren
root.bin
:sudo mount /dev/loop0 mountpoint
Geben Sie das gemountete Dateisystem ein:
cd mountpoint
.Rechte reparieren:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
::chmod +x etc/init.d/rcS
Kopieren Sie die Übermittlung auf die VM:
cp ~/student_assignment.c root/assignment.c
Beenden Sie den Root-FS der VM:
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
Öffnen Sie ein separates Terminal und warten Sie auf die Gastausgabe:
dd if=/tmp/guest_output bs=1
In einem anderen Terminal:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(Ich habe gerade den Ubuntu-Kernel hier verwendet, aber viele Kernel werden funktionieren)Wenn die Gastausgabe "BEREIT" anzeigt, können Sie über die qemu-Eingabeaufforderung Schlüssel an die VM senden. Um diese Zuordnung beispielsweise zu testen, können Sie dies tun
Jetzt
Average = 12.000000
sollte in der Gastausgabepipe angezeigt werden. Wenn nicht, ist der Schüler gescheitert.quit
Ein Programm, das den Test besteht, finden Sie hier: https://stackoverflow.com/a/14424295/309483 . Verwenden Sie einfach
tcclib.h
anstelle vonstdio.h
.quelle
Versuchen Sie Linux im Benutzermodus . Bei CPU-intensiven Jobs beträgt der Leistungsaufwand etwa 1%, bei E / A-intensiven Jobs kann er jedoch sechsmal langsamer sein.
quelle
Firejail ist eines der umfassendsten Tools dafür - es unterstützt seccomp, Dateisystemcontainer, Funktionen und mehr:
https://firejail.wordpress.com/features-3/
quelle
Das Ausführen in einer virtuellen Maschine sollte Ihnen alle gewünschten Sicherheits- und Einschränkungen bieten.
QEMU passt gut dazu, und die gesamte Arbeit (Herunterladen der Anwendung, Aktualisieren des Festplattenabbilds, Starten von QEMU, Ausführen der darin enthaltenen Anwendung und Speichern der Ausgabe zum späteren Abrufen) könnte für automatisierte Testläufe per Skript ausgeführt werden.
quelle
Wenn es um Sanboxing geht, basierend auf dem Check-out von ptrace (strace):
Sandbox " sydbox " und " pinktrace " “ Programmier - Bibliothek (es ist C99 , aber es gibt Bindungen zu Python und Ruby, soweit ich weiß).
Gesammelte Links zum Thema:
http://www.diigo.com/user/wierzowiecki/sydbox
(Entschuldigung, dass keine direkten Links, aber noch nicht genügend Reputationspunkte vorhanden sind)
quelle
seccomp und seccomp-bpf erreichen dies mit geringstem Aufwand: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
quelle
Diese Bibliothek sollte Ihrem Ziel gut dienen
http://sandbox.sourceforge.net
Viel Glück!
quelle
Dies scheint auch vielversprechend. Eine Dateisystem-Sandbox für Linux, die Syscall-Intercepts verwendet.
https://github.com/adtac/fssb
quelle
ok dank all den Antworten, die sie mir sehr geholfen haben. Aber ich würde keinen von ihnen als Lösung für die Person vorschlagen, die die ursprüngliche Frage gestellt hat. Alle genannten Tools erfordern zu viel Arbeit, um den Code der Schüler als Lehrer, Tutor, Professor zu testen. Der beste Weg in diesem Fall wäre meiner Meinung nach virtualbox. Ok, es emuliert ein komplettes x68-System und hat auf diese Weise nichts mit der Bedeutung von Sandboxing zu tun, aber wenn ich mir meinen Programmierlehrer vorstelle, wäre es das Beste für ihn. "Apt-get install virtualbox" auf Debian-basierten Systemen, alle anderen gehen zu http://virtualbox.org/ , erstellen eine VM, fügen eine ISO hinzu, klicken auf "Installieren", warten Sie einige Zeit und haben Sie Glück. Es wird viel einfacher zu bedienen sein, um User-Mode-Linux einzurichten oder ein paar schwere Sachen zu machen ...
Und wenn Sie Angst haben, dass Ihre Schüler Sie hacken, haben Sie vermutlich ein Autoritätsproblem, und eine Lösung dafür würde ihnen drohen, dass Sie das lebendige Tageslicht aus ihnen herausklagen, wenn Sie nur einen Bissen Maleware in der Arbeit beweisen können, die sie geben Sie...
Auch wenn es eine Klasse gibt und 1% davon so gut ist, wie er solche Dinge tun könnte, langweile sie nicht mit so einfachen Aufgaben und gib ihnen einige große, wo sie noch mehr programmieren müssen. Integratives Lernen ist das Beste für alle, also verlassen Sie sich nicht auf alte festgefahrene Strukturen ...
Verwenden Sie natürlich niemals denselben Computer für wichtige Dinge (wie das Schreiben von Bescheinigungen und Prüfungen), die Sie zum Surfen im Internet und zum Testen von Software verwenden.
Verwenden Sie einen Offline-Computer für wichtige Dinge und einen Online-Computer für alle anderen Dinge.
Jedem anderen, der kein paranoider Lehrer ist (ich möchte niemanden beleidigen, ich bin nur der Meinung, dass Sie die Grundlagen über Sicherheit und unsere Gesellschaft lernen sollten, bevor Sie anfangen, Programmiererlehrer zu werden ...)
... wo war ich ... für alle anderen:
Viel Spaß beim Hacken !!
quelle