Interaktion mit Webanwendungen (Requests)

CybersicherheitBeginner
Jetzt üben

Einführung

Willkommen zum Lab „Interaktion mit Webanwendungen“. In der Welt der Cybersicherheit und Web-Automatisierung ist die programmgesteuerte Interaktion mit Webanwendungen eine grundlegende Fähigkeit. Egal, ob Sie Daten scrapen, auf Schwachstellen testen oder sich wiederholende Aufgaben automatisieren möchten – Sie benötigen eine zuverlässige Methode zum Senden und Empfangen von HTTP-Anfragen.

In diesem Lab lernen Sie den Umgang mit der leistungsstarken Python-Bibliothek requests. Sie werden Skripte schreiben, um HTTP GET- und POST-Anfragen zu senden, wichtige Informationen aus Serverantworten zu extrahieren, Formularübermittlungen zu automatisieren und Session-Cookies zu verwalten, um den Authentifizierungsstatus aufrechtzuerhalten.

Im Vergleich zu rohen Sockets arbeitet requests auf einer höheren Abstraktionsebene. Es übernimmt viele HTTP-Details für Sie, wie etwa Header, Kodierung, Weiterleitungen und Cookies. Das macht es ideal für die Sicherheitsautomatisierung, bei der Sie sich mehr auf das Web-Verhalten und die Workflows konzentrieren als auf die Details einzelner Datenpakete.

HTTP GET-Anfragen senden

In diesem Schritt lernen Sie, wie Sie eine einfache HTTP GET-Anfrage mit Python senden. Die GET-Methode wird verwendet, um Daten von einer bestimmten Ressource anzufordern – ähnlich wie Ihr Webbrowser eine Webseite anfordert, wenn Sie eine URL eingeben.

Betrachten Sie dies als die einfachste Form der Web-Automatisierung: Fragen Sie eine Ressource ab und untersuchen Sie die Antwort. Viele Aufgaben im Bereich Aufklärung (Reconnaissance), Tests und Überwachung beginnen genau hier.

Stellen Sie zunächst sicher, dass Sie sich in Ihrem Projektverzeichnis befinden. Hier werden Sie alle Python-Skripte für dieses Lab erstellen.

cd ~/project

Erstellen wir nun ein Python-Skript, um eine GET-Anfrage an einen lokalen Webserver zu senden, der für Sie vorbereitet wurde. Verwenden Sie den Texteditor nano, um eine Datei namens get_request.py zu erstellen:

nano get_request.py

Geben Sie den folgenden Python-Code in den Editor ein:

import requests

url = 'http://127.0.0.1:5000/get'
response = requests.get(url)

print("Response Body:")
print(response.text)

Speichern Sie die Datei und beenden Sie den Editor (in nano drücken Sie Ctrl+O, Enter zum Speichern und Ctrl+X zum Beenden).

Der obige Code importiert die requests-Bibliothek, definiert die Ziel-URL und verwendet die Funktion requests.get(), um die Anfrage zu senden. Die Antwort des Servers wird in der Variablen response gespeichert, und wir geben den Rohtext des Antwortkörpers aus.

Führen Sie Ihr Skript mit dem Python-Interpreter aus:

python3 get_request.py

Sie sollten eine Ausgabe sehen, die in etwa so aussieht:

Response Body:
{"message":"GET request successful"}

HTTP-Status und Header extrahieren

In diesem Schritt lernen Sie, wie Sie detailliertere Informationen aus einer HTTP-Antwort extrahieren, insbesondere den Statuscode und die Header.

Der Antwortkörper ist nur ein Teil der Geschichte. Statuscodes geben an, wie der Server die Anfrage verstanden hat, und Header beschreiben Metadaten wie den Inhaltstyp (Content-Type), die Cache-Richtlinie, Cookies oder die Server-Software. Eine gute Automatisierung betrachtet alle drei Ebenen: Code, Header und Body.

Wenn ein Server auf eine HTTP-Anfrage antwortet, enthält er einen Statuscode (wie 200 für OK oder 404 für Not Found) sowie Header, die Metadaten über die Antwort liefern (wie den Inhaltstyp oder die Server-Software).

Erstellen Sie eine neue Datei namens check_status.py in Ihrem Projektverzeichnis:

nano check_status.py

Fügen Sie den folgenden Code zur Datei hinzu:

import requests

url = 'http://127.0.0.1:5000/get'
response = requests.get(url)

print(f"Status Code: {response.status_code}")

if response.status_code == 200:
    print("The request was successful!")

print("\nResponse Headers:")
print(f"Content-Type: {response.headers.get('Content-Type')}")
print(f"Server: {response.headers.get('Server')}")

Speichern Sie die Datei und beenden Sie den Editor.

In diesem Skript ruft response.status_code den ganzzahligen Statuscode ab, der vom Server zurückgegeben wurde. response.headers ist ein wörterbuchartiges Objekt, das alle vom Server zurückgesendeten HTTP-Header enthält. Wir verwenden die Methode .get(), um spezifische Header sicher zu extrahieren.

Führen Sie das Skript aus, um die extrahierten Informationen zu sehen:

python3 check_status.py

Ihre Ausgabe sollte wie folgt aussehen:

Status Code: 200
The request was successful!

Response Headers:
Content-Type: application/json
Server: Werkzeug/3.0.1 Python/3.10.12

Formularübermittlungen automatisieren (POST)

In diesem Schritt lernen Sie, wie Sie eine HTTP POST-Anfrage senden. Im Gegensatz zu GET-Anfragen, die zum Abrufen von Daten verwendet werden, dienen POST-Anfragen dazu, Daten an den Server zu senden. Dies wird häufig für das Absenden von Webformularen verwendet, beispielsweise für Anmeldedaten.

Diese Unterscheidung spiegelt die HTTP-Semantik wider. In der Praxis wird GET meist zum Lesen von Ressourcen verwendet, während POST oft für Aktionen genutzt wird, die Daten übermitteln oder den Zustand ändern. Das Verständnis dieses Unterschieds hilft Ihnen vorherzusagen, wie sich Anwendungen verhalten und wie Ihre Skripte mit ihnen interagieren sollten.

Wir schreiben ein Skript, um das Absenden eines Anmeldeformulars mit Benutzername und Passwort zu simulieren.

Erstellen Sie eine neue Datei namens post_request.py:

nano post_request.py

Geben Sie den folgenden Code ein:

import requests

url = 'http://127.0.0.1:5000/post'

## Define the form data as a dictionary
form_data = {
    'username': 'admin',
    'password': 'secret'
}

## Send the POST request with the data parameter
response = requests.post(url, data=form_data)

print(f"Status Code: {response.status_code}")
print(f"Response Body: {response.text}")

Speichern Sie die Datei und beenden Sie den Editor.

Hier definieren wir ein Wörterbuch namens form_data, das unsere Anmeldedaten enthält. Dann verwenden wir requests.post() und übergeben unser Wörterbuch an den Parameter data. Die requests-Bibliothek formatiert diese Daten automatisch als Standard-Webformularübermittlung.

Führen Sie das Skript aus, um das Formular abzusenden:

python3 post_request.py

Sie sollten eine erfolgreiche Anmeldebestätigung sehen:

Status Code: 200
Response Body: {"message":"Login successful"}

Sie können versuchen, das Passwort im Skript auf einen falschen Wert (wie wrongpass) zu ändern und es erneut auszuführen, um zu sehen, wie der Server mit einem 401 Unauthorized-Statuscode antwortet.

Session-Cookies verwalten

In diesem letzten Schritt lernen Sie, wie Sie Session-Cookies verwalten. HTTP ist ein zustandsloses Protokoll, was bedeutet, dass jede Anfrage unabhängig ist. Um sich an einen Benutzer zu erinnern, nachdem er sich angemeldet hat, verwenden Webanwendungen Cookies.

Wenn Sie requests.get() oder requests.post() direkt verwenden, werden Cookies nicht zwischen den Anfragen gespeichert. Um eine Sitzung aufrechtzuerhalten (z. B. angemeldet zu bleiben), müssen Sie ein Session-Objekt verwenden, das von der requests-Bibliothek bereitgestellt wird.

Erstellen Sie eine Datei namens session_request.py:

nano session_request.py

Fügen Sie den folgenden Code hinzu:

import requests

## Create a Session object
session = requests.Session()

login_url = 'http://127.0.0.1:5000/login'
profile_url = 'http://127.0.0.1:5000/profile'

print("Attempting to access profile BEFORE login...")
response1 = session.get(profile_url)
print(f"Status: {response1.status_code}, Body: {response1.text.strip()}")

print("\nLogging in to establish a session...")
## The session object will automatically store cookies returned by the server
session.post(login_url)

print("\nAttempting to access profile AFTER login...")
## The session object will automatically send the stored cookies with this request
response2 = session.get(profile_url)
print(f"Status: {response2.status_code}, Body: {response2.text.strip()}")

Speichern Sie die Datei und beenden Sie den Editor.

In diesem Skript erstellt requests.Session() eine persistente Sitzung. Wenn wir die POST-Anfrage an /login senden, setzt der Server ein Session-Cookie. Das Session-Objekt speichert dieses Cookie und fügt es automatisch in die nachfolgende GET-Anfrage an /profile ein, wodurch wir auf die geschützte Route zugreifen können.

Führen Sie das Skript aus:

python3 session_request.py

Beobachten Sie die Ausgabe. Sie werden sehen, dass der erste Versuch fehlschlägt, weil wir nicht angemeldet sind, aber der zweite Versuch erfolgreich ist, da das Session-Cookie automatisch verwaltet wurde:

Attempting to access profile BEFORE login...
Status: 401, Body: {"message":"Unauthorized"}

Logging in to establish a session...

Attempting to access profile AFTER login...
Status: 200, Body: {"message":"Welcome to your profile!"}

Zusammenfassung

Sie haben gelernt, wie Sie die Python-Bibliothek requests verwenden, um Web-Interaktionen zu automatisieren. Sie begannen mit dem Senden einfacher HTTP GET-Anfragen und dem Extrahieren wichtiger Metadaten wie Statuscodes und Header. Danach sind Sie dazu übergegangen, HTTP POST-Anfragen zu senden, um Formularübermittlungen zu automatisieren. Schließlich haben Sie gelernt, wie man Session-Objekte verwendet, um Cookies zu verwalten und den Authentifizierungsstatus über mehrere Anfragen hinweg aufrechtzuerhalten.

Diese Fähigkeiten bilden die Grundlage für viele fortgeschrittene Aufgaben im Bereich Web-Scraping, API-Integration und automatisierte Sicherheitstests.