-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathBinaryCheckModule.php
More file actions
169 lines (143 loc) · 4.61 KB
/
Copy pathBinaryCheckModule.php
File metadata and controls
169 lines (143 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
<?php
namespace CleantalkSP\SpbctWP\Scanner\BinaryCheckModule;
class BinaryCheckModule
{
/**
* @var int Total count of binary files for analysis
*/
private $total_count = 0;
/**
* @var int Count of scanned files
*/
private $scanned_count = 0;
/**
* @var array Statuses of scanned files
*/
private $statuses = array();
/**
* Runs the BinaryCheckModule to find malicious binary files.
* @return array Analysis results
*/
public function run()
{
$this->total_count = 0;
$this->scanned_count = 0;
$this->statuses = array();
$binary_files = $this->getBinaryFiles();
$this->total_count = count($binary_files);
$this->analyzeBinaryFiles($binary_files);
return array(
'success' => true,
'end' => 1,
'total_count' => $this->total_count,
'scanned_count' => $this->scanned_count,
'statuses' => $this->statuses,
);
}
/**
* @return array
*/
public function getBinaryFiles()
{
global $wpdb;
$binary_files = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM " . SPBC_TBL_SCAN_FILES . " WHERE source = %s",
'BINARY'
)
);
return $binary_files ?: array();
}
/**
* @param array $binary_files
* @return void
*/
private function analyzeBinaryFiles($binary_files)
{
foreach ($binary_files as $binary_file) {
$path = realpath(ABSPATH . $binary_file->path);
if (!$path || !file_exists($path)) {
$this->incrementStatus('SKIPPED_NOT_FOUND');
continue;
}
if (!is_readable($path)) {
$this->incrementStatus('SKIPPED_NOT_READABLE');
continue;
}
$isCritical = $this->analyzeBinaryFile($path);
$this->scanned_count++;
if ($isCritical) {
$this->markAsCritical($binary_file->path);
$this->incrementStatus('CRITICAL');
} else {
$this->incrementStatus('OK');
}
}
}
/**
* @param string $status
* @return void
*/
private function incrementStatus($status)
{
if (!isset($this->statuses[$status])) {
$this->statuses[$status] = 0;
}
$this->statuses[$status]++;
}
private function analyzeBinaryFile($binary_file_path)
{
// Read first bytes of the file (we need at least 4 bytes for all checks)
$handle = fopen($binary_file_path, 'rb');
if (!$handle) {
return false;
}
// Read first 4 bytes
$first_bytes = fread($handle, 4);
fclose($handle);
if (strlen($first_bytes) < 4) {
return false;
}
// Method 1: Check using ord() to get byte values
$byte1 = ord($first_bytes[0]);
$byte2 = ord($first_bytes[1]);
$byte3 = ord($first_bytes[2]);
$byte4 = ord($first_bytes[3]);
// Check for ELF (0x7F followed by "ELF" = 0x45 0x4C 0x46)
if ($byte1 === 0x7F && $byte2 === 0x45 && $byte3 === 0x4C && $byte4 === 0x46) {
return true; // ELF file detected
}
// Check for PE/MZ (Windows executable: 0x4D 0x5A = "MZ")
if ($byte1 === 0x4D && $byte2 === 0x5A) {
return true; // PE file detected
}
// Check for MACHO (macOS/iOS executables)
// 32-bit big-endian: 0xFE 0xED 0xFA 0xCE
// 32-bit little-endian: 0xCE 0xFA 0xED 0xFE
// 64-bit big-endian: 0xFE 0xED 0xFA 0xCF
// 64-bit little-endian: 0xCF 0xFA 0xED 0xFE
$macho_signatures = array(
array(0xFE, 0xED, 0xFA, 0xCE), // 32-bit big-endian
array(0xCE, 0xFA, 0xED, 0xFE), // 32-bit little-endian
array(0xFE, 0xED, 0xFA, 0xCF), // 64-bit big-endian
array(0xCF, 0xFA, 0xED, 0xFE), // 64-bit little-endian
);
foreach ($macho_signatures as $signature) {
if ($byte1 === $signature[0] && $byte2 === $signature[1] &&
$byte3 === $signature[2] && $byte4 === $signature[3]) {
return true; // MACHO file detected
}
}
return false;
}
private function markAsCritical($binary_file_path)
{
global $wpdb;
$wpdb->query(
$wpdb->prepare(
"UPDATE " . SPBC_TBL_SCAN_FILES . " SET status = 'INFECTED', severity = 'CRITICAL' WHERE path = %s",
$binary_file_path
)
);
}
}