shell bypass 403
<?php /** * @package akeebabackup * @copyright Copyright (c)2006-2023 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ use Akeeba\Engine\Platform; use FOF40\Container\Container; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Plugin\CMSPlugin; defined('_JEXEC') || die(); class plgActionlogAkeebabackup extends CMSPlugin { /** @var Container */ private $container; /** * Constructor * * @param object $subject The object to observe * @param array $config An array that holds the plugin configuration * * @since 6.4.0 */ public function __construct(&$subject, $config) { // Make sure Akeeba Backup is installed if (!file_exists(JPATH_ADMINISTRATOR . '/components/com_akeeba')) { return; } // Make sure Akeeba Backup is enabled if (!ComponentHelper::isEnabled('com_akeeba')) { return; } // Load FOF if (!defined('FOF40_INCLUDED') && !@include_once(JPATH_LIBRARIES . '/fof40/include.php')) { return; } $this->container = Container::getInstance('com_akeeba'); // No point in logging guest actions if ($this->container->platform->getUser()->guest) { return; } // If any of the above statement returned, our plugin is not attached to the subject, so it's basically disabled parent::__construct($subject, $config); } /** * Logs the creation of a new backup profile * * @param \Akeeba\Backup\Admin\Controller\Profiles $controller * @param array $data * @param int $id */ public function onComAkeebaControllerProfilesAfterApplySave($controller, $data, $id) { // If I have an ID in the request and it's the same of the model, I'm just editing a record if (isset($data['id']) && $data['id'] == $id) { return; } $profile_title = $data['description']; $this->container->platform->logUserAction($profile_title, 'COM_AKEEBA_LOGS_PROFILE_ADD', 'com_akeeba'); } /** * Logs deletion of a backup profile * * @param \Akeeba\Backup\Admin\Controller\Profiles $controller */ public function onComAkeebaControllerProfilesAfterRemove($controller) { $ids = $controller->input->get('cid', [], 'array', 2); $profile_title = '# ' . implode(', ', $ids); $this->container->platform->logUserAction($profile_title, 'COM_AKEEBA_LOGS_PROFILE_DELETE', 'com_akeeba'); } /** * Log configuration edit (apply) * * @param \Akeeba\Backup\Admin\Controller\Configuration $controller */ public function onComAkeebaControllerConfigurationAfterApply($controller) { $this->logConfigurationChange(); } /** * Log configuration edit (save and close) * * @param \Akeeba\Backup\Admin\Controller\Configuration $controller */ public function onComAkeebaControllerConfigurationAfterSave($controller) { $this->logConfigurationChange(); } /** * Log configuration edit (save and new) * * @param \Akeeba\Backup\Admin\Controller\Configuration $controller */ public function onComAkeebaControllerConfigurationAfterSavenew($controller) { $this->logConfigurationChange(); } /** * Log starting a new backup * * @param \Akeeba\Backup\Admin\Controller\Backup $controller */ public function onComAkeebaControllerBackupBeforeAjax($controller) { $ajaxTask = $this->container->input->get('ajax', '', 'cmd'); // Log only starting the backup if ($ajaxTask != 'start') { return; } $profile_id = $this->container->platform->getSessionVar('profile', -10, 'akeeba'); if ($profile_id < 1) { return; } $profile_id = '#' . $profile_id; $this->container->platform->logUserAction($profile_id, 'COM_AKEEBA_LOGS_BACKUP_RUN', 'com_akeeba'); } /** * Log downloading a backup using Joomla interface * * @param \Akeeba\Backup\Admin\Controller\Manage $controller */ public function onComAkeebaControllerManageBeforeDownload($controller) { $id = $this->container->input->getInt('id'); $part = $this->container->input->getInt('part', -1); // This should never happens, but better be safe if (!$id) { return; } $stat = Platform::getInstance()->get_statistics($id); $profile_name = Platform::getInstance()->get_profile_name($stat['profile_id']); $title = 'Profile: "' . $profile_name . '" ID: ' . $id; if ($part > -1) { $title .= ' part: ' . $part; } $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_MANAGE_DOWNLOAD', 'com_akeeba'); } /** * Logs deleting backup files * * @param \Akeeba\Backup\Admin\Controller\Manage $controller */ public function onComAkeebaControllerManageBeforeDeletefiles($controller) { $ids = $this->getIDsFromRequest(); foreach ($ids as $id) { $this->container->platform->logUserAction('ID: ' . $id, 'COM_AKEEBA_LOGS_MANAGE_DELETEFILES', 'com_akeeba'); } } /** * Logs deleting backup stat entry * * @param \Akeeba\Backup\Admin\Controller\Manage $controller */ public function onComAkeebaControllerManageBeforeRemove($controller) { $ids = $this->getIDsFromRequest(); foreach ($ids as $id) { $this->container->platform->logUserAction($id, 'COM_AKEEBA_LOGS_MANAGE_DELETE', 'com_akeeba'); } } /** * Logs downloading remote archives to browser * * @param \Akeeba\Backup\Admin\Controller\RemoteFiles $controller */ public function onComAkeebaControllerRemoteFilesBeforeDlfromremote($controller) { $id = $this->container->input->getInt('id'); $part = $this->container->input->getInt('part', -1); // This should never happens, but better be safe if (!$id) { return; } $stat = Platform::getInstance()->get_statistics($id); $profile_name = Platform::getInstance()->get_profile_name($stat['profile_id']); $title = 'Profile: "' . $profile_name . '" ID: ' . $id; if ($part > -1) { $title .= ' part: ' . $part; } $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_REMOTEFILE_DOWNLOAD', 'com_akeeba'); } /** * Logs downloading remote archives back to the server * * @param \Akeeba\Backup\Admin\Controller\RemoteFiles $controller */ public function onComAkeebaControllerRemoteFilesBeforeDltoserver($controller) { $id = $this->container->input->getInt('id'); $part = $this->container->input->getInt('part', -1); $frag = $this->container->input->getInt('frag', -1); // Log only the first step if ($frag > -1 || $part > -1) { return; } // This should never happens, but better be safe if (!$id) { return; } $stat = Platform::getInstance()->get_statistics($id); $profile_name = Platform::getInstance()->get_profile_name($stat['profile_id']); $title = 'Profile: "' . $profile_name . '" ID: ' . $id; $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_REMOTEFILE_FETCH', 'com_akeeba'); } /** * Logs downloading remote archives to browser * * @param \Akeeba\Backup\Admin\Controller\RemoteFiles $controller */ public function onComAkeebaControllerRemoteFilesBeforeDelete($controller) { $id = $this->container->input->getInt('id'); $part = $this->container->input->getInt('part', -1); // This should never happens, but better be safe if (!$id) { return; } $stat = Platform::getInstance()->get_statistics($id); $profile_name = Platform::getInstance()->get_profile_name($stat['profile_id']); $title = 'Profile: "' . $profile_name . '" ID: ' . $id; if ($part > -1) { $title .= ' part: ' . $part; } $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_REMOTEFILE_DELETE', 'com_akeeba'); } /** * Logs downloading remote archives to browser * * @param \Akeeba\Backup\Admin\Controller\Upload $controller */ public function onComAkeebaControllerUploadBeforeStart($controller) { $id = $this->container->input->getInt('id'); // This should never happens, but better be safe if (!$id) { return; } $stat = Platform::getInstance()->get_statistics($id); $profile_name = Platform::getInstance()->get_profile_name($stat['profile_id']); $title = 'Profile: "' . $profile_name . '" ID: ' . $id; $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_UPLOADS_ADD', 'com_akeeba'); } /** * Log starting a site transfer wizard (connections valid, just before starting to actually transfer files) * * @param \Akeeba\Backup\Admin\Controller\Transfer $controller */ public function onComAkeebaControllerTransferBeforeUpload($controller) { $start = $this->container->input->getBool('start', false); if (!$start) { return; } $title = $this->container->platform->getSessionVar('transfer.url', '', 'akeeba'); if (!$title) { return; } $this->container->platform->logUserAction($title, 'COM_AKEEBA_LOGS_TRANSFER_RUN', 'com_akeeba'); } /** * Logs downloading a backup log * * @param \Akeeba\Backup\Admin\Controller\Log $controller */ public function onComAkeebaControllerLogBeforeDownload($controller) { $tag = $this->container->input->get('tag', null, 'cmd');; $this->container->platform->logUserAction($tag, 'COM_AKEEBA_LOGS_LOG_DOWNLOAD', 'com_akeeba'); } /** * Log importing a backup archive * * @param \Akeeba\Backup\Admin\Controller\Discover $controller */ public function onComAkeebaControllerDiscoverBeforeImport($controller) { $files = $this->container->input->get('files', [], 'array'); foreach ($files as $file) { $this->container->platform->logUserAction($file, 'COM_AKEEBA_LOGS_DISCOVER_IMPORT', 'com_akeeba'); } } /** * Log importing a backup archive from S3 * * @param \Akeeba\Backup\Admin\Controller\Discover $controller */ public function onComAkeebaControllerS3ImportBeforeDltoserver($controller) { $file = $this->container->input->get('file', '', 'string'); // Log only the initial download step $part = $this->container->input->getInt('part', -1); $frag = $this->container->input->getInt('frag', -1); $step = $this->container->input->getInt('step', -1); if ($part > -1 || $frag > -1 || $step > -1) { return; } $this->container->platform->logUserAction($file, 'COM_AKEEBA_LOGS_S3IMPORT_IMPORT', 'com_akeeba'); } private function logConfigurationChange() { $profileName = $this->container->input->getString('profilename', null); $this->container->platform->logUserAction('"' . $profileName . '"', 'COM_AKEEBA_LOGS_CONFIGURATION_EDIT', 'com_akeeba'); } /** * Gets the list of IDs from the request data * * @return array */ private function getIDsFromRequest() { // Get the ID or list of IDs from the request or the configuration $cid = $this->container->input->get('cid', [], 'array'); $id = $this->container->input->getInt('id', 0); $ids = []; if (is_array($cid) && !empty($cid)) { $ids = $cid; } elseif (!empty($id)) { $ids = [$id]; } return $ids; } }