Führen Sie den Benutzercode sicher aus

6

Ich muss C-Code markieren und ein Teil davon beinhaltet das Ausführen und Timen ihrer Einreichungen. Das Problem ist, dass ihr Code dann wie ich ausgeführt wird und sie im Prinzip mit meinen Berechtigungseinstellungen tun können, was sie wollen. Zum Beispiel könnten sie meinen privaten ssh-Schlüssel kopieren.

Ich könnte eine virtuelle Maschine einrichten und ihren Code darin ausführen (obwohl ich nicht ganz sicher bin, wie ich dies am besten verhindern kann). Ein Problem dabei ist, dass die Geschwindigkeitsleistung jetzt nicht realistisch ist. Ich könnte allen Benutzern die gleiche virtuelle Maschine zur Verfügung stellen, um ihren Code vorher zu testen, damit sie zumindest die gleichen Einstellungen zum Testen haben.

Gibt es eine gute Möglichkeit, eine Umgebung einzurichten, in der Sie von anderen geschriebenen Code ausführen, aber den Schaden begrenzen können?

Marshall
quelle
1
Wenn Sie dieses auf einem temporären Konto ausführen, welches Sie nur für diesen Zweck erstellt haben?
peterh
1
@ PeterHorvath Das ist eine gute Idee. Für Tipps zur Sperrung eines solchen temporären Kontos wäre ich sehr dankbar.
Marshall
Wenn es sich um einen einfachen Benutzer handelt, wäre es für ihn praktisch unmöglich, wirklich schädliche Maßnahmen zu ergreifen. Es war schwer für einen Cracker, selbst mit einer interaktiven Shell. Wenn Sie das Konto jedoch nach der Verwendung löschen und alle verbleibenden Vorgänge abbrechen (wenn dies weiterhin der Fall ist, besteht ein wichtiger Grund für eine eingehendere Prüfung des Codes), sind Sie auf der sicheren Seite. (Ps Kommentare sind auch upvotable :-))
Peter
Das gehört zur Sicherheit .
l0b0
@ l0b0 Eigentlich scheint es mir hier um ein Thema zu gehen (obwohl unter Unix und Linux möglicherweise genauere Antworten zu finden sind). Das Ausführen von Software, die vom umgebenden System isoliert ist, ist eine durchaus vernünftige Anforderung in Bezug auf die Verwendung von Computern durch einen Hauptbenutzer.
ein Lebenslauf vom

Antworten:

10

Es gibt tatsächlich mehrere Arten von virtuellen Maschinen, was in den anderen Antworten etwas übersehen wird. Sie können so etwas wie Containervirtualisierung haben - so etwas wie Linux vServer oder OpenVZ. Sie nutzen den Host-Kernel gemeinsam und führen sogenannte "Container" (mit ihren eigenen Umgebungen) aus, anstatt Hardware zu virtualisieren, und sind fast so schnell wie Bare-Metal . (OpenVZ ist bei günstigeren VPS-Diensten üblicher, unterstützt jedoch nur einen benutzerdefinierten Kernel 2.6.x, während vServer auf den neuesten Stand gebracht wird.)

Abgesehen davon ist der Overhead der vollständigen Virtualisierung auf einer modernen Maschine nicht so schlimm, wie Sie denken! Bei der Hardwarevirtualisierung auf einer Mid-High-End-CPU würden die meisten Benutzer nicht einmal Leistungseinbußen bemerken, es sei denn, es gab einen Konflikt um Ressourcen (z. B. der Host oder eine andere VM verwendeten viel). Es wird etwas langsamer sein, da einige Ressourcen vom Gastbetriebssystem verwendet werden, aber die Kosten für die Virtualisierung selbst sind fast vernachlässigbar - insbesondere die CPU-Auslastung, da diese ohne (fast) keine Übersetzung an die Rohhardware weitergegeben werden kann, wenn dies der Fall ist Hardware beschleunigt. Sie könnten es versuchen, Sie könnten überrascht sein.


Beachten Sie, dass jede mit unterschiedlichen Isolationsstufen geliefert wird. Durch die Containervirtualisierung ist es viel einfacher, den Kernel und andere Fehler auszunutzen, um aus dem Container auszubrechen. LXC ist überhaupt nicht sicher, obwohl OpenVZ als ausgereift und sicher gilt (und häufig in VPS-Diensten verwendet wird, in denen Sie verkaufen) nicht vertrauenswürdigen Personen). vServer ist irgendwo dazwischen. Vollständige Virtualisierung hat eine bessere Isolation, aber es gibt noch einige Angriffe, die ausbrechen können.

Es hängt davon ab, wie weit Sie von einem böswilligen Schüler erwarten. Es kann ausreichend sein, einfach als ein anderer Benutzer zu laufen. Vielleicht möchten Sie einen Container für mehr Sicherheit. Es besteht die Möglichkeit, dass ein Container für alles ausreicht, was Sie unter diesen Umständen antreffen.

Bob
quelle
8

Erstellen Sie ein einzelnes Benutzerkonto mit eingeschränkten Berechtigungen (dh, Sie können nur auf eine begrenzte Anzahl von Bibliotheksroutinen zugreifen, möglicherweise sogar auf eine abgespeckte Shell).

ssh als Benutzer in Ihrem System und führen Sie ihre Programme aus.

Sie können sogar ein kleines bashShell-Skript (oder ein beliebiges anderes Shell-Skript) schreiben , um dies zu erreichen.

Vigneshwaren
quelle
1
Wie gut können Sie Berechtigungen einschränken? Idealerweise würde ich nicht zulassen, dass der Code zum Beispiel über das Netzwerk kommuniziert, aber das könnte ein Schritt zu weit sein.
Marshall
1
Um zu vermeiden, dass sie das Netzwerk nutzen, können Sie die ownerMatch-Erweiterung für iptables verwenden: siehe linuxpoison.blogspot.com.es/2010/11/…
Carlos Campderrós,
4
  1. Führen Sie den Code wie nobodyfolgt aus: Je nachdem, wie haarsträubend die Konfiguration ist, ist dies möglicherweise nicht sicher
  2. Laufen Sie in ein chrootGefängnis. Abhängig vom Code kann dies das Verhalten ändern und Gefängnisse können oft abgebrochen werden. Sie sind kein Sicherheitsmerkmal.
  3. In einer virtuellen Maschine ausführen. Ich glaube, es gibt nur sehr wenige bekannte Fälle, in denen man aus diesen ausbrechen kann, aber ich bin mir nicht sicher. Sie können beispielsweise Vagrant verwenden, um eine sehr einfache Virtualisierung einzurichten. Beispielkonfiguration und Befehle .
l0b0
quelle
2
Achtung. nobodywird manchmal von anderen Prozessen verwendet, auf die Sie ebenfalls zugreifen können.
Bob
@ Bob Guter Punkt!
l0b0
1

Es gibt verschiedene Möglichkeiten, je nachdem, wie sehr Sie isoliert sein möchten.

Am einfachsten ist es, einfach dem Code zu vertrauen. Es sieht so aus, als käme das für Sie nicht in Frage, sonst würden Sie das nicht fragen.

Der nächste Schritt besteht darin, den Code auf einem separaten Benutzerkonto auszuführen , wie von Vigneshwaren vorgeschlagen . Wenn Sie den Netzwerkzugriff speziell für ein bestimmtes Benutzerkonto einschränken möchten, können Sie dies durch die Zuordnung der Eigentümer zu iptables erreichen . Wenn dies erledigt ist, kann das Benutzerkonto beibehalten oder gelöscht werden, und alle Prozesse, die als dieser Benutzer ausgeführt werden, können sofort beendet werden.

Ein weiterer Schritt besteht darin, dem separaten Benutzerkonto ein Chroot-Gefängnis hinzuzufügen. Dies kann zu Problemen mit Bibliotheken oder Konfigurationsdateien führen, die vorhanden sein müssen. Wenn es sich jedoch beispielsweise um eine reine Zahlenkalkulationsübung handelt, kann dies praktisch sein. Dadurch wird sichergestellt, dass nur auf die Dateien zugegriffen werden kann, auf die der Schülercode zugreifen soll.

Der letzte Schritt wäre, den Code in einer völlig separaten Umgebung auszuführen. Denken Sie hier an eine virtuelle Maschine, obwohl ein separater physischer Computer dasselbe leisten könnte. Der Code kann in einer vollständig isolierten Umgebung ausgeführt werden, auch wenn das virtuelle Netzwerkkabel abgezogen ist. Eventuelle Schäden, einschließlich des Auffüllens des Datenträgers oder der Bombardierung durch Gabeln, werden innerhalb der virtuellen Maschine isoliert, und das Schlimmste, was passieren kann, ist dass Sie es zwangsweise ausschalten müssen. Da die VM über eine vollständig separate Betriebssysteminstallation verfügt, insbesondere wenn Sie die Netzwerkverbindung trennen, bevor Sie die Software ausführen, können Ihre vertraulichen Daten möglicherweise nicht verloren gehen. Mit einer VM können Sie Datenträger-Snapshots verwenden, um schnell und einfach in einen bekannten Zustand zurückzukehren, nachdem Sie das Programm jedes Schülers ausgeführt haben.

Es hängt alles davon ab, wo auf der Skala von Aufwand zu Vertrauen Sie Ihre Schüler unterbringen. Weniger Vertrauen erfordert mehr Anstrengungen, um sicherzustellen, dass nichts Schlimmes passiert.

ein CVn
quelle
Vielen Dank. Ich denke in diesem Fall wäre ein separater Account mit, iptables und einem chroot-Gefängnis ausreichend. Können Sie uns etwas näher erläutern, wie das Chroot-Gefängnis sinnvoll funktioniert?
Marshall
@ Marshall Sorry, das ist einfach zu breit. Die grundlegendste Antwort auf diese chroot /mnt/chroot /bin/bashFrage lautet: "Machen Sie es für einen bestimmten Wert von / mnt / chroot und beheben Sie alles, worüber es sich beschwert, bis es für das funktioniert, was Sie brauchen." Sie müssen es wahrscheinlich mit einer Shell, einigen grundlegenden Dienstprogrammen, allen erforderlichen Bibliotheken und allem anderen füllen, was die jeweilige Anwendung benötigt. Ich schlage vor, sich umzusehen und es zu versuchen, und wenn Sie auf eine Straßensperre stoßen, stellen Sie eine bestimmte Frage dazu.
ein Lebenslauf vom
0

I have to mark C code

Dann haben Sie uneingeschränkten Zugriff auf den Quellcode. Sehen Sie, es ist zweifelhaft, dass sie in der Lage sind, böswillige Inhalte im Code weiterzugeben, ohne dass Sie es bemerken.

Wenn Sie sich nicht sicher sind, ob es sich um eine VM handelt, wissen Sie in den meisten Fällen, was gerade ausgeführt wird

exussum
quelle
1
Ich verweise Sie auf underhanded.xcott.com :)
Marshall
1
@marshall Beachten Sie, dass diese sich mit Fehlern im Programm befassen und nicht außerhalb des Programms zugreifen. Dies ist eigentlich ein ziemlich guter Vorschlag, wenn die Programme einfach sind und keinen Zugriff auf Systemaufrufe haben sollen, da Sie Systemaufrufe im Compiler deaktivieren können, um deren Verwendung vollständig zu verhindern, einschließlich etwaiger Fehler im System. Wenn es sich jedoch nicht um ein triviales Programm handelt, wäre dies viel schwieriger. Außerdem müsste man darauf vertrauen, dass man alles Notwendige deaktiviert hat.
Bob
0

Ich habe vor ein paar Jahren an einem ähnlichen System gearbeitet. Ich habe ptrace verwendet, um die Systemaufrufe zu begrenzen (siehe Code hier ) und optional die Benutzer-ID oder Chroot zu ändern. Wenn die Programme einfach sind und nur reine Algorithmen und grundlegende E / A-Aufgaben beinhalten, sollte dies eine praktische Lösung sein, die Sie in Betracht ziehen können.

Übrigens ist es erwähnenswert, dass Sie auch die Compiler-Zeit / die Speichernutzung begrenzen sollten. Einige bösartige Programme enthalten möglicherweise Anweisungen, #include </dev/random>die dazu führen können, dass der Compiler längere Zeit hängen bleibt, oder einige rekursive Makros, die dazu führen, dass der Compiler viel Speicher verbraucht.

Jiakai
quelle
Das OP will die Programme zeitlich festlegen. Würde ptrace nicht das Timing verunreinigen?
Scott
@Scott Ich denke, wenn die CPU-Zeit anstatt der Echtzeit des verfolgten Prozesses gemessen wird und Systemaufrufe nicht sehr häufig sind, würde ptrace nicht viel beeinflussen.
Jiakai