From f42ed7c30034f110cd15991f3849c7939945a69c Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 23 Feb 2021 22:16:34 +0300 Subject: [PATCH 1/7] fix missed "|" separators in regex --- .../components/com_jedchecker/libraries/rules/jamss.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.php b/administrator/components/com_jedchecker/libraries/rules/jamss.php index 1432490..8648d9e 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.php +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.php @@ -104,13 +104,13 @@ class JedcheckerRulesJamss extends JEDcheckerRule $jamssStrings .= 'phpremoteview|directmail|bash_history|multiviews|cwings|vandal|bitchx|'; $jamssStrings .= 'eggdrop|guardservices|psybnc|dalnet|undernet|vulnscan|spymeta|raslan58|'; $jamssStrings .= 'Webshell|str_rot13|FilesMan|FilesTools|Web Shell|ifrm|bckdrprm|'; - $jamssStrings .= 'hackmeplz|wrgggthhd|WSOsetcookie|Hmei7|Inbox Mass Mailer|HackTeam|Hackeado'; + $jamssStrings .= 'hackmeplz|wrgggthhd|WSOsetcookie|Hmei7|Inbox Mass Mailer|HackTeam|Hackeado|'; $jamssStrings .= 'Janissaries|Miyachung|ccteam|Adminer|OOO000000|$GLOBALS|findsysfolder'; // These patterns will be used if GET parameter ?deepscan=1 is set while calling jamss.php file $jamssDeepSearchStrings = 'eval|base64_decode|base64_encode|gzdecode|gzdeflate|'; $jamssDeepSearchStrings .= 'gzuncompress|gzcompress|readgzfile|zlib_decode|zlib_encode|'; - $jamssDeepSearchStrings .= 'gzfile|gzget|gzpassthru|iframe|strrev|lzw_decompress|strtr'; + $jamssDeepSearchStrings .= 'gzfile|gzget|gzpassthru|iframe|strrev|lzw_decompress|strtr|'; $jamssDeepSearchStrings .= 'exec|passthru|shell_exec|system|proc_|popen'; // The patterns to search for From 7b8532f3727d0a2e9ab62a5e0d438d364b7e6115 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sun, 4 Apr 2021 11:41:33 +0300 Subject: [PATCH 2/7] unify code lines displaying --- .../com_jedchecker/libraries/rules/jamss.php | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.php b/administrator/components/com_jedchecker/libraries/rules/jamss.php index 8648d9e..0f88d92 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.php +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.php @@ -339,18 +339,34 @@ class JedcheckerRulesJamss extends JEDcheckerRule { $count++; + foreach ($all_results as $match) + { + // Output the line of malware code, but sanitize it before + // The offset is in $match[1] + $offset = $match[1]; + // Note: negative 3rd argument is used for right-to-left search + $start = strrpos($content, "\n", -(strlen($content) - $offset)); + + if ($start === false) + { + $start = 0; + } + + $end = strpos($content, "\n", $offset); + + if ($end === false) + { + $end = strlen($content); + } + + $first_code = substr($content, $start, min($end - $start, 200)); + $first_line = $this->calculate_line_number($offset, $content); + break; + } + if (is_array($pattern)) { // Then it has some additional comments - foreach ($all_results as $match) - { - // Output the line of malware code, but sanitize it before - // The offset is in $match[1] - $first_code = substr($content, $match[1], 200); - $first_line = $this->calculate_line_number($match[1], $content); - break; - } - $this->jamssWarning( $path, JText::_('COM_JEDCHECKER_ERROR_JAMSS_PATTERN') . "#$pattern[2] - $pattern[1]", @@ -362,16 +378,6 @@ class JedcheckerRulesJamss extends JEDcheckerRule else { // It's a string, no comments available - $first_content = ""; - - foreach ($all_results as $match) - { - // Output the line of malware code, but sanitize it before - $first_code = substr($content, $match[1], 200); - $first_line = $this->calculate_line_number($match[1], $content); - break; - } - $this->jamssWarning( $path, JText::_('COM_JEDCHECKER_ERROR_JAMSS_STRING') . $pattern, @@ -423,7 +429,6 @@ class JedcheckerRulesJamss extends JEDcheckerRule private function jamssWarning($path, $title, $info, $code, $line) { $info = !empty($info)?sprintf($this->params->get('info'), htmlentities($info, ENT_QUOTES)):""; - $code = !empty($code)?sprintf($this->params->get('code'), htmlentities($code, ENT_QUOTES)):""; - $this->report->addWarning($path, $info . $code . $title, $line); + $this->report->addWarning($path, $info . $title, $line, $code); } } From 071d50ce65a568e17f8f5d20eaf44ba566672edf Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Tue, 23 Feb 2021 23:25:41 +0300 Subject: [PATCH 3/7] clean PHP code (by removing comments only) in the jamss rules to avoid false-positives --- .../com_jedchecker/libraries/rules/jamss.php | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.php b/administrator/components/com_jedchecker/libraries/rules/jamss.php index 0f88d92..2573b2f 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.php +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.php @@ -306,6 +306,8 @@ class JedcheckerRulesJamss extends JEDcheckerRule } else { + $content = $this->cleanComments($content); + // Do a search for fingerprints foreach ($patterns As $pattern) { @@ -431,4 +433,82 @@ class JedcheckerRulesJamss extends JEDcheckerRule $info = !empty($info)?sprintf($this->params->get('info'), htmlentities($info, ENT_QUOTES)):""; $this->report->addWarning($path, $info . $title, $line, $code); } + + /** + * @param string $content + * + * @return string + */ + private function cleanComments($content) + { + if (!preg_match('/<\?php\s/i', $content, $match, PREG_OFFSET_CAPTURE)) + { + // No PHP code found + return $content; + } + + $pos = $match[0][1]; + $cleanContent = substr($content, 0, $pos); + + while (preg_match('/(?:[\'"]|\/\*|\/\/|\?>)/', $content, $match, PREG_OFFSET_CAPTURE, $pos)) + { + $foundPos = $match[0][1]; + $cleanContent .= substr($content, $pos, $foundPos - $pos); + $pos = $foundPos; + + switch ($match[0][0]) + { + case '"': + case "'": + $q = $match[0][0]; + + if (!preg_match("/$q(?>[^$q\\\\]+|\\\\.)*$q/As", $content, $match, 0, $pos)) + { + return $cleanContent . substr($content, $pos); + } + + $cleanContent .= $match[0]; + $pos += strlen($match[0]); + break; + + case '/*': + $cleanContent .= '/*'; + $pos += 2; + + $endPos = strpos($content, '*/', $pos); + + if ($endPos === false) + { + return $cleanContent; + } + + $cleanContent .= str_repeat("\n", substr_count(substr($content, $pos, $endPos - $pos), "\n")) . '*/'; + $pos = $endPos + 2; + + break; + + case '//': + $pos += strcspn($content, "\r\n", $pos); + break; + + case '?>': + $cleanContent .= '?>'; + $pos += 2; + + if (!preg_match('/<\?php\s/i', $content, $match, PREG_OFFSET_CAPTURE, $pos)) + { + // No PHP code found (up to the end of the file) + return $cleanContent . substr($content, $pos); + } + + $foundPos = $match[0][1]; + $cleanContent .= substr($content, $pos, $foundPos - $pos) . $match[0][0]; + $pos = $foundPos + strlen($match[0][0]); + + break; + } + } + + return $cleanContent; + } } From c241ede692ee62e16de4637dc0c8112c46b57d09 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Wed, 24 Feb 2021 01:15:35 +0300 Subject: [PATCH 4/7] badge-style for info tip in jamss --- .../components/com_jedchecker/libraries/rules/jamss.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.ini b/administrator/components/com_jedchecker/libraries/rules/jamss.ini index deb14e2..2aabd08 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.ini +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.ini @@ -19,4 +19,4 @@ fileExt="php|php3|php4|php5|phps|html|htaccess|gif" ; These format the output: code="code " -info="info " +info="? " From bda87074f0b40eb8c4ed9ed602bb6f2ef5804477 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sun, 4 Apr 2021 11:55:46 +0300 Subject: [PATCH 5/7] Add support of Bootstrap5 tooltips for JAMSS reports --- .../components/com_jedchecker/libraries/rules/jamss.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.ini b/administrator/components/com_jedchecker/libraries/rules/jamss.ini index 2aabd08..ca43d56 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.ini +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.ini @@ -19,4 +19,4 @@ fileExt="php|php3|php4|php5|phps|html|htaccess|gif" ; These format the output: code="code " -info="? " +info="? " From eb6ea3c7ec3c9dc66d88ee22b7bd200336630ed2 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Sun, 4 Apr 2021 13:38:13 +0300 Subject: [PATCH 6/7] codestyle --- .../components/com_jedchecker/libraries/rules/jamss.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.php b/administrator/components/com_jedchecker/libraries/rules/jamss.php index 2573b2f..c4bb8a9 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.php +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.php @@ -430,7 +430,7 @@ class JedcheckerRulesJamss extends JEDcheckerRule */ private function jamssWarning($path, $title, $info, $code, $line) { - $info = !empty($info)?sprintf($this->params->get('info'), htmlentities($info, ENT_QUOTES)):""; + $info = !empty($info) ? sprintf($this->params->get('info'), htmlentities($info, ENT_QUOTES)) : ''; $this->report->addWarning($path, $info . $title, $line, $code); } From c4543746427ec4fcdb8b40ef72324f15cd4d56b6 Mon Sep 17 00:00:00 2001 From: Denis Ryabov Date: Mon, 10 May 2021 20:17:25 +0300 Subject: [PATCH 7/7] switch to use of JEDCheckerHelper in jamss --- .../com_jedchecker/libraries/rules/jamss.php | 83 +------------------ 1 file changed, 4 insertions(+), 79 deletions(-) diff --git a/administrator/components/com_jedchecker/libraries/rules/jamss.php b/administrator/components/com_jedchecker/libraries/rules/jamss.php index c4bb8a9..43e456b 100644 --- a/administrator/components/com_jedchecker/libraries/rules/jamss.php +++ b/administrator/components/com_jedchecker/libraries/rules/jamss.php @@ -15,6 +15,9 @@ defined('_JEXEC') or die('Restricted access'); // Include the rule base class require_once JPATH_COMPONENT_ADMINISTRATOR . '/models/rule.php'; +// Include the helper class +require_once JPATH_COMPONENT_ADMINISTRATOR . '/libraries/helper.php'; + /** * JedcheckerRulesJamss * @@ -306,7 +309,7 @@ class JedcheckerRulesJamss extends JEDcheckerRule } else { - $content = $this->cleanComments($content); + $content = JEDCheckerHelper::cleanPhpCode($content, JEDCheckerHelper::CLEAN_COMMENTS); // Do a search for fingerprints foreach ($patterns As $pattern) @@ -433,82 +436,4 @@ class JedcheckerRulesJamss extends JEDcheckerRule $info = !empty($info) ? sprintf($this->params->get('info'), htmlentities($info, ENT_QUOTES)) : ''; $this->report->addWarning($path, $info . $title, $line, $code); } - - /** - * @param string $content - * - * @return string - */ - private function cleanComments($content) - { - if (!preg_match('/<\?php\s/i', $content, $match, PREG_OFFSET_CAPTURE)) - { - // No PHP code found - return $content; - } - - $pos = $match[0][1]; - $cleanContent = substr($content, 0, $pos); - - while (preg_match('/(?:[\'"]|\/\*|\/\/|\?>)/', $content, $match, PREG_OFFSET_CAPTURE, $pos)) - { - $foundPos = $match[0][1]; - $cleanContent .= substr($content, $pos, $foundPos - $pos); - $pos = $foundPos; - - switch ($match[0][0]) - { - case '"': - case "'": - $q = $match[0][0]; - - if (!preg_match("/$q(?>[^$q\\\\]+|\\\\.)*$q/As", $content, $match, 0, $pos)) - { - return $cleanContent . substr($content, $pos); - } - - $cleanContent .= $match[0]; - $pos += strlen($match[0]); - break; - - case '/*': - $cleanContent .= '/*'; - $pos += 2; - - $endPos = strpos($content, '*/', $pos); - - if ($endPos === false) - { - return $cleanContent; - } - - $cleanContent .= str_repeat("\n", substr_count(substr($content, $pos, $endPos - $pos), "\n")) . '*/'; - $pos = $endPos + 2; - - break; - - case '//': - $pos += strcspn($content, "\r\n", $pos); - break; - - case '?>': - $cleanContent .= '?>'; - $pos += 2; - - if (!preg_match('/<\?php\s/i', $content, $match, PREG_OFFSET_CAPTURE, $pos)) - { - // No PHP code found (up to the end of the file) - return $cleanContent . substr($content, $pos); - } - - $foundPos = $match[0][1]; - $cleanContent .= substr($content, $pos, $foundPos - $pos) . $match[0][0]; - $pos = $foundPos + strlen($match[0][0]); - - break; - } - } - - return $cleanContent; - } }