Blog
Wie Sie Ihre Webanwendung mit Dynamic Application Security Testing (DAST) sicherer machen - Teil 2 der Serie Application Security Testing

Einführung
Willkommen zum zweiten Teil der Serie über Anwendungssicherheitstests. Wie ich bereits im vorherigen Blog erwähnt habe, werden wir uns in dieser Blogserie mit den verschiedenen Arten von Anwendungssicherheitstests und der Analyse der Softwarezusammensetzung beschäftigen. Wenn Sie den ersten Teil verpasst haben, sollten Sie ihn sich unbedingt ansehen: Application Security Testing Teil eins.
Dieses Mal konzentrieren wir uns auf Dynamic Application Security Testing (DAST). Zunächst werde ich eine kurze Erklärung zu DAST geben. Nach der Erklärung werden die Vor- und Nachteile von DAST aufgeführt. Zum Abschluss zeigen wir Ihnen eine Demo eines Open Source DAST-Tools namens OWASP ZAP, das wir für unsere eigene anfällige Webanwendung verwenden.
Die verwundbare Webanwendung ist die gleiche, die wir im ersten Blog dieser Serie verwendet haben. Sie können den Quellcode hier herunterladen: vulnapp.
[caption id="attachment_59673" align="alignnone" width="1024"]
Abbildung 1: Platzierung von DAST und anderen Tests zur Anwendungssicherheit in den Entwicklungsphasen[/caption]
Das automatisierte DAST findet während der "Test"-Phase der Software-Entwicklungsphasen statt. Nichts hindert Sie jedoch daran, ZAP herunterzuladen, um es manuell in Ihrer eigenen lokalen Umgebung zu verwenden.
Wie funktioniert DAST?
DAST testet die Sicherheit einer Anwendung, indem es sie während der Laufzeit überprüft. Dazu benötigt er Informationen über die zu prüfende Webanwendung. Einige Beispiele für Informationen sind URLs und Anmeldedaten.
ZAP beginnt mit dem Spidern Ihrer Webanwendung: Auf der Grundlage der von Ihnen angegebenen URL sucht ZAP nach Links in Seiten, um einen Überblick über die URLs Ihrer Webanwendung zu erhalten. Es registriert diese und startet dann den Scanvorgang. Ein DAST-Tool scannt, indem es HTTP-Anfragen mit bösartigen Nutzdaten sendet und die entsprechenden HTTP-Antworten analysiert, um mögliche Schwachstellen zu identifizieren. Ein DAST-Tool analysiert die HTTP-Antworten, da es keine Kenntnis von der internen Funktionsweise der Anwendung hat.
Ein DAST-Tool verwendet Richtlinien oder Regeln, um festzulegen, welche Art von Angriffen ausgeführt werden soll. Diese Angriffe werden eine bestimmte Art von Sicherheitslücke aufdecken. Anders als die Regeln von SAST-Tools sind sie nicht sprachspezifisch. Vergewissern Sie sich jedoch, dass das DAST-Tool, das Sie verwenden möchten, Richtlinien/Regeln enthält, die die Arten von Sicherheitslücken definieren, die für Ihren Kontext wichtig sind. Die Sicherheitsabteilung sollte Ihnen dabei helfen können.
[caption id="attachment_59674" align="alignnone" width="1024"]
Abbildung 2: Übersicht über DAST auf hoher Ebene[/caption]
Vorteile und Nachteile von DAST
Vorteile
- Ermöglicht die Identifizierung von laufzeit- und umgebungsbezogenen Sicherheitsproblemen
- Sprach- und plattformunabhängig, da es das Verhalten und nicht den Code analysiert
- Erfordert keinen Zugang zum Quellcode
Benachteiligungen
- Langsam, weil es viele Anfragen an die Webanwendung senden und die Antworten auswerten muss
- Gibt keinen genauen Hinweis auf eine Sicherheitslücke im Code
- Sicherheitskenntnisse sind erforderlich, um den Bericht zu verstehen, da er weniger detailliert ist.
- Erfordert eine Laufzeitumgebung, d.h. sie findet in einer der späteren Phasen des Softwareentwicklungszyklus statt
- Skalierung ist schwierig und erfordert Experten mit DAST- und Sicherheitswissen
Wenn Sie sich die oben genannten Punkte ansehen, scheinen die Nachteile in der Überzahl zu sein. Die Nachteile werden aufgelistet, um Ihnen bewusst zu machen, dass Sie das Tool und den Prozess darum herum feinabstimmen sollten. Sie können überwunden werden, indem Sie Maßnahmen ergreifen, um ihnen zu begegnen. Der erste Nachteil lässt sich beispielsweise abmildern, indem Sie ein DAST-Tool in einer separaten CI/CD-Pipeline anstelle Ihrer Haupt-Build-Pipeline verwenden und es nachts laufen lassen. Auf diese Weise liegen Ihnen die Ergebnisse am nächsten Morgen vor und Sie müssen nicht stundenlang warten, bis Ihre Build-Pipeline fertig ist. Wenn es irgendwelche Schwachstellen gibt, können Sie sie am nächsten Tag beheben.
Demo mit OWASP ZAP
Jetzt ist es an der Zeit, ein DAST-Tool gegen unsere verwundbare Webanwendung einzusetzen. Wir werden OWASP Zed Attack Proxy (ZAP) verwenden, ein Open Source-Tool, das auch für Penetrationstests eingesetzt werden kann. ZAP kann als Man-in-the-Middle-Proxy eingerichtet werden, d.h. es fängt HTTP-Anfragen und HTTP-Antworten ab, die zwischen dem Browser und der Webanwendung ausgetauscht werden. Wir werden eine weitere Funktion von OWASP ZAP nutzen, nämlich seine Scan-Funktionen. Wenn Sie mehr über die Möglichkeiten von OWASP ZAP erfahren möchten, besuchen Sie die Website von OWASP ZAP.
Für diese Demo werden wir die Docker-Version von OWASP ZAP verwenden. Es ist also erforderlich, dass Sie Docker auf Ihrem System installiert haben. Sie können Docker hier herunterladen.
Sobald Docker installiert ist, müssen Sie das OWASP ZAP Docker-Image ziehen. Starten Sie ein Terminal und führen Sie den folgenden Befehl aus:
docker pull owasp/zap2docker-stable
Wenn Sie ein Macbook mit einem M-Chip haben, wird das gezogene Image nicht funktionieren, da es für eine andere CPU-Architektur erstellt wurde. Wir müssen das Image dann selbst erstellen. Laden Sie den OWASP ZAP-Quellcode hier herunter oder klonen Sie ihn. Starten Sie ein Terminal und wechseln Sie mit 'cd' in den Ordner, der den ZAP-Quellcode enthält. Sobald Sie sich im Stammordner des ZAP-Quellcodes befinden, wechseln Sie mit 'cd' in den Docker-Ordner. Führen Sie den folgenden Befehl aus:
Docker build -t zapm1 -f Dockerfile-stable .
Docker wird das ZAP-Image erstellen und es zapm1 nennen. Die Vorbereitung des ZAP-Docker-Images ist nun abgeschlossen.
Als nächstes starten wir die verwundbare Anwendung. Verwenden Sie ein Terminal und 'cd' in den heruntergeladenen Stammordner der verwundbaren Anwendung namens vulnerable-app. Er enthält eine Datei namens vulnapp-0.0.1-SNAPSHOT.jar. Wir verwenden diese Datei, um die Webanwendung mit dem folgenden Befehl auszuführen:
java -jar vulnapp-0.0.1-SNAPSHOT.jar
Die Anwendung wird unter http://localhost:8080 ausgeführt.
Nun ist es an der Zeit, den aktiven Scanner von ZAP auf unsere Webanwendung anzuwenden. Dazu müssen wir ZAP einen Kontext über unsere Webanwendung zur Verfügung stellen. Zu diesem Zweck habe ich eine ZAP-Kontextdatei namens DAST.context erstellt. Sie enthält die Anmeldedaten für die Authentifizierung und die Login-/Logout-URL. Auf diese Weise können wir einen authentifizierten Scan durchführen. Ein authentifizierter Scan ist wichtig, da ZAP sonst nur unauthentifizierte Endpunkte scannt und potenzielle Schwachstellen übersehen würde. Weitere Informationen über Authentifizierung und ZAP finden Sie unter: ZAP-Authentifizierung. Sie finden die Datei DAST.context, indem Sie in den Stammordner der heruntergeladenen verwundbaren Anwendung gehen und zu dem Ordner ZAP navigieren. Sie können sich die Datei jetzt ansehen, aber wir werden sie in Kürze ändern.
Der ZAP-Docker-Container ist nicht in der Lage, die verwundbare Webanwendung unter http://localhost:8080 zu erreichen. Er benötigt Ihre private IP-Adresse, um die verwundbare Webanwendung zu erreichen.
Verwenden Sie den folgenden Befehl auf dem Terminal für Linux oder Mac:
ifconfig | grep -E '([0-9]{1,3}.){3}[0-9]{1,3}'
Oder für Fenster:
ipconfig /all
Kopieren Sie die IPV4-Adresse und öffnen Sie DAST.context mit einem Texteditor Ihrer Wahl. Ersetzen Sie alle drei Instanzen von <Ihre PRIVATE IP ADRESSE> durch die kopierte IPV4-Adresse und speichern Sie die Datei. Bei mir wird http://<IHRE PRIVATE IP-ADRESSE>:8080 zu http://192.168.1.148:8080.
Nun können wir ZAP mit unserer Webanwendung ausführen. Öffnen Sie ein Terminal und wechseln Sie in den Ordner, der die Datei DAST.context enthält. Führen Sie den folgenden Befehl aus, wenn Sie das M1-Image verwenden:
docker run -v $(pwd):/zap/wrk/:rw -t zapm1 zap-full-scan.py -t http://<IHRE PRIVATE IP ADRESSE>:8080/login -n DAST.context -U mike -r testreport.html
Führen Sie diesen Befehl aus, wenn Sie das heruntergeladene Image verwenden:
docker run -v $(pwd):/zap/wrk/:rw -t owasp/zap2docker-stable zap-full-scan.py -t http://<IHRE PRIVATE IP ADRESSE>:8080/login -n DAST.context -U mike -r testreport.html
Dieser Befehl verwendet ein Volume (-v), um Dateien zwischen dem Docker-Container und seiner Host-Umgebung verfügbar zu machen. Als nächstes wird das Python-Skript zap-full-scan.py verwendet, das in das ZAP Docker-Image eingebettet ist. Zunächst verwendet das Skript eine Spider-Funktion, um neue URLs in der Webanwendung zu entdecken und beginnt dann mit dem Scannen der entdeckten URLs. Wir zielen auf unsere Webanwendung mit -t und wie zuvor müssen Sie <IHRE PRIVATE IP ADRESSE> im Befehl durch Ihre eigene IP-Adresse ersetzen. Dann geben wir die Kontextdatei mit -n an und verwenden einen authentifizierten Scan, indem wir einen Benutzer, der in der Kontextdatei enthalten ist, mit -U angeben. Schließlich möchten wir, dass ZAP einen Bericht mit den Ergebnissen erstellt, indem wir -r verwenden.
Ergebnisse des OWASP ZAP-Scans
Nachdem ZAP fertig ist, werden die gefundenen Schwachstellen auf dem Terminalbildschirm angezeigt. ZAP erstellt außerdem eine Datei testreport.html in demselben Ordner, in dem Sie den Scan ausgeführt haben. Diese Datei gibt einen gut lesbaren Überblick über die Ergebnisse. Öffnen Sie den Bericht mit einem Browser und Sie sehen Abbildung 3.
[caption id="attachment_59675" align="alignnone" width="1186"]
Abbildung 3: OWASP ZAP-Scanergebnisse der verwundbaren Anwendung[/caption]
ZAP hat eine ganze Reihe von Sicherheitslücken gefunden, die von sehr schlimm (Hoch) bis zu möglicherweise problematisch (Informativ) reichen. Um mich kurz zu fassen, werde ich nur die hohen und mittleren Ergebnisse besprechen und nicht auf alle Schwachstellen eingehen. Wir werden uns nur die Cross-Site-Scripting-Schwachstelle genauer ansehen. Für weitere Details zu den anderen Sicherheitslücken werde ich auf die entsprechenden Ressourcen verweisen.
Cross-Site-Scripting
Die erste Art von High Finding ist Cross Site Scripting. Cross Site Scripting ist ein Injektionsangriff, der es einem Angreifer ermöglicht, die Interaktionen eines Benutzers mit der anfälligen Anwendung zu beeinträchtigen. Das bedeutet, dass ein Angreifer potenziell alle sensiblen Daten, auf die der Browser des Benutzers zugreifen kann, lesen, verändern und übertragen kann. Der Angriff wird ausgeführt, indem JavaScript in die verwundbare Webanwendung injiziert wird, das dann im Browser des Benutzers ausgeführt wird. ZAP nennt zwei Arten von Cross Site Scripting. Persistentes und Reflected Cross Site Scritping. Persistentes Cross Site Scripting bedeutet, dass die JavaScript-Nutzdaten des Angreifers in einem dauerhaften Speicher (z.B. einer Datenbank) gespeichert werden. Die verwundbare Anwendung verwendet diesen persistenten Speicher, um eine Webseite (HTTP-Antwort) zu erstellen, die die JavaScript-Nutzdaten in HTML eingebettet enthält (<script ></script> ist ein HTML-Tag). Das bedeutet, dass jedes Mal, wenn diese Seite besucht wird, die JavaScript-Nutzlast ausgeführt wird. In unserem Fall wird jeder, der die Seite http://localhost:8080/posts?postId=1 besucht, angegriffen.
Sie können dies überprüfen, indem Sie eine JavaScript-Nutzlast wie <script>alert('xss')</script> über das Formular unter http://localhost:8080/posts?postId=1 eingeben. Jedes Mal, wenn Sie die URL aufrufen, erhalten Sie ein Popup-Fenster mit dem Text "xss", wie in Abbildung 4 dargestellt. Dies bestätigt, dass unser hinzugefügtes JavaScript auf dieser Seite ausgeführt wird.
[caption id="attachment_59676" align="alignnone" width="595"]
Abbildung 4: Cross-Site-Scripting-Angriff über /posts[/caption]
Reflektiertes Cross Site Scripting bedeutet, dass die Daten (der HTML-Code, der die eingebettete JavaScript-Nutzlast enthält), die von einer HTTP-Anfrage gesendet werden, der HTTP-Antwort der entsprechenden HTTP-Anfrage auf unsichere Weise hinzugefügt werden. Es wird keine dauerhafte Speicherung verwendet. Sie denken vielleicht, dass es nur möglich ist, Ihren eigenen Browser auf diese Weise anzugreifen. Es ist jedoch auch möglich, einen anderen Benutzer anzugreifen, indem Sie einen Link mit einer JavaScript-Nutzlast senden. Zum Beispiel, indem Sie jemandem eine E-Mail mit einer Nutzlast wie https://vulnerableapp.com/post?message=<script>alert('xss')</script> schicken. Wenn der Empfänger dieses Links darauf klickt, wird das JavaScript in seinem Browser ausgeführt. Der Fund von Reflected Cross Site Scripting in den ZAP-Ergebnissen ist ein falsches Positiv. Die JavaScript-Nutzdaten werden in der Antwort auf die Anfrage nicht reflektiert, da die Antwort auf die Anfrage eine Weiterleitung zu http://localhost:8080/posts?postId=1 ist. Die weitergeleitete Seite enthält die JavaScript-Nutzdaten. ZAP denkt, dass die umgeleitete Seite die HTTP-Antwort der HTTP-Anfrage ist. Das ist jedoch nicht der Fall.
Jetzt ist es an der Zeit, das Problem zu beheben. Es gibt zwei Dinge, die wir anwenden können, um dieses Problem zu vermeiden. Erstens sollten Sie die Eingaben des Benutzers immer validieren und zweitens bieten die meisten modernen Template-Engines Möglichkeiten zur Ausgabeverschlüsselung von benutzerkontrollierten Daten. Wenn Sie mehr über die Validierung von Eingaben erfahren möchten, sehen Sie sich dieses OWASP-Spickblatt an: Spickzettel zur Eingabeüberprüfung. Wir werden uns die Ausgabekodierung ansehen. Wenn wir uns den Code der Vorlage posts.html im Verzeichnis vulnerable-app/src/main/resources/templates/ ansehen, sehen wir den folgenden Code:
[caption id="attachment_59677" align="alignnone" width="682"]
Abbildung 5: Vorlage für Beiträge[/caption]
Die verwundbare Anwendung verwendet eine Template Engine namens Thymeleaf. Wenn wir die Dokumentation unter Dokumentation (3.2) besuchen, stellen wir fest, dass Thymeleaf standardmäßig HTML mit dem 'th:text' Tag kodiert. Das macht Cross Site Scripting, wie wir es gerade bei ZAP gefunden haben, unmöglich. In Zeile 12 der Posts-Vorlage (posts.html) verwendet die anfällige Anwendung jedoch 'th:utext', um Daten darzustellen. Der 'th:utext'-Tag rendert rohes HTML und da es sich bei den von diesem Tag gerenderten Daten um nicht überprüfte Benutzerdaten handelt, tritt das Problem des Cross Site Scripting auf. In diesem Fall ist die Lösung einfach. Ändern Sie das 'th:utext' in Zeile 12 in 'th:text'. Wenn wir uns nun den Quellcode der verwundbaren Webseite über den Browser ansehen, sehen wir nicht den Payload '<script>alert('xss')</script>', sondern '<script>alert('xss')</script>. Die Nutzlast '<script>alert('xss')</script>' ist ausgabeverschlüsselt. Dadurch wird der Browser daran gehindert, JavaScript über HTML-Konstrukte auszuführen. Beachten Sie, dass es wichtig ist, die richtige Ausgabekodierungsmethode für den jeweiligen Kontext zu verwenden. Weitere Informationen hierzu finden Sie im OWASP Cross Site Scripting Prevention Cheat Sheet.
Andere HOHE und MITTLERE Schwachstellen
Die zweite Art von High finding betrifft SQL-Einschleusung. Offenbar ist es möglich, die Datenbank der verwundbaren Webanwendung zu kompromittieren und die Authentifizierung über die Anmeldeseite mittels SQL Injection zu umgehen. Obwohl ZAP sie als zwei verschiedene SQL-Injections auflistet, handelt es sich um eine SQL-Injection, die je nach Nutzlast auf unterschiedliche Weise ausgenutzt werden kann. Es handelt sich um eine zusätzliche SQL-Injection zu derjenigen, die Semgrep im vorherigen Blog gefunden hat. Aus irgendeinem Grund hat OWASP ZAP die SQL Injection, die Semgrep gefunden hat, nicht gefunden, nämlich die SQL Injection in posts?postId=1. Wir werden im dritten Blog auf die Details der "/login" SQL Injection eingehen.
Auf der anderen Seite fand ZAP Schwachstellen, die Semgrep nicht fand. Dies macht deutlich, warum es wichtig ist, mehrere verschiedene Arten von Sicherheitstests zu verwenden, um möglichst genaue Ergebnisse zu erhalten. Nun werden wir kurz auf die mittleren Ergebnisse eingehen.
Die anfällige Webanwendung scheint keinen Schutz gegen CSRF zu bieten. Dies kann dazu führen, dass ein Angreifer unbeabsichtigte Aktionen im Namen des Benutzers durchführt. Zum Beispiel die unbeabsichtigte Überweisung von Geld auf ein Bankkonto.
ZAP glaubt auch, dass unsere Webanwendung einen Pufferüberlauf, einen Integer-Überlauf und einen Format-String-Fehler enthält. Diese Arten von Sicherheitslücken können zu Remotecodeausführung führen, was wirklich beängstigend ist. Denn das bedeutet, dass beliebiger Code auf dem angegriffenen Server ausgeführt werden kann und einem Angreifer die Kontrolle über den Server geben könnte.
Die Webanwendung verwendet einen unsicheren Kommunikationskanal, da sie HTTP anstelle von HTTPS verwendet. HTTP verschlüsselt die Kommunikation zwischen dem Server und dem Client nicht. Dies kann missbraucht werden durch einen Man-in-the-Middle-Angriff . Bei einem solchen Angriff kann der Angreifer alle Daten lesen, die zwischen einem Client und einem Server ausgetauscht werden. Der Angreifer könnte dies zum Beispiel nutzen, um Anmeldedaten zu sammeln.
Die letzte Entdeckung von ZAP, die wir besprechen werden, betrifft HTTP-Antwort-Header. In den Antworten der verwundbaren Anwendung fehlen HTTP-Sicherheits-Header. Die mittleren Ergebnisse betreffen das Fehlen eines Schutzes gegen Clickjacking und der Content Security Policy, die Cross Site Scripting eindämmen hilft. Die Art von Schwachstellen, vor denen diese HTTP-Sicherheitsheader schützen, können beispielsweise dazu missbraucht werden, eine Webanwendung zu verunstalten, Malware zu verbreiten oder den Benutzer zu unbeabsichtigten Aktionen zu verleiten.
Der nächste Schritt wäre die Überprüfung, ob es sich bei den von ZAP gefundenen Sicherheitslücken um echte Sicherheitslücken (True Positives) oder gar keine Sicherheitslücken (False Positives) handelt. Wir wissen bereits, dass das Cross Site Scripting und die SQL-Injection-Schwachstelle echte positive Ergebnisse sind. Was ist mit dem Rest? Versuchen Sie, es selbst herauszufinden. Wenn Sie es sofort wissen wollen, markieren Sie den Text in den Spoilern schwarz, indem Sie ihn auswählen.
<Spoiler>
Die Feststellungen zu CSRF, zur Verwendung von HTTP und zu fehlenden Sicherheits-Headern sind allesamt echte Positivbefunde. Die Feststellungen zum Pufferüberlauf, Format String Error und Integer-Überlauf sind Probleme, aber keine Sicherheitslücken. Sie können nicht ausgenutzt werden und sind Fehlalarme. Sie machen uns jedoch darauf aufmerksam, dass wir nicht über eine Eingabevalidierung und eine angemessene Fehlerbehandlung verfügen, und dies sollte behoben werden.
</Spoilers>
Eine umfassende Liste von Tools finden Sie unter: AppSecMap.
Damit ist dieser Blog beendet. Im nächsten Blog werden wir uns mit Interactive Application Security Testing (IAST) beschäftigen und erneut unsere anfällige Webanwendung testen. Wir sehen uns beim nächsten Mal!
Verfasst von
Maarten Plat
Unsere Ideen
Weitere Blogs
Contact



