-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathindex.js
121 lines (108 loc) · 5.35 KB
/
index.js
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
module.exports = [
{
id: 'P64:general:obfuscation:scripts_with_base64',
name: 'Matches any script containing base64-encoded strings',
description: 'Malicious scripts often use base64 to encode their payloads. While there are of course legitimate purposes for base64-encoded strings within scripts, their presence is cause for suspicion.',
urls: ['https://www.polaris64.net/blog/cyber-security/2017/hidden-in-plain-sight-how-attackers-use-obfuscation-to-hide-code'],
deprecated: false,
tags: ['suspicion', 'general', 'obfuscation', 'base64'],
tests: {
path: (f) => {
return !!f.match(/\.(js|aspx?|ph[p34][34]?)$/i)
},
content: (content) => {
const re = /([A-Za-z0-9+/]|[A-Za-z0-9+,]|[A-Za-z0-9_-]|[A-Za-z0-9.-]|[A-Za-z0-9._]|[A-Za-z0-9_:]|[A-Za-z0-9~-]){3,}={0,2}/g;
let matches = null;
do {
matches = re.exec(content);
if (matches && matches.length > 0 && matches[0].length > 25)
{
// Make sure match is not a common structure
if (
// Path
!matches[0].match(/^([a-z0-9_.-]+\/)+([a-z0-9_.-]+)?$/i) &&
// A,list,of,words,or,numbers,10 and list.with.periods
!matches[0].match(/^(([a-z0-9]+,)+[a-z0-9]+,?|([a-z0-9]+\.)+[a-z0-9]+\.?)$/i) &&
// //comment
!matches[0].match(/\/\/[a-z0-9_:,+/-]+$/i) &&
// Word with ellipsis...
!matches[0].match(/^[a-z0-9_+.,:/-]+\.\.\.$/i) &&
// __dunder
!matches[0].match(/^__[a-z][a-z0-9_-]+$/i) &&
// Snake_case or kebab-case
!matches[0].match(/^(([a-z0-9]+_)+[a-z0-9]+_?|([a-z0-9]+-)+[a-z0-9]+-?)$/i) &&
// Class::StaticVar
!matches[0].match(/^[a-z][a-z0-9]*::[a-z][a-z0-9]*$/i) &&
// String from A-Z, 0-9, and list of all base64 characters
!matches[0].match(/^((abcdefghijklmnopqrstuvwxyz)+(0123456789+)(\+\/|\/\+)?|(0123456789)+(abcdefghijklmnopqrstuvwxyz)+(\+\/|\/\+)?|(abcdefghijklmnopqrstuvwxyz)+(1234567890)+(\+\/|\/\+)?|(1234567890)+(abcdefghijklmnopqrstuvwxyz)+(\+\/|\/\+)?)$/i) &&
// Hexadecimal characters only
!matches[0].match(/^[a-f0-9]+$/i) &&
// Hexadecimal number
!matches[0].match(/^0x[a-f0-9]+$/i) &&
// CSS
!matches[0].match(/^[a-z-]+:[a-z0-9_()-]+$/i)
)
{
// Try to decode base64
const buf = Buffer.from(matches[0], 'base64');
if (buf && buf.toString('base64') === matches[0])
{
// Must have > 5 [a-z] and > 0 [0-9] characters
const alpha_match = matches[0].match(/[a-zA-Z]/g);
const num_match = matches[0].match(/[0-9]/g);
if ((alpha_match && alpha_match.length) > 5 && (num_match && num_match.length > 0))
return true;
}
}
}
} while (matches);
return false;
},
},
},
{
id: 'P64:general:obfuscation:scripts_with_escaped_ascii',
name: 'Matches any script containing strings with hexadecimal escape codes for standard ASCII characters',
description: 'Malicious scripts will often use escape sequences to obfuscate strings. It is rare for a legitimate script to use an escape sequence to encode a standard ASCII character as a hexadecimal reference as this takes four times more space than simply writing the character directly. This rule detects the presence of such obfuscation in script files (ASCII range 0x20..0x7F).',
urls: ['https://www.polaris64.net/blog/cyber-security/2017/hidden-in-plain-sight-how-attackers-use-obfuscation-to-hide-code'],
deprecated: false,
tags: ['suspicion', 'general', 'obfuscation', 'escape-sequences'],
tests: {
path: (f) => {
return !!(
f.match(/\.(js|aspx?|php)$/i) &&
// Exclude known SwiftMailer files
!f.match(/classes\/Swift\/Mime\/Headers\/ParameterizedHeader\.php$/i) &&
!f.match(/Swift\/Encoder\/Rfc2231EncoderTest\.php$/i)
)
},
content: (content) => {
// Match if lines contains a sequence of 3 or more escaped standard
// ASCII characters and no escaped non-standard characters
return !!(content.match(/(\\x[2-7][0-9A-F]){3,}/i) && !content.match(/(\\x([0-1]|[8-9A-F])[0-9A-F])+/i));
},
},
},
{
id: 'P64:general:tags:hacked_by',
name: 'Matches any script or page containing phrases similar to "hacked by"',
description: 'Attackers will often leave a "calling card" in a file contents, either as a comment or as a string to be output. This rule looks for many common strings that match this pattern.',
urls: null,
deprecated: false,
tags: ['suspicion', 'general', 'tags', 'hacked_by'],
tests: {
path: /(\.aspx?$|\.php$|\.jsx?$|\.html?$)/i,
content: (content) => {
return !!(
content.match(/h[a4](x+|ck)([0o]r)?ed[^a-z0-9]*\s*by/i) ||
content.match(/(h4x+([o0]r)?[e3]d|h4(ck)([o0]r)?[e3]d)/i) ||
content.match(/(l33t|1337).*h[a4](ck|x+)/i) ||
content.match(/h[a4](ck|x+).*(l33t|1337)/i) ||
content.match(/pwn([a4]g[e3]|[e3]d|t)/i) ||
content.match(/([o0]wn[a4]g[e3]|0wn[e3]d|own3d)/i) ||
content.match(/n00bz?/i)
);
},
},
},
];