diff --git a/.gitignore b/.gitignore index adce3c8..5b05426 100644 --- a/.gitignore +++ b/.gitignore @@ -2,13 +2,15 @@ __pycache__/ *.py[cod] *.egg-info/ -dist/ -build/ -.eggs/ .venv/ venv/ env/ +# PyInstaller build artifacts +build/ +dist/ +*.spec + # Logs (scan logs from the tool) SysMonitorLogs/ *.log diff --git a/README.md b/README.md index f094e02..1f8e326 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ | ๐Ÿ—‚๏ธ **File Scan** | Scans key folders (`ProgramData`, `Public`, `Program Files`, `Temp`) for malicious files | | ๐Ÿ”‘ **Registry Scan** | Detects suspicious startup entries & restores Windows Defender exclusions | | โฐ **Scheduled Task Scan** | Detects malicious scheduled tasks (including English-word deception) | -| โš™๏ธ **Process Scan** | Identifies and kills malicious processes | +| โš™๏ธ **Process Scan** | Identifies and kills malicious processes (`Get-Process`, no deprecated `wmic`) | | ๐ŸŒ **Network Scan** | Flags connections to known mining pools / C2 servers | -| ๐Ÿ”ค **Random-Name Checker** | Detects virus-like random filenames (e.g. `UT7ejTkn`, `5ghAHv`) | +| ๐Ÿ”ค **Random-Name Checker** | Detects virus-like random filenames | | โ™ป๏ธ **Post-Restart Compare** | Compares logs after reboot to detect old/new viruses | | ๐Ÿงน **Auto-Cleanup** | Removes autostart when system is confirmed clean | | ๐Ÿ’พ **Scan Logs** | Saves detailed scan & cleanup records to `C:\SysMonitorLogs` | @@ -29,6 +29,24 @@ --- +## โœ… v1.0.1 Fixes + +This release fixes several issues found in v1.0.0: + +| Fix | Description | +|-----|-------------| +| ๐ŸŸข **AweSun False Positive** | Removed AweSun (Sunlogin remote control) from malicious keywords; added to whitelist | +| ๐Ÿ”ง **Process Scan Overhaul** | Replaced deprecated `wmic` with PowerShell `Get-Process` (removed on Win 10/11) | +| ๐Ÿ—‘๏ธ **Effective Deletion/Kill** | Fixed `_found_malicious_files` / `_found_malicious_processes` not being passed โ€” now uses global variables | +| ๐Ÿ“ **Path Fix** | `WORK_DIR` now uses script directory (`os.path.dirname(os.path.abspath(__file__))`) instead of hardcoded path | +| ๐Ÿ“ **Expanded Whitelist** | Added AweSun, Thunder, PalmInput, Wujie, CrystalDisk, and system processes to avoid false positives | +| ๐Ÿšซ **Path Whitelist** | Skips scanning legitimate dirs (AweSun, CrystalDisk, Thunder, PalmInput, Wujie) | +| ๐Ÿ”‡ **Silent Errors** | Added `2>nul` to reg/schtasks commands to suppress "path not found" errors | +| ๐Ÿ” **Registry Scan Fix** | Only outputs suspicious registry items (no more repeated spam) | +| ๐ŸŽฒ **Random-Name Tuning** | Only checks `.exe/.dll/.dat/.tmp/.sys/.bin`; whitelisted names not flagged | + +--- + ## ๐Ÿš€ Quick Start ### Prerequisites @@ -57,6 +75,14 @@ python code/sys_monitor.py python code/BootVerify.py ``` +### Rebuild the EXE + +```powershell +# Rebuild WMTR_MAIN.exe from source +cd code +pyinstaller --onefile --name WMTR_MAIN --console WMTR.py +``` + --- ## ๐Ÿ“ฆ Project Structure @@ -91,6 +117,12 @@ Windows-Mining-Trojan-Remover/ - **Mining pools / C2**: kryptex, gleeze, 176.96.137.253, etc. - **English-word deception**: fake task names like "Efficiently Achieve Analysis", "Windows System Health" +### Whitelist (to avoid false positives) +- AweSun / AweSun Guard (Sunlogin) +- Thunder (่ฟ…้›ท), PalmInput (ๆ‰‹ๅฟƒ่พ“ๅ…ฅๆณ•), Wujie (ๆ— ็•Œๆต่งˆๅ™จ) +- CrystalDiskInfo / CrystalDiskMark +- Common system processes (svchost, lsass, winlogon, etc.) + --- ## ๐Ÿ“„ License diff --git a/WMTR_MAIN.exe b/WMTR_MAIN.exe index 49fafd4..0b7ac4e 100644 Binary files a/WMTR_MAIN.exe and b/WMTR_MAIN.exe differ diff --git a/code/WMTR.py b/code/WMTR.py index d57308e..2707bc1 100644 --- a/code/WMTR.py +++ b/code/WMTR.py @@ -19,59 +19,133 @@ import subprocess import datetime import shutil import ctypes +import re # ============ Configuration ============ -WORK_DIR = r"C:\Windows-Mining-Trojan-Remover" +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +WORK_DIR = SCRIPT_DIR LOG_DIR = r"C:\SysMonitorLogs" INITIAL_LOG = os.path.join(LOG_DIR, "WMTR_initial_scan.log") COMPARE_LOG = os.path.join(LOG_DIR, "WMTR_compare.log") SYSMONITOR_EXE = os.path.join(WORK_DIR, "sys_monitor.exe") WMTR_EXE = os.path.join(WORK_DIR, "WMTR.exe") -# Known malicious keywords (including English-word deception) +# Known malicious keywords (AweSun removed - legitimate software) MALICIOUS_KEYWORDS = [ # Mining trojans 'UT7ejTkn', 'WE93mndC', 'WpSJj0lv', 'YRbL1xSX', 'RuntimeHost', 'RuntimeTask', '8B86CBC', '2FA7F989', 'ABE94A11', '15205438', 'D3F4E2A1', '50AB775E', 'proxies-peer', '15AB6CF5', 'B95EB893', '5ghAHv', 'jHkYtN', 'zQM241sm', - 'nAumBAO1', 'lw5ypO', 'P41H56Vb', 'WE93mndC', 'KxDQmm', 'ccv', 'mzcv', + 'nAumBAO1', 'lw5ypO', 'P41H56Vb', 'KxDQmm', 'ccv', 'mzcv', 'lolMiner', 'SRBMiner', 'gminer', 'miniZ', 'SecurityHealthHost', '0AzjkAEd', '6E7B6FD3', 'Diagnostics.Client', 'SimpleRunPE', - # Remote control + # Remote control (malicious variants) 'ScreenConnect', 'Windows VC', 'rasedy', 'ConnectWise', # Mining pools / C2 'kryptex', 'gleeze', '176.96.137.253', '217.216.109.4', - # English-word deception (fake normal English task names) + # English-word deception (fake normal task names) 'Efficiently Achieve Analysis', 'productivity Deadlines Priority', 'Windows System Health', 'Workflow Contingency', 'Elevate Plans Interface', ] +# Whitelist - legitimate program names (case insensitive) +WHITELIST_NAMES = { + # System + 'securityhealth', 'securityhealthsystray', 'runtimebroker', 'svchost', + 'services', 'lsass', 'winlogon', 'explorer', 'taskhostw', 'dwm', + 'csrss', 'smss', 'wininit', 'conhost', 'system', 'registry', + 'ctfmon', 'sihost', 'fontdrvhost', 'dllhost', 'spoolsv', + # Legitimate software + 'awesun', 'awesun_guard', 'onedrive', 'onedrivesetup', 'thunder', + 'palminput', 'palminputstartup', 'wujie', 'msedge', 'microsoftedge', + # CrystalDisk + 'diskmark64', 'diskspd64', 'diskspd64l', +} + +# Whitelist path prefixes - skip these directories entirely +WHITELIST_PATHS = [ + r'C:\Windows\System32', + r'C:\Windows\SysWOW64', + r'C:\Windows\Microsoft.NET', + r'C:\Program Files\WindowsApps', + r'C:\Program Files\Common Files\microsoft shared', + r'C:\Program Files\Microsoft Office', + r'C:\Program Files (x86)\Microsoft', + r'C:\Program Files (x86)\Thunder Network', + r'D:\Program Files (x86)\PalmInput', + r'D:\leidian\wujie', + r'C:\Program Files\CrystalDiskInfo', + r'C:\Program Files\CrystalDiskMark', + r'C:\Program Files\Oray\AweSun', + r'C:\ProgramData\Oray\AweSun', +] + +# Storage for detected items +_found_malicious_files = [] +_found_malicious_processes = [] + def is_admin(): """Check if running with admin/NT/SYSTEM privileges""" try: - # Check if SYSTEM if 'SYSTEM' in os.environ.get('USERNAME', '').upper(): return True, 'SYSTEM' - # Check if admin return ctypes.windll.shell32.IsUserAnAdmin() != 0, 'ADMIN' except Exception: return False, 'UNKNOWN' -def is_random_name(name): - """Check if name looks like a virus random name (e.g. 5ghAHv, UT7ejTkn)""" - base = os.path.splitext(name)[0] - if len(base) < 6 or len(base) > 12: +def is_whitelisted_path(path): + """Check if path is in whitelist""" + if not path: return False + path_lower = path.lower() + for wp in WHITELIST_PATHS: + if wp.lower() in path_lower: + return True + return False + + +def is_whitelisted_name(name): + """Check if filename is in whitelist""" + if not name: + return False + base = os.path.splitext(name)[0].lower() + return base in WHITELIST_NAMES + + +def is_random_name(name): + """Check if name looks like a random virus name (whitelist excluded)""" + if not name: + return False + + base = os.path.splitext(name)[0] + + # Skip if whitelisted + if is_whitelisted_name(name): + return False + + # Only check executable/dll types + ext = os.path.splitext(name)[1].lower() + if ext not in ['.exe', '.dll', '.dat', '.tmp', '.sys', '.bin']: + return False + + # Length check + if len(base) < 6 or len(base) > 14: + return False + + # Must have mixed case and digits has_upper = any(c.isupper() for c in base) has_lower = any(c.islower() for c in base) has_digit = any(c.isdigit() for c in base) + if has_upper and has_lower and has_digit: + # Low vowel ratio (random names typically have few vowels) vowels = 'aeiouAEIOU' vowel_count = sum(1 for c in base if c in vowels) - if vowel_count / len(base) < 0.25: + if vowel_count / len(base) < 0.2: return True + return False @@ -80,6 +154,7 @@ def now(): def run_cmd(cmd, timeout=30): + """Execute command and return output""" try: result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout, errors='ignore') @@ -96,7 +171,6 @@ def log_write(f, section, content): # ============ 1. Scan Phase ============ -# ๅŠจๆ€ๅ…ณ้”ฎ่ฏ๏ผšไปŽๅฏๅŠจ้กนๆๅ–ๆ–‡ไปถๅๅนถๆทปๅŠ ๅˆฐๅ…ณ้”ฎ่ฏๅˆ—่กจ def extract_startup_keywords(): """Scan startup items, extract file names, dynamically add to keywords""" added = [] @@ -106,38 +180,38 @@ def extract_startup_keywords(): r'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run', r'HKCU\Software\Microsoft\Windows\CurrentVersion\Run', r'HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', - r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices', - r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce', ] + for k in keys: - out = run_cmd(f'reg query "{k}"') - # ๆๅ–ๆ‰€ๆœ‰ exe/dll ๆ–‡ไปถๅ + out = run_cmd(f'reg query "{k}" 2>nul') + if not out or 'ERROR' in out: + continue + for line in out.split('\n'): - # ๆๅ–่ทฏๅพ„ไธญ็š„ๆ–‡ไปถๅ - import re as _re - exes = _re.findall(r'[\\/]([A-Za-z0-9_]+\.(?:exe|dll|bat|cmd|ps1))', line, _re.IGNORECASE) + exes = re.findall(r'[\\/]([A-Za-z0-9_]+\.(?:exe|dll|bat|cmd|ps1))', line, re.IGNORECASE) for exe in exes: - base = os.path.splitext(exe)[0] - if base.lower() not in [k.lower() for k in MALICIOUS_KEYWORDS]: - # ๅชๆทปๅŠ ็œ‹่ตทๆฅๅฏ็–‘็š„๏ผˆ้šๆœบๅๆˆ–ไธๅœจ็ณป็ปŸๆญฃๅธธ็จ‹ๅบไธญ็š„๏ผ‰ - if is_random_name(exe) or base.lower() not in ['securityhealth', 'awe sun', 'onedrive', 'thunder', 'palminput', 'wujie', 'msedge']: + if not is_whitelisted_name(exe) and is_random_name(exe): + base = os.path.splitext(exe)[0] + if base.lower() not in [k.lower() for k in MALICIOUS_KEYWORDS]: MALICIOUS_KEYWORDS.append(base) added.append(f"Dynamic keyword added: {base}") return '\n'.join(added) if added else "No new dynamic keywords" - - def scan_files(): """Scan key folders for malicious files""" + global _found_malicious_files + _found_malicious_files = [] results = [] + base_dirs = [ r'C:\ProgramData', r'C:\Users\Public', - r'C:\Program Files (x86)', - r'C:\Program Files', r'C:\Windows\Temp', + r'C:\Program Files', + r'C:\Program Files (x86)', ] + for base in base_dirs: if not os.path.exists(base): continue @@ -147,19 +221,39 @@ def scan_files(): if depth > 4: dirs[:] = [] continue + + if is_whitelisted_path(root): + continue + for item in dirs + files: full = os.path.join(root, item) - if any(k.lower() in (item + full).lower() for k in MALICIOUS_KEYWORDS): + + if is_whitelisted_path(full): + continue + if is_whitelisted_name(item): + continue + + # Check for malicious keywords + is_malicious = False + for kw in MALICIOUS_KEYWORDS: + if kw.lower() in item.lower() or kw.lower() in full.lower(): + is_malicious = True + break + + if is_malicious: results.append(f"MALICIOUS: {full}") - elif is_random_name(item) and item.lower().endswith(('.exe', '.dll', '.dat', '.tmp')): + _found_malicious_files.append(full) + elif is_random_name(item): results.append(f"RANDOM-NAME: {full}") + except Exception: pass + return '\n'.join(results) if results else "No malicious files found" def scan_registry(): - """Scan registry startup items, dynamically add found paths to keywords""" + """Scan registry startup items""" results = [] keys = [ r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', @@ -167,22 +261,23 @@ def scan_registry(): r'HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run', r'HKCU\Software\Microsoft\Windows\CurrentVersion\Run', r'HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce', - r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices', - r'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce', ] + for k in keys: - out = run_cmd(f'reg query "{k}"') - if any(m.lower() in out.lower() for m in MALICIOUS_KEYWORDS): - results.append(f"REGISTRY SUSPICIOUS [{k}]: {out}") - # Dynamically extract file names from startup paths - import re as _re - for line in out.split('\n'): - exes = _re.findall(r'[\\/]([A-Za-z0-9_]+\.(?:exe|dll|bat|cmd|ps1))', line, _re.IGNORECASE) - for exe in exes: - base = os.path.splitext(exe)[0] - if is_random_name(exe) and base.lower() not in [k.lower() for k in MALICIOUS_KEYWORDS]: - MALICIOUS_KEYWORDS.append(base) - results.append(f"DYNAMIC keyword from startup: {base}") + out = run_cmd(f'reg query "{k}" 2>nul') + if not out or 'ERROR' in out: + continue + + # Check if any malicious keyword is in the registry output + found = False + for kw in MALICIOUS_KEYWORDS: + if kw.lower() in out.lower(): + found = True + break + + if found: + results.append(f"REGISTRY SUSPICIOUS [{k}]:\n{out}") + return '\n'.join(results) if results else "Registry startup items clean" @@ -191,26 +286,64 @@ def scan_tasks(): results = [] tasks_dir = r'C:\Windows\System32\Tasks' if os.path.exists(tasks_dir): - for root, dirs, files in os.walk(tasks_dir): - for f in files: - full = os.path.join(root, f) - try: - with open(full, 'r', encoding='utf-8', errors='ignore') as fh: - content = fh.read() - if any(k.lower() in content.lower() for k in MALICIOUS_KEYWORDS): - results.append(f"TASK SUSPICIOUS: {full}") - except Exception: - pass + try: + for root, dirs, files in os.walk(tasks_dir): + # Limit depth + depth = root[len(tasks_dir):].count(os.sep) + if depth > 3: + continue + for f in files: + full = os.path.join(root, f) + try: + with open(full, 'r', encoding='utf-8', errors='ignore') as fh: + content = fh.read() + for kw in MALICIOUS_KEYWORDS: + if kw.lower() in content.lower(): + results.append(f"TASK SUSPICIOUS: {full}") + break + except Exception: + pass + except Exception: + pass + return '\n'.join(results) if results else "Scheduled tasks clean" def scan_processes(): """Scan running malicious processes""" + global _found_malicious_processes + _found_malicious_processes = [] results = [] - out = run_cmd('wmic process get name,processid,executablepath /format:csv') + + # Use PowerShell Get-Process (more reliable than wmic which is deprecated) + out = run_cmd('powershell -NoProfile -Command "Get-Process | ForEach-Object { $_.ProcessName + \'|\' + $_.Id + \'|\' + $_.Path }"') + for line in out.split('\n'): - if any(k.lower() in line.lower() for k in MALICIOUS_KEYWORDS): - results.append(f"PROCESS SUSPICIOUS: {line.strip()}") + if '|' not in line: + continue + parts = line.split('|') + if len(parts) < 2: + continue + + name = parts[0].strip() + pid = parts[1].strip() if len(parts) > 1 else '' + path = parts[2].strip() if len(parts) > 2 else '' + + # Skip whitelisted names + if is_whitelisted_name(name): + continue + + # Check if malicious + is_malicious = False + for kw in MALICIOUS_KEYWORDS: + if kw.lower() in name.lower() or (path and kw.lower() in path.lower()): + is_malicious = True + break + + if is_malicious: + results.append(f"PROCESS SUSPICIOUS: {name}, {path}, {pid}") + _found_malicious_processes.append({'name': name, 'path': path, 'pid': pid}) + return '\n'.join(results) if results else "No malicious processes" @@ -219,8 +352,10 @@ def scan_network(): results = [] out = run_cmd('netstat -ano') for line in out.split('\n'): - if any(p in line for p in ['kryptex', 'gleeze', 'rasedy', '176.96.137.253', '217.216.109.4', ':4041', ':8041', ':8443']): - results.append(f"NETWORK SUSPICIOUS: {line.strip()}") + for kw in ['kryptex', 'gleeze', 'rasedy', '176.96.137.253', '217.216.109.4', ':4041', ':8041', ':8443']: + if kw.lower() in line.lower(): + results.append(f"NETWORK SUSPICIOUS: {line.strip()}") + break return '\n'.join(results) if results else "No malicious network connections" @@ -228,21 +363,47 @@ def scan_network(): def kill_processes(): """Kill malicious processes""" - procs = ['UT7ejTkn', 'WE93mndC', 'WpSJj0lv', 'YRbL1xSX', 'RuntimeHost', - 'RuntimeTask', 'ScreenConnect', 'lolMiner', 'SRBMiner', 'gminer', - 'miniZ', 'lw5ypO', 'P41H56Vb', 'KxDQmm', 'ccv', 'mzcv'] + global _found_malicious_processes killed = [] - for p in procs: - result = run_cmd(f'taskkill /F /IM {p}.exe 2>nul') + + # Use the detected processes from scan + for proc in _found_malicious_processes: + pid = proc.get('pid', '') + if pid and pid.isdigit(): + result = run_cmd(f'taskkill /F /PID {pid} 2>nul') + if 'SUCCESS' in result.upper() or 'ๆˆๅŠŸ' in result: + killed.append(f"{proc['name']} (PID: {pid})") + + # Also try killing by name (fallback) + for kw in ['UT7ejTkn', 'WE93mndC', 'WpSJj0lv', 'YRbL1xSX', 'RuntimeHost', + 'RuntimeTask', 'ScreenConnect', 'lolMiner', 'SRBMiner', 'gminer', + 'miniZ', 'lw5ypO', 'P41H56Vb', 'KxDQmm', 'ccv', 'mzcv']: + result = run_cmd(f'taskkill /F /IM {kw}.exe 2>nul') if 'SUCCESS' in result.upper() or 'ๆˆๅŠŸ' in result: - killed.append(f"{p}.exe") + killed.append(f"{kw}.exe") + return '\n'.join(killed) if killed else "No malicious processes to kill" def delete_files(): - """Delete malicious files""" + """Delete malicious files found during scan""" + global _found_malicious_files deleted = [] - mal_dirs = [ + + for filepath in _found_malicious_files: + try: + if os.path.exists(filepath): + if os.path.isfile(filepath): + os.remove(filepath) + deleted.append(f"Deleted: {filepath}") + elif os.path.isdir(filepath): + shutil.rmtree(filepath, ignore_errors=True) + deleted.append(f"Deleted dir: {filepath}") + except Exception as e: + deleted.append(f"Delete failed: {filepath} | {e}") + + # Also delete known malicious directories + known_dirs = [ r'C:\ProgramData\UT7ejTkn.exe', r'C:\ProgramData\TfuSTvhb', r'C:\ProgramData\0AzjkAEd', @@ -253,7 +414,8 @@ def delete_files(): r'C:\Program Files (x86)\Windows VC', r'C:\Program Files (x86)\Common Files\Microsoft Shared\2FA7F989', ] - for d in mal_dirs: + + for d in known_dirs: if os.path.exists(d): try: if os.path.isfile(d): @@ -263,6 +425,7 @@ def delete_files(): deleted.append(f"Deleted: {d}") except Exception as e: deleted.append(f"Delete failed: {d} | {e}") + return '\n'.join(deleted) if deleted else "No malicious files to delete" @@ -270,15 +433,15 @@ def restore_registry(): """Restore registry (remove malicious exclusions and startup items)""" restored = [] cmds = [ - 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths" /f', - 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes" /f', - 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Extensions" /f', - 'reg delete "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Exclusions" /f', - 'schtasks /delete /tn "Efficiently Achieve Analysis Your" /f', - 'schtasks /delete /tn "productivity Deadlines Priority" /f', - 'schtasks /delete /tn "Windows System Health" /f', - 'schtasks /delete /tn "Workflow Contingency Delegation With Maximum" /f', - 'schtasks /delete /tn "Elevate Plans Interface productivity Organize" /f', + 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Paths" /f 2>nul', + 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Processes" /f 2>nul', + 'reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions\\Extensions" /f 2>nul', + 'reg delete "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Exclusions" /f 2>nul', + 'schtasks /delete /tn "Efficiently Achieve Analysis Your" /f 2>nul', + 'schtasks /delete /tn "productivity Deadlines Priority" /f 2>nul', + 'schtasks /delete /tn "Windows System Health" /f 2>nul', + 'schtasks /delete /tn "Workflow Contingency Delegation With Maximum" /f 2>nul', + 'schtasks /delete /tn "Elevate Plans Interface productivity Organize" /f 2>nul', ] for cmd in cmds: run_cmd(cmd) @@ -301,15 +464,15 @@ def restore_security(): # ============ 3. Autostart Setup ============ def setup_autostart(): - """Setup sys_monitor and WMTR autostart (add 2 registry Run entries each)""" + """Setup sys_monitor and WMTR autostart""" added = [] if os.path.exists(SYSMONITOR_EXE): - run_cmd(f'reg add "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /t REG_SZ /d "{SYSMONITOR_EXE}" /f') - run_cmd(f'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /t REG_SZ /d "{SYSMONITOR_EXE}" /f') + run_cmd(f'reg add "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /t REG_SZ /d "{SYSMONITOR_EXE}" /f 2>nul') + run_cmd(f'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /t REG_SZ /d "{SYSMONITOR_EXE}" /f 2>nul') added.append("Added SysMonitor to HKLM/HKCU Run") if os.path.exists(WMTR_EXE): - run_cmd(f'reg add "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /t REG_SZ /d "{WMTR_EXE}" /f') - run_cmd(f'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /t REG_SZ /d "{WMTR_EXE}" /f') + run_cmd(f'reg add "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /t REG_SZ /d "{WMTR_EXE}" /f 2>nul') + run_cmd(f'reg add "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /t REG_SZ /d "{WMTR_EXE}" /f 2>nul') added.append("Added WMTR to HKLM/HKCU Run") return '\n'.join(added) if added else "Autostart setup complete" @@ -317,10 +480,10 @@ def setup_autostart(): def remove_autostart(): """Remove autostart for both exe when confirmed clean""" removed = [] - run_cmd('reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /f') - run_cmd('reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /f') - run_cmd('reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /f') - run_cmd('reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /f') + run_cmd('reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /f 2>nul') + run_cmd('reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "SysMonitor" /f 2>nul') + run_cmd('reg delete "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /f 2>nul') + run_cmd('reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "WMTR" /f 2>nul') removed.append("Removed SysMonitor and WMTR autostart from registry") return '\n'.join(removed) @@ -329,6 +492,11 @@ def remove_autostart(): def save_initial_log(): """Save initial scan record""" + try: + os.makedirs(LOG_DIR, exist_ok=True) + except Exception: + pass + with open(INITIAL_LOG, 'w', encoding='utf-8') as f: f.write(f"WMTR Initial Scan Record\nTime: {now()}\n") log_write(f, "1. Malicious File Scan", scan_files()) @@ -350,11 +518,14 @@ def compare_logs(): results = [] if not os.path.exists(LOG_DIR): return "Log directory does not exist" + logs = [f for f in os.listdir(LOG_DIR) if f.startswith('continuous_monitor_')] if not logs: return "No monitor logs found" - latest = max(logs, key=lambda f: (os.path.getmtime(os.path.join(LOG_DIR, f)), os.path.getsize(os.path.join(LOG_DIR, f)))) + + latest = max(logs, key=lambda f: os.path.getmtime(os.path.join(LOG_DIR, f))) latest_path = os.path.join(LOG_DIR, latest) + with open(latest_path, 'r', encoding='utf-8') as f: latest_content = f.read() @@ -398,10 +569,15 @@ def random_name_checker(): for base in scan_dirs: if not os.path.exists(base): continue - for root, dirs, files in os.walk(base): - for item in dirs + files: - if is_random_name(item): - results.append(f"Random name: {os.path.join(root, item)}") + try: + for root, dirs, files in os.walk(base): + if is_whitelisted_path(root): + continue + for item in dirs + files: + if not is_whitelisted_name(item) and is_random_name(item): + results.append(f"Random name: {os.path.join(root, item)}") + except Exception: + pass return '\n'.join(results) if results else "No random-named files found" @@ -448,43 +624,39 @@ def main(): return # First run mode - # Step 0: Scan startup items FIRST to dynamically add keywords print("\n[0/8] Scanning startup items (dynamic keyword extraction)...") - dyn = extract_startup_keywords() - print(dyn) + print(extract_startup_keywords()) print(scan_registry()) print("\n[1/8] Scanning malicious files...") print(scan_files()) + print("\n[2/8] Scanning scheduled tasks...") print(scan_tasks()) + print("\n[3/8] Scanning malicious processes...") print(scan_processes()) + print("\n[4/8] Killing malicious processes...") print(kill_processes()) + print("\n[5/8] Deleting malicious files...") print(delete_files()) + print("\n[6/8] Restoring registry + security software...") print(restore_registry()) print(restore_security()) - # Setup autostart print("\n[7/8] Setting up autostart...") print(setup_autostart()) - # Save initial log print("\n[8/8] Saving initial scan record...") - - # Save initial log - print("\nSaving initial scan record...") log_file = save_initial_log() print(f"Log saved: {log_file}") - # Random name check print("\nRandom name checker...") print(random_name_checker()) - # Ask to restart print("\n" + "=" * 60) choice = input("Restart now? (y/n): ").strip().lower() if choice == 'y':