PATH:
home
/
vcomplcotr
/
www
/
wp-content
/
plugins
/
akeebabackupwp
/
app
/
Solo
/
assets
/
installers
<?php /** * Akeeba Kickstart * An AJAX-powered archive extraction tool * * @package kickstart * @copyright Copyright (c)2025-2026 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ // PHP version check if (version_compare(PHP_VERSION, '7.4', 'lt')) { $message = sprintf('This script requires PHP %s or later. You are currently using PHP %s.', AKEEBA_MIN_PHP, PHP_VERSION); if (_AKEEBA_IS_WEB) { echo "<html lang=\"en\"><head><title>Unsupported PHP version</title></head><body><h1>Unsupported PHP version</h1><p>$me </p></body></html>"; exit; } echo $message; exit(255); } // Normalise the locale function_exists('setlocale') && @setlocale(LC_ALL, 'en_US.UTF8'); define('_AKEEBA_SELF_DIR', @is_link(__FILE__) ? getcwd() : __DIR__); define('_AKEEBA_SELF_BASENAME', basename(__FILE__)); define('_AKEEBA_SELF_BARENAME', implode('.', array_slice(explode('.', basename(__FILE__)), 0, -1))); define('_AKEEBA_WEB_ENTRYPOINT', 'src/kickstart_web.php'); define('_AKEEBA_CLI_ENTRYPOINT', 'src/kickstart_cli.php'); define('_AKEEBA_RESTORATION', 1); define('_AKEEBA_IS_WINDOWS', strpos(strtoupper(PHP_OS), 'WIN') === 0); define( '_AKEEBA_IS_WEB', @(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST')) ); define('AKEEBA_VERSION', '9.0.4'); define('AKEEBA_DATE', '2026-03-30 08:26:56'); define('AKEEBA_PRO', '0'); define('AKEEBA_NAME', 'kickstart'); define('AKEEBA_MIN_PHP', '7.4'); define( 'AKEEBA_RUN_AS_PHP', !in_array('phar', stream_get_wrappers()) || !class_exists('Phar', false) ? 1 : Phar::PHP ); define( 'AKEEBA_MIMETYPES', [ 'dtd' => 'text/plain', 'txt' => 'text/plain', 'xsd' => 'text/plain', 'php' => AKEEBA_RUN_AS_PHP, 'inc' => AKEEBA_RUN_AS_PHP, 'bmp' => 'image/bmp', 'css' => 'text/css', 'gif' => 'image/gif', 'htm' => 'text/html', 'html' => 'text/html', 'htmls' => 'text/html', 'ico' => 'image/x-ico', 'jpe' => 'image/jpeg', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'js' => 'application/x-javascript', 'png' => 'image/png', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'xml' => 'text/xml', ] ); define('_AKEEBA_HAS_KICKTEMP', @file_exists(_AKEEBA_SELF_DIR . '/kicktemp') && @is_dir(_AKEEBA_SELF_DIR . '/kicktemp') && @is_writeable(_AKEEBA_SELF_DIR . '/kicktemp')); function akstrlen(?string $string): int { if ($string === null || $string === '') { return 0; } return function_exists('mb_strlen') ? mb_strlen($string ?? '', '8bit') : count(unpack('C*', $string)); } /** * A binary-safe strpos replacement. * * @param string|null $haystack The string to search in. * @param string $needle The string to search for. * @param int $offset The search offset. * * @return int|false The position of the needle, or false if not found. */ function akstrpos(?string $haystack, string $needle, int $offset = 0) { if ($haystack === null || $needle === '') { return false; } if (function_exists('mb_strpos')) { return mb_strpos($haystack, $needle, $offset, '8bit'); } // Use regex to find the position. // preg_match is binary-safe as long as the /u (UTF-8) modifier is NOT used. // We quote the needle to handle special regex characters. $regex = '/' . preg_quote($needle, '/') . '/'; $result = preg_match($regex, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset); if ($result) { return $matches[0][1]; } return false; } /** * A binary-safe substr replacement. * * @param string|null $string The input string. * @param int $start The start offset. * @param int|null $length The length of the slice. * * @return string|false The extracted part of the string, or false on failure. */ function aksubstr(?string $string, int $start, ?int $length = null) { if ($string === null) { return false; } if (function_exists('mb_substr')) { return mb_substr($string, $start, $length, '8bit'); } // If length is null, we want the rest of the string. if ($length === null) { // A simple regex to capture everything from $start to the end. // We use . with the /s (dotall) modifier to include newlines. $pattern = '/^.{' . $start . '}(.*)$/s'; if (preg_match($pattern, $string, $matches)) { return $matches[1]; } return ''; } // Handle the case where a specific length is requested. $pattern = '/^.{' . $start . '}(.{0,' . $length . '})/s'; if (preg_match($pattern, $string, $matches)) { return $matches[1]; } return false; } // Check for FTP ASCII mode corruption. // When uploading .php files via FTP, most clients default to ASCII mode. In ASCII mode, // Windows-to-Linux transfers strip carriage return (\r) bytes, converting every \r\n pair // to a bare \n. The PHAR format mandates that the __HALT_COMPILER() marker is followed by // \r\n. If the \r is gone, the PHAR body is corrupt and cannot be parsed or extracted. // The PHP error messages that result ("Could not open...", "internal corruption", etc.) give // users no actionable guidance, hence this early check. call_user_func( function () { $fp = @fopen(__FILE__, 'rb'); if (!$fp) { return; } $data = fread($fp, 65536); fclose($fp); // The PHAR spec mandates CRLF here; ASCII-mode FTP strips the CR. $crlfMarker = '__HALT_' . 'COMPILER(); ?>' . "\r\n"; $lfMarker = '__HALT_' . 'COMPILER(); ?>' . "\n"; if (akstrpos($data, $crlfMarker) !== false || akstrpos($data, $lfMarker) === false) { // CRLF marker present (file is OK), or marker not found at all (different problem). return; } // CRLF marker is missing but LF-only marker exists: classic ASCII-mode FTP corruption. $message = sprintf( 'The file "%1$s" is corrupt and cannot run. It was most likely uploaded via FTP in ' . 'ASCII mode (the default for .php files in many FTP clients). ' . 'ASCII mode corrupts binary files by stripping carriage-return (\\r) bytes from ' . 'every \\r\\n pair. Because %1$s is a PHP Archive (PHAR) the binary data inside ' . 'it is now unreadable.', _AKEEBA_SELF_BASENAME ); $howToFix = 'Re-upload the file using Binary (not ASCII / Auto) transfer mode, ' . 'or switch to SFTP / SCP which never modify file contents.'; $ftpClientTips = [ 'FileZilla' => 'Transfer menu → Transfer Type → Binary.', 'WinSCP' => 'Preferences → Transfer → Transfer mode → Binary.', 'cPanel File Manager' => 'Use the Upload button in File Manager; it uses Binary mode automatically.', 'Command-line FTP' => 'Type "binary" at the ftp> prompt before issuing the put command.', ]; if (_AKEEBA_IS_WEB) { $tips = ''; foreach ($ftpClientTips as $client => $tip) { $tips .= '<li><strong>' . htmlspecialchars($client) . ':</strong> ' . htmlspecialchars($tip) . '</li>'; } echo "<!DOCTYPE html>\n" . "<html lang=\"en\"><head><meta charset=\"utf-8\">" . "<title>Corrupt File – FTP ASCII Mode</title></head><body>" . "<h1>Corrupt File – FTP ASCII Mode Upload Detected</h1>" . "<p>" . htmlspecialchars($message) . "</p>" . "<h2>How to fix this</h2>" . "<p>" . htmlspecialchars($howToFix) . "</p>" . "<h3>FTP client instructions</h3><ul>" . $tips . "</ul>" . "</body></html>"; } else { echo "ERROR: " . $message . "\n\n"; echo "How to fix: " . $howToFix . "\n\n"; echo "FTP client instructions:\n"; foreach ($ftpClientTips as $client => $tip) { echo " $client: $tip\n"; } } exit(1); } ); // Try to use the PHAR stream wrapper call_user_func( function () { // Is PHAR handling manually disabled? if (_AKEEBA_HAS_KICKTEMP && @file_exists(_AKEEBA_SELF_DIR . '/kicktemp/nophar.txt')) { return; } if (!in_array('phar', stream_get_wrappers()) || !class_exists('Phar', false)) { return; } // Check whether open_basedir restrictions would prevent phar:// includes. if (function_exists('ini_get')) { $openBasedir = @ini_get('open_basedir'); if (!empty($openBasedir)) { $pharFile = realpath(__FILE__) ?: __FILE__; $pharAllowed = false; foreach (array_filter(explode(PATH_SEPARATOR, $openBasedir)) as $allowedPath) { $allowedPath = rtrim(realpath($allowedPath) ?: $allowedPath, DIRECTORY_SEPARATOR); if ($pharFile === $allowedPath || strpos($pharFile, $allowedPath . DIRECTORY_SEPARATOR) === 0) { $pharAllowed = true; break; } } if (!$pharAllowed) { // Ensure kicktemp exists and is writable so the fallback extractor can use it. $kicktempDir = _AKEEBA_SELF_DIR . '/kicktemp'; if (!(@file_exists($kicktempDir) && @is_dir($kicktempDir) && @is_writable($kicktempDir))) { if (!@mkdir($kicktempDir, 0755, true) || !@is_writable($kicktempDir)) { $message = sprintf( 'Your server\'s open_basedir restrictions prevent Kickstart from using its built-in ' . 'PHAR support. Please create a writable directory named "kicktemp" in the same ' . 'folder as %s and reload this page.', _AKEEBA_SELF_BASENAME ); if (_AKEEBA_IS_WEB) { echo "<html lang=\"en\"><head><title>Setup Required</title></head><body>" . "<h1>Setup Required</h1><p>" . htmlspecialchars($message) . "</p></body></html>"; } else { echo $message . "\n"; } exit(1); } } // Ensure kicktemp/nophar.txt exists so the PHAR path is permanently skipped. $nopharFile = $kicktempDir . '/nophar.txt'; if (!@file_exists($nopharFile)) { if (@file_put_contents($nopharFile, '') === false) { $message = sprintf( 'Your server\'s open_basedir restrictions prevent Kickstart from using its built-in ' . 'PHAR support. Please create an empty file named "nophar.txt" inside the ' . '"kicktemp" directory next to %s and reload this page.', _AKEEBA_SELF_BASENAME ); if (_AKEEBA_IS_WEB) { echo "<html lang=\"en\"><head><title>Setup Required</title></head><body>" . "<h1>Setup Required</h1><p>" . htmlspecialchars($message) . "</p></body></html>"; } else { echo $message . "\n"; } exit(1); } } // kicktemp and nophar.txt are in place; use the fallback extractor. return; } } } // A miniature router for webPhar $miniRouter = function($path) { // Clean the path, removing ourselves. $path = ltrim($path, '/'); if (substr($path, 0, strlen(_AKEEBA_SELF_BASENAME)) === _AKEEBA_SELF_BASENAME) { $path = ltrim(substr($path, strlen(_AKEEBA_SELF_BASENAME)), '/'); } $path = rtrim($path, '/'); // We only accept URLs with a path suffix equal to our front controller, or none at all. if (empty($path) || $path === _AKEEBA_WEB_ENTRYPOINT) { // In both cases, force loading our front controller. return _AKEEBA_WEB_ENTRYPOINT; } // Explicitly block direct access to arbitrary PHP files packed in the application PHAR archive. if (substr($path, -4) === '.php') { return false; } // All other files: return them if they exist; 404 if they don't exist. $nominalFile = 'phar://' . __FILE__ . '/' . $path; return !file_exists($nominalFile) || !@is_file($nominalFile) ? false : $path; }; try { Phar::interceptFileFuncs(); include 'phar://' . __FILE__ . '/src/includes/preamble.php'; Phar::webPhar(null, _AKEEBA_WEB_ENTRYPOINT, null, AKEEBA_MIMETYPES, $miniRouter); include 'phar://' . __FILE__ . '/' . _AKEEBA_CLI_ENTRYPOINT; } catch (\Throwable $e) { if (_AKEEBA_IS_WEB) { echo "<html lang=\"en\"><head><title>Kickstart Error</title></head><body>" . "<h1>Kickstart cannot start</h1>" . "<p>An error occurred while trying to run Kickstart.</p>" . "<p><strong>Error:</strong> " . htmlspecialchars($e->getMessage()) . "</p>" . "<p>This is very unlikely to be a bug in Kickstart itself. " . "It is almost certainly caused by how the file was uploaded to your server, " . "or by the server's PHP OPcache settings. Both of these issues are documented " . "and easy to address.</p>" . "<p>Please read the “Before using Kickstart” section of the documentation: " . "<a href=\"https://www.akeeba.com/documentation/akeeba-kickstart-documentation.html\">" . "https://www.akeeba.com/documentation/akeeba-kickstart-documentation.html</a></p>" . "</body></html>"; } else { echo "Kickstart cannot start.\n\n" . "Error: " . $e->getMessage() . "\n\n" . "This is very unlikely to be a bug in Kickstart itself. " . "It is almost certainly caused by how the file was uploaded to your server, " . "or by the server's PHP OPcache settings. Both of these issues are documented " . "and easy to address.\n\n" . "Please read the \"Before using Kickstart\" section of the documentation:\n" . "https://www.akeeba.com/documentation/akeeba-kickstart-documentation.html\n"; } exit(1); } exit; } ); /** * PHAR extraction helper, for use when PHAR support is missing on the server. */ class Kickstart_Extract_Phar { const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; static $temp; static $origdir; static function go($return = false) { $stubLength = self::getStubLength(); $fp = fopen(__FILE__, 'rb'); fseek($fp, $stubLength); $L = unpack('V', $a = fread($fp, 4)); $m = ''; do { $read = 8192; if ($L[1] - akstrlen($m) < 8192) { $read = $L[1] - akstrlen($m); } $last = fread($fp, $read); $m .= $last; } while (akstrlen($last) && akstrlen($m) < $L[1]); if (akstrlen($m) < $L[1]) { die(sprintf("Error: Corrupt file. Manifest length read was \"%s\", should be \"%s\"", akstrlen($m), $L[1])); } $info = self::_unpack($m); $f = $info['c']; if ($f & self::GZ && !function_exists('gzinflate')) { die('Error: The PHP zlib extension is not enabled'); } if ($f & self::BZ2 && !function_exists('bzdecompress')) { die('Error: The PHP bzip2 extension is not enabled'); } $temp = self::tmpdir(); if (!$temp || !is_writable($temp)) { $sessionpath = session_save_path(); if (strpos($sessionpath, ";") !== false) { $sessionpath = substr($sessionpath, strpos($sessionpath, ";") + 1); } if (!file_exists($sessionpath) || !is_dir($sessionpath)) { die('Could not locate temporary directory to extract Kickstart'); } $temp = $sessionpath; } $temp .= '/pharextract/' . _AKEEBA_SELF_BARENAME; self::$temp = $temp; self::$origdir = getcwd(); @mkdir($temp, 0777, true); $temp = realpath($temp); if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) { self::recursiveRmdir($temp); @mkdir($temp, 0777, true); @file_put_contents($temp . '/' . md5_file(__FILE__), ''); foreach ($info['m'] as $path => $file) { $a = !file_exists(dirname($temp . '/' . $path)); @mkdir(dirname($temp . '/' . $path), 0777, true); clearstatcache(); if ($path[strlen($path) - 1] == '/') { @mkdir($temp . '/' . $path, 0777); continue; } file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp)); @chmod($temp . '/' . $path, 0666); } } include Kickstart_Extract_Phar::$temp . '/src/includes/preamble.php'; if (!$return) { include Kickstart_Extract_Phar::$temp . DIRECTORY_SEPARATOR . _AKEEBA_CLI_ENTRYPOINT; } } static function getStubLength() { $fp = fopen(__FILE__, 'rb'); $data = fread($fp, 65536); fclose($fp); $locate = '__HALT_' . 'COMPILER(); ?>' . "\r\n"; return akstrpos($data, $locate) + akstrlen($locate); } static function tmpdir() { // Use the kicktemp directory if it already exists and is writeable. if (file_exists(_AKEEBA_SELF_DIR . '/kicktemp') && is_dir(_AKEEBA_SELF_DIR . '/kicktemp') && is_writeable(_AKEEBA_SELF_DIR . '/kicktemp')) { return _AKEEBA_SELF_DIR . '/kicktemp'; } if (_AKEEBA_IS_WINDOWS) { if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) { return $var; } if (is_dir('/temp') || mkdir('/temp')) { return realpath('/temp'); } return false; } if ($var = getenv('TMPDIR')) { return $var; } return realpath('/tmp'); } static function _unpack($m) { $info = unpack('V', aksubstr($m, 0, 4)); $l = unpack('V', aksubstr($m, 10, 4)); $m = aksubstr($m, 14 + $l[1]); $s = unpack('V', aksubstr($m, 0, 4)); $o = 0; $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { $len = unpack('V', aksubstr($m, $start, 4)); $start += 4; $savepath = aksubstr($m, $start, $len[1]); $start += $len[1]; $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', aksubstr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; $o += $ret['m'][$savepath][2]; $start += 24 + $ret['m'][$savepath][5]; $ret['c'] |= $ret['m'][$savepath][4] & self::MASK; } return $ret; } static function extractFile($path, $entry, $fp) { $data = ''; $c = $entry[2]; while ($c) { if ($c < 8192) { $data .= @fread($fp, $c); $c = 0; break; } $c -= 8192; $data .= @fread($fp, 8192); } if ($entry[4] & self::GZ) { $data = gzinflate($data); } elseif ($entry[4] & self::BZ2) { $data = bzdecompress($data); } if (strlen($data) != $entry[0]) { die(sprintf("Kickstart is corrupt. Size error extracting file: %s != %s", strlen($data), $entry[0])); } if ($entry[3] != sprintf("%u", crc32($data) & 0xffffffff)) { die("Kickstart is corrupt. Invalid checksum extracting file."); } return $data; } public static function recursiveRmdir(string $directory): bool { $directory = rtrim($directory, '/'); if (!file_exists($directory) || !is_dir($directory) || !is_readable($directory)) { return false; } $di = new DirectoryIterator($directory); foreach ($di as $item) { if ($item->isDot()) { continue; } if ($item->isDir()) { self::recursiveRmdir($item->getPathname()); continue; } unlink($item->getPathname()); } return rmdir($directory); } } // Web controller call_user_func( function () { if (!_AKEEBA_IS_WEB) { return; } Kickstart_Extract_Phar::go(true); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); $basename = basename(__FILE__); if (!strpos($_SERVER['REQUEST_URI'], $basename)) { include Kickstart_Extract_Phar::$temp . DIRECTORY_SEPARATOR . _AKEEBA_WEB_ENTRYPOINT; return; } $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename)); if (!$pt || $pt == '/') { // Fudge the request path to always load Kickstart's front controller. $pt = _AKEEBA_WEB_ENTRYPOINT; } // Make sure the file exists $a = @realpath(Kickstart_Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt); // Forbid direct access to .php files; only the front controller must be web-accessible. $z = substr($pt, -4) === '.php'; if ($z || !$a || strlen(dirname($a)) < strlen(Kickstart_Extract_Phar::$temp)) { header('HTTP/1.0 404 Not Found'); echo "<html lang=\"en\">\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>"; exit; } $b = pathinfo($a); if (!isset($b['extension'])) { header('Content-Type: text/plain'); header('Content-Length: ' . filesize($a)); readfile($a); exit; } if (isset(AKEEBA_MIMETYPES[$b['extension']])) { if (AKEEBA_MIMETYPES[$b['extension']] === 1) { include $a; exit; } if (AKEEBA_MIMETYPES[$b['extension']] === 2) { highlight_file($a); exit; } header('Content-Type: ' . AKEEBA_MIMETYPES[$b['extension']]); header('Content-Length: ' . filesize($a)); readfile($a); exit; } } ); // CLI mode Kickstart_Extract_Phar::go(); __HALT_COMPILER(); ?> _ K kickstart.phar language/en-GB.ini�* �3�i� g@_ɤ media/js/postextraction.js� �3�it �x� media/js/utils.jsE@ �3�i� ��C�� media/js/initialization.js7 �3�iB wx� media/js/ajax.js�* �3�i� 2h�C� media/js/common_ui.js_ �3�i� >'�� media/js/extraction.js� �3�i� (�cT� media/js/preextraction.js< �3�i� ]@�� media/js/json.jsF3 �3�i� ���c� media/js/translate.jsm �3�i� \jɐ� media/js/system.js�O �3�i Ӽ{� media/css/theme.css11 �3�iO �緤 src/Unarchiver/JPS.php] �3�i &�Қ� src/Unarchiver/JPA.php�Y �3�i zG� % src/Unarchiver/AbstractUnarchiver.php|M �3�i� ��a� src/Unarchiver/State.php� �3�i� n`�� src/Unarchiver/ZIP.phpb+ �3�i� ��{�� src/Base/AbstractObject.php� �3�iA �@�� src/Base/AbstractPart.php7"