Das Sandbox2-Design basiert auf bekannten und etablierten Technologien, einem Richtlinienframework und zwei Prozessen: dem Sandbox-Executor und dem Sandboxee.
Beteiligte Technologien
In den folgenden Abschnitten werden die Technologien beschrieben, die die Fundierungsebene für Sandbox2 bilden.
Linux-Namespaces
Die Linux-Namespaces sind ein Versuch, Virtualisierung auf Betriebssystemebene zu ermöglichen. Mehrere Nutzerbereiche werden scheinbar unabhängig voneinander ausgeführt, sie verwenden jedoch eine gemeinsame Kernelinstanz. Sandbox2 verwendet die folgenden Arten von Namespaces:
- IPC
- Netzwerk (sofern nicht explizit durch Aufrufen von
PolicyBuilder::AllowUnrestrictedNetworking()
deaktiviert) - Bereitstellen (mit einer benutzerdefinierten Ansicht der Dateisystemstruktur)
- PID
- Nutzer
- UTS
Weitere Informationen zu Linux-Namespaces finden Sie auf Wikipedia oder auf der zugehörigen Manpage.
IPC
Mit Sandbox2 können beliebige Daten zwischen dem Sandbox-Executor und dem nicht vertrauenswürdigen Sandboxee ausgetauscht werden. Es unterstützt TLV-Nachrichten (Type-Length-Value), die Übergabe von Dateideskriptoren und den Austausch von Anmeldedaten über Tokens und Handles.
Seccomp-BPF
Sandbox2 basiert auf seccomp-bpf, einer Erweiterung des Secure Computing Mode (seccomp), mit der Systemaufrufe mithilfe von Berkeley Packet Filter (BPF)-Regeln gefiltert werden können.
seccomp ist eine Linux-Kernel-Funktion, die die Systemaufrufe eines Prozesses auf exit
, sigreturn
, read
und write
beschränkt. Wenn ein Prozess versucht, einen anderen Systemaufruf auszuführen, wird er beendet. Die seccomp-bpf-Erweiterung bietet mehr Flexibilität als seccomp. Anstatt eine feste Gruppe von Systemaufrufen zuzulassen, führt seccomp-bpf ein BPF-Programm für die Systemaufrufdaten aus. Je nach Rückgabewert des Programms kann der Systemaufruf ausgeführt, übersprungen und ein Dummy-Wert zurückgegeben, der Prozess beendet, ein Signal generiert oder der Tracer benachrichtigt werden.
Ptrace
Der ptrace-Systemaufruf (process trace) bietet Funktionen, mit denen der Tracer-Prozess die Ausführung des Tracee-Prozesses beobachten und steuern kann. Der Tracer-Prozess hat die volle Kontrolle über den Tracee, sobald er angehängt ist. Weitere Informationen zu „ptrace“ finden Sie auf Wikipedia oder auf der zugehörigen Manpage.
Sandbox-Richtlinie
Die Sandbox-Richtlinie ist der wichtigste Teil einer Sandbox, da sie die Aktionen angibt, die der Sandboxee ausführen darf und welche nicht. Eine Sandbox-Richtlinie besteht aus zwei Teilen:
- Syscall-Richtlinie
- Namespace einrichten
Standard-Syscall-Richtlinie
Die Standardrichtlinie blockiert Syscalls, die immer gefährlich sind, und hat Vorrang vor der vom Nutzer bereitgestellten erweiterten Richtlinie.
Erweiterte Syscall-Richtlinie
Die erweiterte Syscall-Richtlinie kann mit unserer PolicyBuilder-Klasse erstellt werden. In dieser Klasse werden eine Reihe von praktischen Regeln definiert (z.B. AllowStaticStartup
, AllowDynamicStartup
, AllowOpen
), mit denen die Lesbarkeit Ihrer Richtlinie verbessert werden kann.
Wenn Sie Syscalls weiter einschränken oder komplexere Regeln benötigen, können Sie mit AddPolicyOnSyscall
und AddPolicyOnSyscalls
rohe BPF-Makros angeben. Im crc4-Beispiel wird dieser Mechanismus verwendet, um Argumente für die Syscalls read
, write
und close
einzuschränken.
Im Allgemeinen gilt: Je strenger die Sandbox-Richtlinie, desto besser, da die Ausnutzung von Sicherheitslücken im Code durch die Richtlinie eingeschränkt wird. Wenn Sie genau angeben können, welche Systemaufrufe und Argumente für den normalen Betrieb des Programms erforderlich sind, unterliegt jeder Angreifer, der eine Codeausführungslücke ausnutzt, denselben Einschränkungen.
Eine sehr restriktive Sandbox-Richtlinie könnte alle Systemaufrufe mit Ausnahme von Lese- und Schreibvorgängen für Standard-Ein- und Ausgabedateideskriptoren ablehnen. In dieser Sandbox konnte ein Programm Eingaben entgegennehmen, verarbeiten und die Ausgabe zurückgeben. Wenn der Prozess jedoch versuchen würde, einen anderen Systemaufruf auszuführen, würde er aufgrund eines Richtlinienverstoßes beendet. Wenn der Prozess also manipuliert wird (Ausführung von Code durch einen böswilligen Nutzer), kann er nichts Schlimmeres anrichten, als eine fehlerhafte Ausgabe zu erzeugen, die vom Executor und anderen weiterhin korrekt verarbeitet werden muss.
Namespace einrichten
Das PolicyBuilder-Objekt wird auch verwendet, um die individuelle Ansicht des Dateisystems für einen Sandboxee einzurichten. Einzelne Dateien (AddFile
/ AddFileAt
), ganze Verzeichnisse (AddDirectory
/ AddDirectoryAt
) sowie temporärer Speicher (AddTmpfs
) können in die Umgebung des Sandboxee eingebunden werden. Außerdem kann AddLibrariesForBinary
verwendet werden, um automatisch alle Bibliotheken zuzuordnen, die für die angegebene dynamisch verknüpfte ausführbare Datei erforderlich sind.
Befehlszeilen-Flags
Jede Sandbox2-Richtlinie kann durch Angabe eines der folgenden Befehlszeilen-Flags deaktiviert werden. Diese Flags sind für Testzwecke vorgesehen, z.B. zum Optimieren der erweiterten Syscall-Richtlinie.
--sandbox2_danger_danger_permit_all
--sandbox2_danger_danger_permit_all_and_log
Sandbox-Executor
Der Sandbox-Executor ist ein Prozess, der selbst nicht in einer Sandbox ausgeführt wird. Es handelt sich um den ptrace-Tracer-Prozess, der an den Sandboxee-Prozess (ptrace-Tracee-Prozess) angehängt wird. Der Sandbox-Executor richtet auch eine Monitor-Instanz ein und führt sie aus, die den Sandboxee verfolgt und Statusinformationen bereitstellt.
Sandbox2 bietet drei Ausführungsmodi: Stand-alone, Sandbox2-Forkserver und benutzerdefinierter Forkserver. Wenn Sie einen Forkserver verwenden, wird der Sandboxee als untergeordneter Prozess des Sandbox-Executors erstellt. Diese Modi werden hier ausführlich beschrieben.
Sandboxee
Der Sandboxee ist der Prozess, der in der eingeschränkten Sandbox-Umgebung ausgeführt wird, die durch die Sandbox-Richtlinie definiert wurde. Der Sandbox-Executor sendet die Richtlinie über IPC an den Sandboxee. Der Sandboxee wendet dann die Richtlinie an. Jeder Verstoß gegen die Richtlinie führt zur Beendigung des Prozesses, sofern nichts anderes konfiguriert ist (siehe Sandbox-Richtlinie).