PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / behavior / scan / malware-quick-scan.php

malware-quick-scan.php in Defender Security – Malware Scanner, Login Security & Firewall 3.0.1, at src/behavior/scan/malware-quick-scan.php

162 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WP_Defender\Behavior\Scan;
4
5 use Calotes\Component\Behavior;
6 use WP_Defender\Traits\IO;
7
8 /**
9 * This will fast travel all yara rules to quickly get files seem suspicious, this is catchy.
10 *
11 * Class Malware_Quick_Scan
12 * @package WP_Defender\Behavior\Scan
13 */
14 class Malware_Quick_Scan extends Behavior {
15 use IO;
16
17 private $content;
18
19 /**
20 * @param $file
21 * @param $rules
22 *
23 * @return array|void
24 */
25 public function do_quick_scan( $file, $rules ) {
26 if ( ! file_exists( $file ) ) {
27 return;
28 }
29 $content = file_get_contents( $file );
30 $this->content = $content;
31 $total_issues = 0;
32 $qs_detail = [];
33 foreach ( $rules as $rule ) {
34 $strings = $rule['strings'];
35 $local_issues = [
36 'identifier' => $rule['identifier'],
37 'catches' => []
38 ];
39 foreach ( $strings as $string ) {
40 $offset = false;
41 if ( $string['type'] == 0 ) {
42 $offset = strpos( $content, $string['text'] );
43 $text = $string['text'];
44 } else {
45 $pattern = "/{$string['text']}/";
46 $is_match = preg_match_all( $pattern, $content, $matches,
47 PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE );
48 if ( $is_match ) {
49 $offset = $matches[0][0][1];
50 $text = $matches[0][0][0];
51 }
52 }
53 if ( false === $offset ) {
54 continue;
55 }
56 $local_issues['catches'] [] = [
57 'id' => $string['id'],
58 'text' => $text,
59 'offset' => $offset
60 ];
61 }
62 if ( empty( $local_issues['catches'] ) ) {
63 continue;
64 }
65
66 if ( $this->condition_valid( $local_issues['catches'], $rule ) ) {
67 $total_issues ++;
68 $qs_detail[] = $local_issues;
69 }
70 }
71
72 return [ $total_issues, $qs_detail ];
73 }
74
75 /**
76 * Parse the condition to see if this is an issue or not.
77 *
78 * @param $found
79 * @param $rule
80 *
81 * @return bool
82 */
83 private function condition_valid( $found, $rule ) {
84 $condition = explode( 'and', $rule['condition'] );
85 $count = 0;
86 foreach ( $condition as $item ) {
87 $patterns = [
88 'x_of_them' => '/([a-z0-9]+)\s*of\s*(.*)/',
89 'id_at_pos' => '/(\$[a-zA-Z0-9]+)\s*at\s*(\d+)/',
90 //'not_x' => '/not\s*(\$[a-z0-9]+)/'
91 ];
92 foreach ( $patterns as $func => $pattern ) {
93 if ( preg_match( $pattern, $item, $match ) ) {
94 $count ++;
95 $ret = $this->$func( $found, $match, $rule );
96 if ( false === $ret ) {
97
98 return false;
99 }
100 }
101 }
102 }
103 if ( $count === 0 ) {
104 $this->log( $rule['identifier'], 'malware_scan.log' );
105 $this->log( var_export( $found, true ), 'malware_scan.log' );
106
107 return false;
108 }
109
110 return true;
111 }
112
113 /**
114 * This will parse the condition x of y.
115 *
116 * @param $found
117 * @param $match
118 * @param $rule
119 *
120 * @return bool
121 */
122 private function x_of_them( $found, $match, $rule ) {
123 $num = $match[1];
124 $num = 'all' === $num ? count( $rule['strings'] ) : $num;
125 $num = 'any' === $num ? 1 : $num;
126
127 if ( '(s*)' == $match[2] ) {
128 // Hard code in this situation.
129 $num -= 1;
130 }
131 //$this->log( sprintf( 'num %s', $num ), 'malware_scan.log' );
132 //$this->log( sprintf( 'count %s', count( $found ) ), 'malware_scan.log' );
133
134 return (is_array($found) || $found instanceof \Countable ? count( $found ) : 0) >= $num;
135 }
136
137 /**
138 * @param $found
139 * @param $match
140 * @param $rule
141 *
142 * @return bool
143 */
144 private function id_at_pos( $found, $match, $rule ) {
145 // Get the text to check.
146 foreach ( $found as $item ) {
147 if ( $item['id'] === $match[1] ) {
148 return strpos( $this->content, $item['text'] ) == $match[2];
149 }
150 }
151
152 return false;
153 }
154
155 private function not_x( $found, $match, $rule ) {
156 $this->log( 'not x', 'malware_scan.log' );
157 $this->log( var_export( $match, true ), 'malware_scan.log' );
158
159 return true;
160 }
161 }
162