Prv8 Shell
Server : Apache
System : Linux ecngx264.inmotionhosting.com 4.18.0-553.77.1.lve.el8.x86_64 #1 SMP Wed Oct 8 14:21:00 UTC 2025 x86_64
User : lonias5 ( 3576)
PHP Version : 7.3.33
Disable Function : NONE
Directory :  /proc/self/root/proc/thread-self/root/opt/sharedrads/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/self/root/proc/thread-self/root/opt/sharedrads/cmspass.py
#!/usr/lib/rads/venv/bin/python3
"""Scans a cPanel account for WordPress and Joomla! configuration files, then
uses whmapi1 to reset database passwords to match what was found in them.
This script logs to /var/log/messages"""

import subprocess
import re
import sys
from argparse import ArgumentParser
from pathlib import Path
import rads
import logging
from logging.handlers import SysLogHandler
from cpapis import whmapi1, CpAPIError

WP_CONF = re.compile(r"DB_(USER|PASSWORD).*['\"](.+)['\"]")
JM_CONF = re.compile(r"\b(user|password) = '(.+)'")


def setup_logging() -> logging.Logger:
    logger = logging.getLogger('cmspass.py')
    logger.setLevel(logging.DEBUG)
    out_fmt = logging.Formatter(fmt='%(levelname)s: %(message)s')
    log_fmt = logging.Formatter(fmt='cmspass.py: %(levelname)s: %(message)s')
    stdout = logging.StreamHandler(stream=sys.stdout)
    stdout.setFormatter(out_fmt)
    stdout.setLevel(logging.DEBUG)
    logger.addHandler(stdout)
    syslog = SysLogHandler(address='/dev/log')
    syslog.setFormatter(log_fmt)
    syslog.setLevel(logging.WARNING)
    logger.addHandler(syslog)
    return logger


def conf_parse(regex: re.Pattern, path: Path) -> tuple[str | None, str | None]:
    """Will parse db conf variables"""
    db_user, db_pass = None, None
    with open(path, encoding='utf-8') as file:
        for line in file:
            if match := regex.search(line):
                key, val = match.groups()
                key: str
                val: str
                if key.lower() == 'user':
                    db_user = val
                elif key.lower() == 'password':
                    db_pass = val
    return db_user, db_pass


def set_pass(logger: logging.Logger, cpuser: str, db_user: str, db_pass: str):
    """Will pass the reset variables to the cPanel API"""
    if db_user is None or db_pass is None:
        return
    try:
        whmapi1(
            'set_mysql_password',
            args={'cpuser': cpuser, 'user': db_user, 'password': db_pass},
            check=True,
        )
    except CpAPIError as exc:
        logger.error("Failed to reset password for %s: %s", db_user, exc)
    else:
        logger.warning("Reset password for %s", db_user)


def parse_args() -> str:
    """Will parse input for user and ensure the user exists"""
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('-u', '--user', required=True, help='cPanel username')
    user = parser.parse_args().user
    if not rads.cpuser_safe(user):
        sys.exit(f"{user} does not exist or is restricted")
    return user


def find_files(homedir: str) -> list[Path]:
    """Find all config files"""
    # fmt: off
    cmd = [
        'find', homedir, '-not', '(', '-path', f"{homedir}/mail", '-prune', ')',
        '(', '-name', 'wp-config.php', '-o', '-name', 'configuration.php', ')',
        '-type', 'f', '-print0',
    ]
    # fmt: on
    ret = subprocess.run(
        cmd, stdout=subprocess.PIPE, encoding='utf-8', check=False
    )
    return [Path(x) for x in ret.stdout.split('\0') if x]


def conf_is_joomla(path: Path):
    if path.name != 'configuration.php':
        return False
    with open(path, encoding='utf-8') as conf:
        for line in conf:
            if 'class JConfig' in line:
                return True
    return False


def main():
    user = parse_args()
    logger = setup_logging()
    try:
        homedir = rads.get_homedir(user)
    except rads.CpuserError as exc:
        sys.exit(exc)
    for path in find_files(homedir):
        db_user, db_pass = None, None
        if path.name == 'wp-config.php':
            logger.debug('Scanning %s', path)
            db_user, db_pass = conf_parse(WP_CONF, path)
        elif conf_is_joomla(path):
            logger.debug('Scanning %s', path)
            db_user, db_pass = conf_parse(JM_CONF, path)
        if db_user and db_pass:
            set_pass(logger, user, db_user, db_pass)


if __name__ == "__main__":
    main()

@StableExploit - 2025