From 14fa6e21559e6046b2fdb7856148dd12f49d84be Mon Sep 17 00:00:00 2001 From: svfcode Date: Fri, 28 Jun 2024 08:42:10 +0300 Subject: [PATCH] New. Scan. Init self check stage. --- inc/spbc-settings.php | 1 + .../SpbctWP/Scanner/ScannerQueue.php | 10 + .../SpbctWP/Scanner/Stages/SelfCheckStage.php | 185 ++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php diff --git a/inc/spbc-settings.php b/inc/spbc-settings.php index 7825b8305..631d7e2b0 100644 --- a/inc/spbc-settings.php +++ b/inc/spbc-settings.php @@ -2978,6 +2978,7 @@ function spbc_field_scanner() echo '
' + . '' . __('Self check', 'security-malware-firewall') . ' -> ' . '' . __('Receiving core hashes', 'security-malware-firewall') . ' -> ' . '' . __('Receiving plugin and theme hashes', 'security-malware-firewall') . ' -> ' . '' . __('Preparing', 'security-malware-firewall') . ' -> ' diff --git a/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php b/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php index 600e046b2..40cdef815 100755 --- a/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php +++ b/lib/CleantalkSP/SpbctWP/Scanner/ScannerQueue.php @@ -31,6 +31,7 @@ use CleantalkSP\SpbctWP\Helpers\Helper as QueueHelper; use CleantalkSP\SpbctWP\Helpers\CSV; use CleantalkSP\SpbctWP\RemoteCalls; +use CleantalkSP\SpbctWP\Scanner\Stages\SelfCheckStage; use CleantalkSP\SpbctWP\Scanner\Stages\SendResultsStage; class ScannerQueue @@ -39,6 +40,7 @@ class ScannerQueue * @var string[] List of scan stages */ public static $stages = array( + 'self_check', 'get_cms_hashes', 'get_modules_hashes', 'clean_results', @@ -306,6 +308,14 @@ public static function controllerFront() wp_send_json($out); } + public function self_check() // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps + { + $selfCheck = new SelfCheckStage(); + $selfCheck->run(); + + return ['end' => true]; + } + /** * Receive CMS hash * diff --git a/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php b/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php new file mode 100644 index 000000000..f8b57a1cc --- /dev/null +++ b/lib/CleantalkSP/SpbctWP/Scanner/Stages/SelfCheckStage.php @@ -0,0 +1,185 @@ +url = $this->setUrl(); + $this->seal = $this->calculateSeal(); + } + + /** + * Run self check and cure + */ + public function run() + { + $check = $this->check(); + + if (count($check) > 0) { + // TODO: Send to Cleantalk + // TODO: log + + // $this->sendToCleantalk($check); + // $this->writeLog($check); + $this->cure($check); + } + + return true; + } + + /** + * Check files + */ + private function check() + { + $files = $this->getFiles('check'); + + foreach ($files as $key) { + if ($key === $this->seal) { + unset($files[$key]); + } + } + + return $files; + } + + /** + * Set url + */ + private function setUrl() + { + $url = 'https://plugins.svn.wordpress.org/security-malware-firewall/tags/'; + $version = preg_replace('/[^\d.]/', '', SPBC_VERSION); + $url .= $version . '/'; + + $response = wp_remote_get($url . 'security-malware-firewall.php'); + $code = wp_remote_retrieve_response_code($response); + if ($code !== 200) { + $url = 'https://plugins.svn.wordpress.org/security-malware-firewall/trunk/'; + } + + return $url; + } + + /** + * Calculate seal + */ + private function calculateSeal() + { + $files = $this->getFiles('calculate'); + + $frequency = array_count_values($files); + arsort($frequency); + + reset($frequency); + return key($frequency); + } + + /** + * Get files + */ + private function getFiles($type) + { + $result = []; + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->dir, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST, + \RecursiveIteratorIterator::CATCH_GET_CHILD + ); + + foreach ($iterator as $fileinfo) { + if ($fileinfo->getFilename() === '.' || $fileinfo->getFilename() === '..') { + continue; + } + + if ($fileinfo->getExtension() !== 'php') { + continue; + } + + if ($fileinfo->getFilename() === 'SelfCheck.php') { + continue; + } + + if (strpos($fileinfo->getPathname(), $this->dir . 'vendor') !== false) { + continue; + } + + if (strpos($fileinfo->getPathname(), $this->dir . 'node_modules') !== false) { + continue; + } + + if (strpos($fileinfo->getPathname(), $this->dir . 'backups') !== false) { + continue; + } + + if ($type === 'calculate') { + $result[] = $fileinfo->getMTime(); + continue; + } + + if ($type === 'check') { + $result[$fileinfo->getMTime()] = str_replace($this->dir, '', $fileinfo->getPathname()); + continue; + } + } + + return $result; + } + + /** + * Cure + */ + private function cure($check) + { + foreach ($check as $file) { + $response = wp_remote_get($this->url . $file); + $code = wp_remote_retrieve_response_code($response); + + if ($code !== 200) { + // TODO: alient file, handle it + continue; + } + + if (is_wp_error($response)) { + // TODO: handle error + continue; + } + + $body = wp_remote_retrieve_body($response); + if (empty($body)) { + // TODO: handle error + continue; + } + + $success = file_put_contents($this->dir . $file, $body); + if (!$success) { + // TODO: handle error + continue; + } + + // TODO: log + } + } +}