Mehrschichtige Verteidigung für einen lokalen Secret-Service

CybersicherheitBeginner
Jetzt üben

Einführung

Mehrschichtige Verteidigung (Defense in Depth) bedeutet, mehrere Sicherheitskontrollen zu kombinieren, damit ein einzelner Fehler nicht sofort ein wichtiges Asset gefährdet. Eine Token-Prüfung, eine lokale Netzwerkbindung, Dateiberechtigungen und eine Protokollierung schützen jeweils einen anderen Aspekt desselben Dienstes.

In diesem Lab härten Sie einen kleinen Python-Dienst, der eine geheime Datei ausliest. Sie nehmen jeweils eine kleine Änderung vor, starten den Dienst, testen ihn mit curl und überprüfen, wie die verschiedenen Ebenen zusammenwirken.

Start mit einem ungeschützten Geheimnis

In diesem Schritt untersuchen Sie den Dienst und beobachten die erste Kontrollinstanz: Eine Anfrage ohne das erwartete Token wird abgelehnt, während eine Anfrage mit dem korrekten Token erfolgreich ist. Mehrschichtige Verteidigung beginnt damit, zu prüfen, was bereits geschützt ist und wo eine weitere Schutzschicht erforderlich ist.

Wechseln Sie in das Projektverzeichnis:

cd /home/labex/project

Listen Sie die vorbereiteten Dateien auf:

ls -l

Sie sollten secret_service.py, secret.txt und service-check.py sehen.

Starten Sie den Dienst im Hintergrund. Das & am Ende weist die Shell an, den Dienst weiterlaufen zu lassen, während Sie weitere Befehle eingeben:

python3 secret_service.py > service.log 2>&1 &

Speichern Sie die Prozess-ID des Hintergrundprozesses, damit Sie ihn später sauber beenden können:

echo $! > service.pid

Versuchen Sie, das Geheimnis ohne Token auszulesen:

curl -i http://127.0.0.1:8081/secret

Die Antwort sollte 403 Forbidden enthalten. Senden Sie nun den erforderlichen Token-Header:

curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret

Sie sollten Folgendes sehen:

Project launch code: ORBIT-742

Stoppen Sie den Dienst, bevor Sie fortfahren:

kill "$(cat service.pid)"

Führen Sie die Überprüfung für die Token-Ebene aus:

python3 service-check.py token

Das erwartete Ergebnis ist:

token: complete

Den Dienst lokal halten

In diesem Schritt bestätigen Sie die Ebene der Netzwerk-Exponierung. Ein Dienst, der nur lokalen Zugriff benötigt, sollte an 127.0.0.1 gebunden sein, auch bekannt als localhost. Diese Adresse akzeptiert nur Verbindungen von derselben Maschine.

Überprüfen Sie die Standard-Host-Einstellung des Dienstes:

grep 'default="127.0.0.1"' secret_service.py

Sie sollten die Argumentdefinition für die Option --host sehen. Dieser Standardwert bedeutet, dass der Befehl python3 secret_service.py den Dienst auf localhost startet.

Starten Sie den Dienst erneut:

python3 secret_service.py > service.log 2>&1 &

Speichern Sie die Prozess-ID:

echo $! > service.pid

Verwenden Sie ss, um die lauschenden TCP-Sockets zu untersuchen. Die Optionen -ltn stehen für listening, TCP und numerische Adressen:

ss -ltn | grep ':8081'

Die Ausgabe sollte 127.0.0.1:8081 zeigen, was beweist, dass der Dienst nur lokal erreichbar ist:

LISTEN ... 127.0.0.1:8081 ...

Stoppen Sie den Dienst:

kill "$(cat service.pid)"

Führen Sie die Überprüfung für die Localhost-Ebene aus:

python3 service-check.py localhost

Das erwartete Ergebnis ist:

localhost: complete

Die geheime Datei einschränken

In diesem Schritt fügen Sie eine Ebene mit Dateisystemberechtigungen hinzu. Selbst wenn der Dienst einen Fehler aufweist, sollte die geheime Datei nicht für jedes lokale Konto lesbar sein.

Überprüfen Sie die aktuellen Dateiberechtigungen:

ls -l secret.txt

Die Datei hat anfangs breitere Berechtigungen, damit Sie diese verbessern können. Verwenden Sie chmod 600, um die Datei nur für den Besitzer lesbar und beschreibbar zu machen:

chmod 600 secret.txt

Überprüfen Sie die Berechtigungen erneut:

ls -l secret.txt

Die Berechtigungsbits sollten nun mit -rw------- beginnen:

-rw------- ... secret.txt

Führen Sie die Überprüfung für diese Ebene aus:

python3 service-check.py permissions

Das erwartete Ergebnis ist:

permissions: complete

Abgelehnte Anfragen protokollieren

In diesem Schritt testen Sie die Erkennungsebene. Das Blockieren einer unbefugten Anfrage ist nützlich, aber die Aufzeichnung dieser Ablehnung liefert Administratoren den Beweis, dass jemand versucht hat, auf die geschützte Route zuzugreifen.

Löschen Sie alte Protokolldateien, damit dieser Schritt sauber beginnt:

rm -f access.log

Starten Sie den Dienst:

python3 secret_service.py > service.log 2>&1 &

Speichern Sie die Prozess-ID:

echo $! > service.pid

Senden Sie eine Anfrage ohne Token:

curl -s http://127.0.0.1:8081/secret

Der Antworttext sollte wie folgt lauten:

forbidden

Sehen Sie sich das Zugriffsprotokoll an:

cat access.log

Das Protokoll sollte rejected, /secret und missing_or_bad_token enthalten.

Stoppen Sie den Dienst:

kill "$(cat service.pid)"

Führen Sie die Überprüfung für die Protokollierungsebene aus:

python3 service-check.py logging

Das erwartete Ergebnis ist:

logging: complete

Die Ebenen gemeinsam verifizieren

In diesem Schritt verifizieren Sie das vollständige Ergebnis der mehrschichtigen Verteidigung. Der Dienst sollte das Token erfordern, standardmäßig lokal bleiben, die geheime Datei mit Berechtigungen nur für den Besitzer schützen und abgelehnte Anfragen protokollieren.

Führen Sie die vollständige Überprüfung aus:

python3 service-check.py all

Jede Ebene sollte als abgeschlossen markiert sein:

token: complete
localhost: complete
permissions: complete
logging: complete

Starten Sie den Dienst ein letztes Mal:

python3 secret_service.py > service.log 2>&1 &

Speichern Sie die Prozess-ID:

echo $! > service.pid

Bestätigen Sie, dass das Geheimnis für eine autorisierte Anfrage weiterhin funktioniert:

curl -s -H "X-Access-Token: lab-token-2026" http://127.0.0.1:8081/secret

Sie sollten weiterhin Folgendes sehen:

Project launch code: ORBIT-742

Stoppen Sie den Dienst:

kill "$(cat service.pid)"

Diese abschließende Prüfung ist wichtig, da die mehrschichtige Verteidigung den Dienst schützen sollte, ohne die beabsichtigte autorisierte Nutzung zu beeinträchtigen.

Zusammenfassung

Sie haben das Prinzip der mehrschichtigen Verteidigung geübt, indem Sie verschiedene Kontrollen um einen kleinen Dienst herum aufgebaut haben. Sie haben eine Token-Anforderung, eine lokale Bindung, Dateiberechtigungen nur für den Besitzer und die Protokollierung abgelehnter Zugriffe verifiziert.

Die wichtigste Erkenntnis ist, dass jede Ebene einen anderen potenziellen Fehlerpunkt absichert, während das autorisierte Verhalten des Dienstes weiterhin gewährleistet bleibt.