chore: adjustments to tasks.grunt.virustotal

This commit is contained in:
Aetherinox 2024-04-21 04:42:31 -07:00
parent a90f01d9b3
commit 1f081efd39
No known key found for this signature in database
GPG Key ID: CB5C4C30CD0D4028
1 changed files with 28 additions and 14 deletions

View File

@ -5,7 +5,7 @@ module.exports = function (grunt) {
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const fetch = require('node-fetch'); const got = require('got');
const FormData = require('form-data'); const FormData = require('form-data');
Promise.all( Promise.all(
@ -16,6 +16,16 @@ module.exports = function (grunt) {
) )
).then(done); ).then(done);
/*
convert to a more suitable time
*/
function formatMilliseconds(ms) {
const m = Math.floor(ms / 60000);
const s = ((ms % 60000) / 1000).toFixed(0);
return m + 'm ' + (s < 10 ? '0' : '') + s + 's';
}
async function checkFile(opt, file) { async function checkFile(opt, file) {
grunt.log.writeln(`Uploading to VirusTotal: ${file}...`); grunt.log.writeln(`Uploading to VirusTotal: ${file}...`);
@ -31,63 +41,67 @@ module.exports = function (grunt) {
const form = new FormData(); const form = new FormData();
form.append('file', fileData, fileName); form.append('file', fileData, fileName);
const fileUploadResp = await fetch('https://www.virustotal.com/api/v3/files', {
const fileUploadResp = await got('https://www.virustotal.com/api/v3/files', {
method: 'POST', method: 'POST',
headers, headers,
body: form body: form
}); }).json();
const fileUploadRespData = await fileUploadResp.json();
if (fileUploadRespData.error) { if (fileUploadResp.error) {
const errStr = JSON.stringify(fileUploadRespData.error); const errStr = JSON.stringify(fileUploadResp.error);
throw new Error(`File upload error: ${errStr}`); throw new Error(`File upload error: ${errStr}`);
} }
const id = fileUploadRespData.data.id; const id = fileUploadResp.data.id;
if (!id) { if (!id) {
throw new Error('File upload error: empty id'); throw new Error('File upload error: empty id');
} }
grunt.log.writeln(`Uploaded ${file} to VirusTotal, id: ${id}`); grunt.log.writeln(`\nUploaded ${file} to VirusTotal, id: ${id}`.grey.bold);
let elapsed; let elapsed;
do { do {
const checkResp = await fetch(`https://www.virustotal.com/api/v3/analyses/${id}`, { const checkResp = await fetch(`https://www.virustotal.com/api/v3/analyses/${id}`, {
headers headers
}); });
const checkRespData = await checkResp.json(); const checkRespData = await checkResp.json();
if (checkRespData.error) { if (checkRespData.error) {
const errStr = JSON.stringify(checkRespData.error); const errStr = JSON.stringify(checkRespData.error);
throw new Error(`File check error: ${errStr}`); throw new Error(`File check error: ${errStr}`.red.bold);
} }
const { attributes } = checkRespData.data; const { attributes } = checkRespData.data;
if (attributes.status === 'completed') { if (attributes.status === 'completed') {
const { stats } = attributes; const { stats } = attributes;
if (stats.malicious > 0) { if (stats.malicious > 0) {
throw new Error( throw new Error(
`File ${file} reported as malicious ${stats.malicious} time(s)` `File ${file} reported as malicious ${stats.malicious} time(s)`.yellow.bold
); );
} }
if (stats.suspicious > 0) { if (stats.suspicious > 0) {
throw new Error( throw new Error(
`File ${file} reported as malicious ${stats.suspicious} time(s)` `File ${file} reported as malicious ${stats.suspicious} time(s)`.red.bold
); );
} }
const statsStr = Object.entries(stats) const statsStr = Object.entries(stats)
.map(([k, v]) => `${k}=${v}`) .map(([k, v]) => `${k}=${v}`)
.join(', '); .join(', ');
grunt.log.writeln(`VirusTotal check OK: ${file}, stats:`, statsStr); grunt.log.writeln(`VirusTotal Check OK: ${file}, stats:`.green.bold, statsStr);
return; return;
} }
elapsed = Date.now() - timeStarted; elapsed = Date.now() - timeStarted;
const elapsedHuman = formatMilliseconds(elapsed);
grunt.log.writeln( grunt.log.writeln(
`VirusTotal check status: ${attributes.status}, elapsed ${elapsed}ms` `VirusTotal Status: ${attributes.status}, ${elapsedHuman}`.grey.bold
); );
await wait(interval); await wait(interval);
} while (elapsed < timeout); } while (elapsed < timeout);
throw new Error(`Timed out after ${timeout}ms`); throw new Error(`VirusTotal timed out after ${timeout}ms`.red.bold);
} }
function wait(ms) { function wait(ms) {