Hardening Dienstag: AppArmor Teil 2 - Ich sehe was, was du nicht siehst

in #deutsch2 years ago

Heute bin ich beim Aufräumen meiner Platte (ich weiß, aufräumen ist bäh und macht man nicht) glatt auf den Entwurf einer schon fast vergessenen Fortsetzung gestoßen. Na wenn das (und natürlich meine grenzenlose Geldgier bei den Kursen, wobei ich natürlich auch weiterhin Schecks, Bankkarte und PIN, sowie Erstgeborene Kinder in Anzahlung nehme) kein Anlass ist, mal wieder den Linux-Rechner anzuwerfen.

apparmor.png
(©CC4.0, Noah Davis, 2018. Siehe auch hier, bzw. hier. Entstammt der offiziellen Website)

Intro

Im letzten Teil der Reihe (Anm. is ja grade mal knapp zwei Jahre her. Da hätte ich mir auch noch Zeit lassen können) haben wir AppArmor auf unserem Rechner konfiguriert. Nun wollen wir es einmal ausprobieren (Anm. Warum eigentlich immer wir? So fett bin ich nun auch wieder nicht..).


AppArmor 101

Die Idee hinter AppArmor ist simpel: Ein Programm erhält eine Aufzeichnung (sog. Profil) aller Interaktionen mit der Umgebung, in der es läuft. Dies können u.a. der Zugriff auf Schnittstellen, das Binden an Ports (z.B. bei Webservern) oder der Zugriff auf Dateien und Ordner sein.
Nach der Erstellung des Profils (und ausführlichen Tests, dass das Programm immer noch das tut, was es soll), kann es "scharf"-geschaltet werden. Dann stellt AppArmor sicher, dass unser Programm nur das tun darf, was im Profil angegeben wurde.

Umgebung

Für den Testlauf benötigen wir ein Programm, welches eine Schwachstelle besitzt, die durch AppArmor abgedeckt werden kann (WICHTIG: AppArmor ersetzt natürlich keine Sicherheitstests oder das Beheben von Schwachstellen!). Wir benutzen hierfür unser Beispielprogramm aus dem Symlink-Angriff-Post (Anm. das damalige Programm war ähnlich, aber da inzwischen bereits ein Post über besagtes Programm vorliegt, ist dieses Beispiel geeigneter).

Durchführung

Der eigentlichen Angriff (und dessen Folgen) wurden im Symlink-Post ja bereits beschrieben. Nun sichern wir unser Programm mittels AppArmor ab.

Profilerstellung

Ein AppArmor-Profil kann von Hand oder via Assistent erstellt werden. Für unseren Fall ist der Assistent jedoch vollkommen hinreichend.

$ sudo aa-genprof /tmp/daemon

AppArmor-Profile in /etc/apparmor.d werden aktualisiert.
Aktualisiertes Profil für /tmp/daemon wird geschrieben.
/tmp/daemon wird in den Complain-Modus versetzt.

Bevor Sie beginnen, möchten Sie vielleicht prüfen,
ob bereits ein Profil für das Programm besteht,
das Sie einschränken möchten. Weitere Informationen
können Sie auf der folgenden Wiki-Seite erhalten:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profilerstellung: /tmp/daemon

Starten Sie die Anwendung, für die ein Profil erstellt werden soll, in
einem anderen Fenster, und führen Sie die Funktionalität jetzt aus.

Nach Abschluss dieses Vorgangs bitte unten »Durchsuchen« wählen,
um in den Systemprotokollen nach AppArmor-Ereignissen zu suchen. 

Für jedes AppArmor-Ereignis haben Sie die Gelegenheit anzugeben,
ob der Zugriff zugelassen oder verweigert werden soll.

[Systemprotokoll nach AppArmor-Ereignissen (s)cannen] / En(d)e

Das ist schonmal einiges an Informationen, die wir hier erhalten.
Zunächst wird das Profil erstellt und in den Complain-Modus versetzt. Das bedeutet, dass Verstöße gegen die Profilrichtlinien zwar protokolliert, jedoch nicht von AppArmor unterbunden werden.

Weiterhin sollen wir die Anwendung nun ausführen, und zwar so, wie sie im regulären Betrieb genutzt werden würde (hierbei sollten möglichst alle Anwendungsfälle abgedeckt werden, da diese sonst im Profil fehlen).

Dann machen wir doch nun genau das. In einem weiteren Fenster führen wir nun folgendes aus:

$ /tmp/daemon
Write something: abcdefg
Write something: STRG+d
$ cat logfile.txt
Daemon initialized
abcdefgDaemon stopped. Have a nice day!

Wenn wir nun zurück zu unserem aa-genprof wechseln und s (für scannen) drücken, dann erscheint folgende Info:

Protokolleinträge von /var/log/audit/audit.log werden gelesen.
Änderungen im complain-Modus

Profil:      /tmp/daemon
Pfad:        /tmp/logfile.txt
Neuer Modus: owner w
Schweregrad: unbekannt

  [1 - include <abstractions/lightdm>]
  2 - include <abstractions/user-tmp> 
  3 - owner /tmp/logfile.txt w, 
Erl(a)uben / [A(b)lehnen] / (I)gnorieren / (G)lob / Glob with (E)xtension / (N)eu / Audi(t) / Be(s)itzerberechtigungen aus / Abb(r)echen / En(d)e

Hier können wir uns zwischen drei Optionen entscheiden. Abstractions sind Gruppen an Richtlinien, die Profilelemente für einen gewissen Sachverhalt zusammenfassen (eine Art Schablone/Vorlage). Hier wird z.B. user-tmp angeboten, welches uns helfen würde, falls unser Programm viel im /tmp-Verzeichniss arbeiten müsste. Da uns aber nur eine einzige Datei (und zwar /tmp/logfile.txt) interessiert, ignorieren wir die Abstractions und wählen Option 3, welche die Datei /tmp/logfile.txt als Eigentum des Programms (und mit Schreibrechten) im Profil hinterlegt.
Diese wählen wir mit den Pfeiltasten und bestätigen mit a (Erlauben).

Daraufhin erhalten wir folgende Nachricht:

= Changed Local Profiles =
Die folgenden lokalen Profile wurden geändert. Möchten Sie sie speichern?

 [1 - /tmp/daemon]
Änderungen (s)peichern / Ausgewähl(t)es Profil speichern / [Änderungen an(z)eigen] / Änderungen zwischen sau(b)eren Profilen anzeigen / Abb(r)echen

Dies bestätigen wir mit s (speichern).

Nun sind wir wieder im Hauptdialog. Da wir die gesamte Funktionalität des Programms jedoch bereits ausgeschöpft haben, können wir nun mit d (Ende) die Profilerstellung beenden.

/tmp/daemon wird in den Erzwingen-Modus versetzt.

AppArmor-Profile wurden im Erzwingenmodus neu geladen.

Bitte überlegen Sie es Ihr neues Profil beizusteuern.
Weitere Informationen können Sie auf der folgenden Wiki-Seite erhalten:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profilerstellung für /tmp/daemon abgeschlossen.

Damit wurde unser Profil auch gleich scharfgeschaltet, was wir mit einem Blick auf aa-status bestätigen können:

$ sudo aa-status

apparmor module is loaded.
x profiles are loaded.
y profiles are in enforce mode.
   /tmp/daemon
    ...

Verifikation

Nun führen wir den Angriff noch einmal durch:

$ rm logfile.txt
$ touch passwd
$ ln -s passwd logfile.txt
$ ./daemon
Write something: abcdefg
Write something: STRG+D

Wenn wir uns nun jedoch die passwd-Datei anschauen, so ist diese leer (da wir keine Zugriffsrechte auf ebendiese Datei im AppArmor-Profil haben):

$ cat passwd

Dies können wir auch nochmal im Systemlog überprüfen:

$ sudo journalctl -n 200
...
AVC apparmor="DENIED" operation="open" profile="/tmp/daemon" name="/tmp/passwd" pid=x comm="daemon" requested_mask="wc" denied_mask="wc" fsuid=y ouid=z
...

Hier sehen wir, dass die Schreib-Operation des Programms von AppArmor verweigert wurde, weshalb wir auch keinen Eintrag in der Datei finden können.

Profil im Klartext

Hier noch einmal das Profil, welches uns vom Assistent generiert wurde:

# Last Modified: Sun Mar 21 21:40:27 2021
abi <abi/3.0>,

include <tunables/global>

/tmp/daemon {
  include <abstractions/base>

  /tmp/daemon mr,
  owner /tmp/logfile.txt w,

}

Resume und Anmerkungen

AppArmor bietet eine Vielzahl an Möglichkeiten, um insbesondere kleinere Anwendungen zusätzlich abzusichern. Da AppArmor als Kernelmodul im Kernel läuft, ist es zwar potentiell anfällig gegen Kernel-Exploits, diese sind jedoch meist sehr spezifisch auf eine Kernel-Version angepasst und selten in freier Wildbahn zu beobachten.
Problematisch kann bei AppArmor allerdings sein, dass es pfadbasiert arbeitet (im Gegensatz zu z.B. SELinux, welches Label verwendet). Dies führt dazu, dass selbst simple Dateioperationen wie ein Verschieben oder Kopieren von Dateien bereits eine Aktualisierung des Profils, oder im schlimmsten Fall das (teilweise-) aushebeln des Schutzes (z.B. durch einen unachtsamen Administrator) nach sich ziehen kann.

Auch in der Containerwelt hat AppArmor aufgrund des pfadbasierten Systems und den eingesetzten mount-namespaces (die den Dateibaum innerhalb des Containers verändern) so seine Schwierigkeiten.
Alles in Allem is AppArmor allerdings oft eine gute erste Möglichkeit, um die Sicherheit auf dem System zu erhöhen.
WICHTIG: AppArmor ersetzt selbstverständlich keine Sicherheitstests von Anwendungen oder das Patchen von Bugs, sondern soll lediglich als weitere Schutzebene (eine Art (vor-)letzte Instanz) dienen. Ein AppArmor-Profil alleine ist daher oft nicht ausreichend, um eine Anwendung hinreichend zu sichern.

Sort:  

Du hast ein Upvote von mir bekommen, diese soll die Deutsche Community unterstützen. Wenn du mich unterstützten möchtest, dann sende mir eine Delegation. Egal wie klein die Unterstützung ist, Du hilfst damit der Community. DANKE!

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider supporting our funding proposal, approving our witness (@stem.witness) or delegating to the @stemsocial account (for some ROI).

Please consider using the STEMsocial app app and including @stemsocial as a beneficiary to get a stronger support.