Skip to content

Commit fe468ce

Browse files
authored
Add file upload command to Intezer (#1561)
By @shaytidhar
1 parent 647f1d8 commit fe468ce

File tree

3 files changed

+663
-23
lines changed

3 files changed

+663
-23
lines changed

Integrations/integration-Intezer.yml

Lines changed: 157 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ commonfields:
33
version: -1
44
name: Intezer
55
display: Intezer
6-
category: Data Enrichment & Threat Intelligence
6+
releaseNotes: Add file upload command and update category
7+
category: Forensics & Malware Analysis
78
image: data:image/png;base64,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
89
description: Malware detection and analysis based on code reuse
910
detaileddescription: |
@@ -25,52 +26,82 @@ script:
2526
var SERVER_API = 'https://analyze.intezer.com/api/';
2627
var IS_AVAILABLE_URL = 'is-available';
2728
var HASH_URL = 'v1-2/analyze-by-sha256';
29+
var FILE_UPLOAD_URL = 'v1-2/analyze';
2830
var ANALYSIS_RESULT_URL = 'v1-2/analyses/';
2931
var SHA_256_REGEXP = new RegExp('[A-Fa-f0-9]{64}');
3032
var SUCCESS_STATUS = 'succeeded';
3133
var ERROR_PREFIX = 'Error from Intezer: ';
3234
33-
var sendRequest = function(method, url, parameters) {
35+
var sendRequest = function(method, url, body, acceptedCodes) {
3436
// handle '/' at the end of the url
3537
if (url[url.length - 1] === '/') {
3638
url = url.substring(0, url.length - 1);
3739
}
38-
if (!parameters) {
39-
parameters = {};
40+
if (!body) {
41+
body = {};
4042
}
41-
parameters.api_key = params.APIKey;
43+
body.api_key = params.APIKey;
4244
// no need to handle url query encoding in GET (as no such api in Intezer)
4345
var result = http(
4446
SERVER_API + url,
4547
{
4648
Headers: {'Content-Type': ['application/json'], 'Accept': ['application/json']},
4749
Method: method,
48-
Body: method == 'POST' ? JSON.stringify(parameters) : ''
50+
Body: method == 'POST' ? JSON.stringify(body) : ''
4951
},
5052
false,
5153
params.useproxy
5254
);
5355
56+
return handleResponse(result, url, acceptedCodes);
57+
}
58+
59+
var sendMultipartRequest = function(url, file, body) {
60+
// handle '/' at the end of the url
61+
if (url[url.length - 1] === '/') {
62+
url = url.substring(0, url.length - 1);
63+
}
64+
if (!body) {
65+
body = {};
66+
}
67+
body.api_key = params.APIKey;
68+
69+
var result = httpMultipart(
70+
SERVER_API + url,
71+
file,
72+
{
73+
Method: 'POST',
74+
Headers: {'Content-Type': ['multipart/form-data']},
75+
},
76+
body
77+
);
78+
79+
return handleResponse(result, url);
80+
};
81+
82+
var handleResponse = function(result, url, acceptedCodes) {
83+
var ignoreStatusCode = acceptedCodes && (acceptedCodes.indexOf(result.StatusCode) !== -1);
84+
5485
// validate response
55-
if (result.StatusCode < 200 || result.StatusCode > 299) {
86+
if (!ignoreStatusCode && (result.StatusCode < 200 || result.StatusCode > 299)) {
5687
switch (result.StatusCode) {
57-
case '400':
88+
case 400:
5889
throw ERROR_PREFIX + '400 Bad Request - Wrong or invalid parameters\n';
59-
case '401':
90+
case 401:
6091
throw ERROR_PREFIX + '401 Unauthorized - Wrong or invalid api key\n';
61-
case '403':
92+
case 403:
6293
throw ERROR_PREFIX + '403 Forbidden - The API key is not valid\n';
63-
case '404':
94+
case 404:
6495
throw ERROR_PREFIX + '404 Not Found - Access to expired analysis URL or sha256 not found for analysis by sha256\n';
65-
case '410':
96+
case 410:
6697
throw ERROR_PREFIX + '410 Gone - Analysis no longer exists in the service\n';
67-
case '413':
98+
case 413:
6899
throw ERROR_PREFIX + '413 Payload Too Large - Large request\n';
69-
case '415':
100+
case 415:
70101
throw ERROR_PREFIX + '415 Unsupported Media Type - Wrong or missing content type\n';
71-
case '500':
102+
case 500:
72103
throw ERROR_PREFIX + '500 Internal Server Error - Internal error\n';
73-
case '503':
104+
case 503:
74105
throw ERROR_PREFIX + '503 Service Unavailable\n';
75106
default:
76107
throw ERROR_PREFIX + 'Failed to perform request ' + SERVER_API + url + ', request status code: ' + result.StatusCode + '\n';
@@ -93,12 +124,12 @@ script:
93124
94125
var getAnalysis = function(analysisId) {
95126
var analysisRes = sendRequest('POST', ANALYSIS_RESULT_URL + analysisId);
127+
96128
return analysisRes.obj;
97129
};
98130
99131
var analyzeSHA256 = function(hash, codeItemType, maxRetries, delay) {
100132
// validate file is indeed sha256
101-
var entries = [];
102133
if (!SHA_256_REGEXP.test(hash)) {
103134
var warning = ERROR_PREFIX + 'File hash is not valid sha256.\nIntezer file hash reputation supports only sha256 hash.\n\n';
104135
return {
@@ -112,15 +143,57 @@ script:
112143
var res = sendRequest('POST', HASH_URL, {
113144
sha256: hash,
114145
code_item_type: codeItemType
115-
});
146+
}, [404]);
116147
117148
var analysisId;
118-
if (res.statusCode === 201) {
149+
150+
if (res.statusCode === 404) {
151+
var dBotScore = [{Indicator: hash, Type: 'hash', Vendor: 'Intezer', Score: 0}];
152+
var file = {
153+
SHA256: hash,
154+
ExistsInIntezer: false,
155+
Malicious: {
156+
Vendor: 'Intezer'
157+
}
158+
};
159+
var ec = {
160+
'File(val.SHA256==obj.SHA256)': file,
161+
DBotScore: dBotScore
162+
};
163+
164+
return [{
165+
Type: entryTypes.note,
166+
Contents: '',
167+
ContentsFormat: formats.json,
168+
HumanReadable: 'Hash ' + hash + ' does not exist on Intezer genome database',
169+
EntryContext: ec
170+
}];
171+
} else if (res.statusCode === 201) {
119172
analysisId = res.obj.analysis_id;
120173
} else {
121174
throw ERROR_PREFIX + 'Failed to create sha256 analysis for ' + hash + ', request status code: ' + res.statusCode + '\n';
122175
}
123176
177+
return waitForResponse(analysisId, maxRetries, delay);
178+
}
179+
180+
var analyzeUploadedFile = function(fileEntryId, codeItemType, maxRetries, delay) {
181+
var res = sendMultipartRequest(FILE_UPLOAD_URL, fileEntryId, {code_item_type: codeItemType});
182+
183+
var analysisId;
184+
185+
if (res.statusCode === 201) {
186+
analysisId = res.obj.analysis_id;
187+
} else {
188+
throw ERROR_PREFIX + 'Failed to create analysis, request status code: ' + res.statusCode + '\n';
189+
}
190+
191+
return waitForResponse(analysisId, maxRetries, delay);
192+
}
193+
194+
var waitForResponse = function(analysisId, maxRetries, delay) {
195+
var entries = [];
196+
124197
// perform wait loop
125198
res = getAnalysis(analysisId);
126199
var tries = 0;
@@ -133,10 +206,11 @@ script:
133206
134207
// if polling did not retrieve response after {delay * maxRetries} seconds, return an error message
135208
if (res.status !== SUCCESS_STATUS) {
136-
throw ERROR_PREFIX + 'Failed to pool sha256 analysis for ' + hash + ', Try to change maxRetries or delay arguments\n';
209+
throw ERROR_PREFIX + 'Failed to analyze, Try to change maxRetries or delay arguments\n';
137210
} else {
138211
// Create new indicator of sha256 according to verdict
139212
var verdict = res.result.verdict;
213+
var hash = res.result.sha256;
140214
var dbotScore = 0;
141215
var ec = {};
142216
ec[outputPaths.file] = [];
@@ -153,7 +227,14 @@ script:
153227
} else if (verdict === 'trusted' || verdict === 'neutral') {
154228
dbotScore = 1;
155229
}
156-
ec.DBotScore = [{Indicator: hash, Type: 'hash', Vendor: 'Intezer', Score: dbotScore}];
230+
var dBotScore = [{Indicator: hash, Type: 'hash', Vendor: 'Intezer', Score: dbotScore}];
231+
var file = {
232+
SHA256: hash,
233+
ExistsInIntezer: true,
234+
Malicious: {
235+
Vendor: 'Intezer'
236+
}
237+
};
157238
var data = res.result;
158239
var md = '## Intezer analysis result\n';
159240
md += 'SHA256: ' + hash + '\n';
@@ -169,7 +250,10 @@ script:
169250
Contents: res.body,
170251
ContentsFormat: formats.json,
171252
HumanReadable: md,
172-
EntryContext: ec
253+
EntryContext: {
254+
'File(val.SHA256==obj.SHA256)': file,
255+
DBotScore: dBotScore
256+
}
173257
});
174258
}
175259
@@ -181,7 +265,9 @@ script:
181265
// send is available
182266
return sendRequest('GET', IS_AVAILABLE_URL).obj.is_available;
183267
case 'file':
184-
return analyzeSHA256(args.file, args.codeItemType, args.maxRetries, args.delay);
268+
return analyzeSHA256(args.file, args.codeItuemType, args.maxRetries, args.delay);
269+
case 'intezer-upload':
270+
return analyzeUploadedFile(args.fileEntryId, args.codeItemType, args.maxRetries, args.delay);
185271
default:
186272
}
187273
type: javascript
@@ -226,5 +312,53 @@ script:
226312
- contextPath: DBotScore.Score
227313
description: The actual score
228314
type: number
315+
- contextPath: Intezer.File
316+
description: 'The file '
317+
type: unknown
318+
- contextPath: File.ExistsInIntezer
319+
description: 'File exists in Intezer genome database (in case file does not
320+
exist, consider upload the file) '
321+
type: boolean
229322
description: Checks file reputation of the given hash, supports SHA256
323+
- name: intezer-upload
324+
arguments:
325+
- name: fileEntryId
326+
required: true
327+
default: true
328+
description: The file entry id to upload
329+
- name: codeItemType
330+
auto: PREDEFINED
331+
predefined:
332+
- file
333+
- memory_module
334+
- fileless_code
335+
description: Item type - File (file), Memory Module (memory_module) or Memory
336+
Fileless Code (fileless_code)
337+
defaultValue: file
338+
- name: maxRetries
339+
description: Number of retries for polling the analysis report
340+
defaultValue: "60"
341+
- name: delay
342+
description: Delay in seconds between polling of analysis results
343+
defaultValue: "5"
344+
outputs:
345+
- contextPath: File.SHA256
346+
description: Bad hash SHA256
347+
type: string
348+
- contextPath: File.Malicious.Vendor
349+
description: For malicious files, the vendor that made the decision
350+
type: string
351+
- contextPath: DBotScore.Indicator
352+
description: The indicator we tested
353+
type: string
354+
- contextPath: DBotScore.Type
355+
description: The type of the indicator
356+
type: string
357+
- contextPath: DBotScore.Vendor
358+
description: Vendor used to calculate the score
359+
type: string
360+
- contextPath: DBotScore.Score
361+
description: The actual score
362+
type: number
363+
description: Checks file reputation for uploaded file (up to 20MB)
230364
runonce: false

0 commit comments

Comments
 (0)