216 lines
8.1 KiB
PHP
Executable File
216 lines
8.1 KiB
PHP
Executable File
|
|
<?php
|
|
header('Content-Type: application/json');
|
|
header('Access-Control-Allow-Origin: *');
|
|
session_start();
|
|
|
|
$action = $_GET['action'] ?? $_POST['action'] ?? '';
|
|
|
|
switch ($action) {
|
|
case 'exec':
|
|
$command = $_POST['command'] ?? '';
|
|
$cwd = $_POST['cwd'] ?? '/opt/wevads';
|
|
|
|
if (empty($command)) {
|
|
echo json_encode(['success' => false, 'error' => 'No command']);
|
|
exit;
|
|
}
|
|
|
|
// Commandes bloquées
|
|
$blocked = ['rm -rf /', 'rm -rf /*', 'mkfs', 'dd if=/dev', ':(){', '> /dev/sda'];
|
|
foreach ($blocked as $b) {
|
|
if (stripos($command, $b) !== false) {
|
|
echo json_encode(['success' => false, 'error' => 'Commande bloquée']);
|
|
exit;
|
|
}
|
|
}
|
|
|
|
if (!is_dir($cwd)) $cwd = '/opt/wevads';
|
|
|
|
$descriptors = [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
|
|
$env = ['PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', 'HOME' => '/root', 'TERM' => 'xterm-256color'];
|
|
|
|
$process = proc_open($command, $descriptors, $pipes, $cwd, $env);
|
|
if (!is_resource($process)) {
|
|
echo json_encode(['success' => false, 'error' => 'Cannot execute']);
|
|
exit;
|
|
}
|
|
|
|
fclose($pipes[0]);
|
|
stream_set_timeout($pipes[1], 30);
|
|
stream_set_timeout($pipes[2], 30);
|
|
$stdout = stream_get_contents($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
$exitCode = proc_close($process);
|
|
|
|
echo json_encode(['success' => true, 'stdout' => $stdout, 'stderr' => $stderr, 'exitCode' => $exitCode, 'cwd' => $cwd]);
|
|
break;
|
|
|
|
case 'scan':
|
|
// Scan système complet
|
|
$scan = [
|
|
'hostname' => gethostname(),
|
|
'ip' => $_SERVER['SERVER_ADDR'] ?? '95.216.167.89',
|
|
'os' => php_uname(),
|
|
'php' => PHP_VERSION,
|
|
'uptime' => trim(shell_exec('uptime -p 2>/dev/null') ?: 'N/A'),
|
|
'load' => sys_getloadavg(),
|
|
'memory' => [],
|
|
'disk' => [],
|
|
'services' => [],
|
|
'processes' => []
|
|
];
|
|
|
|
// Mémoire
|
|
$free = shell_exec('free -b 2>/dev/null');
|
|
if (preg_match('/Mem:\s+(\d+)\s+(\d+)\s+(\d+)/', $free, $m)) {
|
|
$scan['memory'] = ['total' => (int)$m[1], 'used' => (int)$m[2], 'free' => (int)$m[3], 'percent' => round($m[2]/$m[1]*100, 1)];
|
|
}
|
|
|
|
// Disque
|
|
$scan['disk'] = ['total' => disk_total_space('/'), 'free' => disk_free_space('/'), 'used' => disk_total_space('/') - disk_free_space('/'), 'percent' => round((1 - disk_free_space('/') / disk_total_space('/')) * 100, 1)];
|
|
|
|
// Services
|
|
$services = ['apache2', 'nginx', 'postgresql', 'mysql', 'redis', 'docker', 'ollama'];
|
|
foreach ($services as $svc) {
|
|
$status = trim(shell_exec("systemctl is-active $svc 2>/dev/null") ?: 'unknown');
|
|
$scan['services'][$svc] = $status;
|
|
}
|
|
|
|
// Top processus
|
|
$ps = shell_exec('ps aux --sort=-%mem 2>/dev/null | head -6');
|
|
$scan['top_processes'] = $ps;
|
|
|
|
// Ports ouverts
|
|
$scan['ports'] = trim(shell_exec('ss -tlnp 2>/dev/null | head -15') ?: '');
|
|
|
|
// Docker containers
|
|
$scan['docker'] = trim(shell_exec('docker ps --format "{{.Names}}: {{.Status}}" 2>/dev/null') ?: '');
|
|
|
|
echo json_encode(['success' => true, 'scan' => $scan]);
|
|
break;
|
|
|
|
case 'read':
|
|
$file = $_GET['file'] ?? $_POST['file'] ?? '';
|
|
if (empty($file) || !file_exists($file)) {
|
|
echo json_encode(['success' => false, 'error' => 'File not found']);
|
|
exit;
|
|
}
|
|
if (filesize($file) > 1024 * 1024) {
|
|
echo json_encode(['success' => false, 'error' => 'File too large (max 1MB)']);
|
|
exit;
|
|
}
|
|
$content = file_get_contents($file);
|
|
echo json_encode(['success' => true, 'file' => $file, 'content' => $content, 'size' => filesize($file), 'modified' => filemtime($file)]);
|
|
break;
|
|
|
|
case 'write':
|
|
$file = $_POST['file'] ?? '';
|
|
$content = $_POST['content'] ?? '';
|
|
$backup = $_POST['backup'] ?? true;
|
|
|
|
if (empty($file)) {
|
|
echo json_encode(['success' => false, 'error' => 'No file specified']);
|
|
exit;
|
|
}
|
|
|
|
// Créer backup si le fichier existe
|
|
if ($backup && file_exists($file)) {
|
|
$backupFile = $file . '.backup_' . date('Ymd_His');
|
|
copy($file, $backupFile);
|
|
}
|
|
|
|
$result = file_put_contents($file, $content);
|
|
echo json_encode(['success' => $result !== false, 'file' => $file, 'size' => $result, 'backup' => $backupFile ?? null]);
|
|
break;
|
|
|
|
case 'logs':
|
|
$type = $_GET['type'] ?? 'apache';
|
|
$lines = min((int)($_GET['lines'] ?? 50), 200);
|
|
|
|
$logFiles = [
|
|
'apache' => '/var/log/apache2/error.log',
|
|
'apache_access' => '/var/log/apache2/access.log',
|
|
'syslog' => '/var/log/syslog',
|
|
'auth' => '/var/log/auth.log',
|
|
'wevads' => '/opt/wevads/logs/app.log',
|
|
'postgresql' => '/var/log/postgresql/postgresql-*-main.log'
|
|
];
|
|
|
|
$logFile = $logFiles[$type] ?? $logFiles['apache'];
|
|
if (strpos($logFile, '*') !== false) {
|
|
$files = glob($logFile);
|
|
$logFile = end($files) ?: $logFile;
|
|
}
|
|
|
|
$content = '';
|
|
if (file_exists($logFile)) {
|
|
$content = shell_exec("tail -n $lines " . escapeshellarg($logFile) . " 2>/dev/null");
|
|
}
|
|
|
|
echo json_encode(['success' => true, 'type' => $type, 'file' => $logFile, 'content' => $content]);
|
|
break;
|
|
|
|
case 'search':
|
|
$query = $_GET['query'] ?? '';
|
|
$path = $_GET['path'] ?? '/opt/wevads';
|
|
$type = $_GET['type'] ?? 'content'; // content, filename
|
|
|
|
if (empty($query)) {
|
|
echo json_encode(['success' => false, 'error' => 'No query']);
|
|
exit;
|
|
}
|
|
|
|
$results = [];
|
|
if ($type === 'filename') {
|
|
$cmd = "find " . escapeshellarg($path) . " -name " . escapeshellarg("*$query*") . " -type f 2>/dev/null | head -50";
|
|
} else {
|
|
$cmd = "grep -rl " . escapeshellarg($query) . " " . escapeshellarg($path) . " --include='*.php' --include='*.js' --include='*.html' 2>/dev/null | head -30";
|
|
}
|
|
|
|
$output = shell_exec($cmd);
|
|
$results = array_filter(explode("\n", trim($output)));
|
|
|
|
echo json_encode(['success' => true, 'query' => $query, 'results' => $results, 'count' => count($results)]);
|
|
break;
|
|
|
|
case 'tree':
|
|
$path = $_GET['path'] ?? '/opt/wevads';
|
|
$depth = min((int)($_GET['depth'] ?? 2), 4);
|
|
|
|
$tree = shell_exec("find " . escapeshellarg($path) . " -maxdepth $depth -type f -o -type d 2>/dev/null | head -100");
|
|
echo json_encode(['success' => true, 'path' => $path, 'tree' => $tree]);
|
|
break;
|
|
|
|
case 'hamid':
|
|
$message = $_POST['message'] ?? '';
|
|
$context = $_POST['context'] ?? '';
|
|
$provider = $_POST['provider'] ?? 'cerebras';
|
|
|
|
if (empty($message)) {
|
|
echo json_encode(['success' => false, 'error' => 'No message']);
|
|
exit;
|
|
}
|
|
|
|
// Appeler l'API WEVAL MIND
|
|
$ch = curl_init('http://localhost/api/widget-api.php');
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_POST => true,
|
|
CURLOPT_POSTFIELDS => http_build_query(['message' => $message . ($context ? "\n\nContexte:\n$context" : ''), 'provider' => $provider]),
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_TIMEOUT => 120
|
|
]);
|
|
$response = curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
$data = json_decode($response, true);
|
|
echo json_encode($data ?: ['success' => false, 'error' => 'API error']);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode(['success' => false, 'error' => 'Unknown action: ' . $action]);
|
|
}
|
|
|