Skip to content

Commit

Permalink
Finish 1.4.0-beta
Browse files Browse the repository at this point in the history
  • Loading branch information
sarus committed Jul 19, 2017
2 parents 1e92578 + 3296182 commit 3bee78b
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 38 deletions.
17 changes: 17 additions & 0 deletions config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ module.exports = {
*/
trackPendingLookups: false
},
request: {
// Provide the path to your certFile. Leave an empty string to ignore this option.
// Relative paths are relative to the VT integration's root directory
cert: '',
// Provide the path to your private key. Leave an empty string to ignore this option.
// Relative paths are relative to the VT integration's root directory
key: '',
// Provide the key passphrase if required. Leave an empty string to ignore this option.
// Relative paths are relative to the VT integration's root directory
passphrase: '',
// Provide the Certificate Authority. Leave an empty string to ignore this option.
// Relative paths are relative to the VT integration's root directory
ca: '',
// An HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for
// the url parameter (by embedding the auth info in the uri)
proxy: ''
},
logging: {
// directory is relative to the this integrations directory
// e.g., if the integration is in /app/polarity-server/integrations/virustotal
Expand Down
140 changes: 103 additions & 37 deletions integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ let net = require('net');
let config = require('./config/config');
let async = require('async');
let PendingLookupCache = require('./lib/pending-lookup-cache');
let fs = require('fs');

let Logger;
let pendingLookupCache;

let doLookupLogging;
let lookupHashSet;
let lookupIpSet;

let requestOptionsIp = {};
let requestOptionsHash = {};

const debugLookupStats = {
hourCount: 0,
dayCount: 0,
Expand All @@ -23,6 +28,11 @@ const debugLookupStats = {
hashLookups: 0
};

const IGNORED_IPS = new Set([
'127.0.0.1',
'255.255.255.255',
'0.0.0.0'
]);

const HASH_LOOKUP_URI = "https://www.virustotal.com/vtapi/v2/file/report";
const IP_LOOKUP_URI = "https://www.virustotal.com/vtapi/v2/ip-address/report";
Expand Down Expand Up @@ -73,7 +83,7 @@ function doLookup(entities, options, cb) {
if (doLookupLogging === true) {
lookupHashSet.add(entity.value);
}
} else if (entity.isIPv4 && !entity.isPrivateIP && options.lookupIps) {
} else if (entity.isIPv4 && !entity.isPrivateIP && !IGNORED_IPS.has(entity.value) && options.lookupIps) {
if (doLookupLogging === true) {
lookupIpSet.add(entity.value);
}
Expand Down Expand Up @@ -153,7 +163,10 @@ function doLookup(entities, options, cb) {
combinedResults.push(lookupResult)
});


pendingLookupCache.logStats();


cb(null, combinedResults);
});
}
Expand All @@ -163,7 +176,9 @@ function doLookup(entities, options, cb) {
function _handleRequestError(err, response, body, options, cb) {
if (err) {
cb(_createJsonErrorPayload("Unable to connect to VirusTotal server", null, '500', '2A', 'VirusTotal HTTP Request Failed', {
err: err
err: err,
response: response,
body: body
}));
return;
}
Expand All @@ -190,7 +205,10 @@ function _handleRequestError(err, response, body, options, cb) {
if (body) {
cb(body);
} else {
cb(response.statusMessage);
cb(_createJsonErrorPayload(response.statusMessage, null, response.statusCode, '2A', 'VirusTotal HTTP Request Failed', {
response: response,
body: body
}));
}
return;
}
Expand All @@ -204,18 +222,20 @@ function _lookupHash(hashesArray, entityLookup, options, done) {
}

//do the lookup
request({
uri: HASH_LOOKUP_URI,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-encoded'
},
form: {
"apikey": options.apiKey,
"resource": hashesArray.join(', ')
},
json: true
}, function (err, response, body) {
requestOptionsHash.uri = HASH_LOOKUP_URI;
requestOptionsHash.method = 'POST';
requestOptionsHash.headers = {
'Content-Type': 'application/x-www-form-encoded'
};
requestOptionsHash.form = {
"apikey": options.apiKey,
"resource": hashesArray.join(', ')
};
requestOptionsHash.json = true;

//Logger.debug({requestOptionsHash: requestOptionsHash}, 'Request Options for Hash Lookup');

request(requestOptionsHash, function (err, response, body) {
_handleRequestError(err, response, body, options, function (err, body) {
if (err) {
Logger.error({err: err}, 'Error Looking up Hash');
Expand All @@ -241,9 +261,11 @@ function _lookupHash(hashesArray, entityLookup, options, done) {
function _processHashLookupItem(virusTotalResultItem, entityLookupHash, hashLookupResults) {
let entity = entityLookupHash[virusTotalResultItem.resource.toLowerCase()];

if (virusTotalResultItem.response_code === 1) {
if (virusTotalResultItem.response_code === 1 ||
(virusTotalResultItem.positives === 0 && virusTotalResultItem.total === 0)) {
virusTotalResultItem.type = 'file';
Logger.debug({hash: entity.value}, 'Had Result');

hashLookupResults.push({
entity: entity,
data: {
Expand All @@ -252,7 +274,8 @@ function _processHashLookupItem(virusTotalResultItem, entityLookupHash, hashLook
details: virusTotalResultItem
}
});
} else if (virusTotalResultItem.response_code === 0) {
} else if (virusTotalResultItem.response_code === 0 ||
(virusTotalResultItem.positives === 0 && virusTotalResultItem.total === 0)) {
Logger.debug({hash: entity.value}, 'No Result');
hashLookupResults.push({
entity: entity,
Expand All @@ -269,15 +292,18 @@ function _lookupIp(ipEntity, options, done) {
debugLookupStats.ipLookups++;
}

request({
uri: IP_LOOKUP_URI,
method: 'GET',
qs: {
"apikey": options.apiKey,
"ip": ipEntity.value
},
json: true
}, function (err, response, body) {
//do the lookup
requestOptionsIp.uri = IP_LOOKUP_URI;
requestOptionsIp.method = 'GET';
requestOptionsIp.qs = {
"apikey": options.apiKey,
"ip": ipEntity.value
};
requestOptionsIp.json = true;

//Logger.debug({requestOptionsIp:requestOptionsIp}, 'Options for IP Lookup');

request(requestOptionsIp, function (err, response, body) {
_handleRequestError(err, response, body, options, function (err, result) {
if (err) {
Logger.error({err: err}, 'Error Looking up IP');
Expand Down Expand Up @@ -328,17 +354,27 @@ function _processIpLookupItem(virusTotalResultItem, ipEntity, ipLookupResults) {
if (virusTotalResultItem.response_code === 1) {
// Compute the details
let details = _computeIpDetails(virusTotalResultItem);
Logger.debug({ip: ipEntity.value}, 'Had Result');
ipLookupResults.push({
entity: ipEntity,
data: {
summary: [
util.format("%d <i class='bts bt-globe integration-text-bold-color'></i>", details.numResolutions),
util.format("%d <i class='fa fa-bug integration-text-bold-color'></i> / %d", details.overallPositives, details.overallTotal)
],
details: details
}
});

if(details.numResolutions === 0 && details.overallPositives === 0 && details.overallTotal === 0){
Logger.debug({ip: ipEntity.value}, 'No Positive Detections or Resolutions');
// This was an empty result so we just push a null data value
ipLookupResults.push({
entity: ipEntity,
data: null
})
}else{
Logger.debug({ip: ipEntity.value}, 'Had Result');
ipLookupResults.push({
entity: ipEntity,
data: {
summary: [
util.format("%d <i class='bts bt-globe integration-text-bold-color'></i>", details.numResolutions),
util.format("%d <i class='fa fa-bug integration-text-bold-color'></i> / %d", details.overallPositives, details.overallTotal)
],
details: details
}
});
}
} else if (virusTotalResultItem.response_code === 0) {
Logger.debug({ip: ipEntity.value}, 'No Result');
// This was an empty result so we just push a null data value
Expand Down Expand Up @@ -467,6 +503,36 @@ function startup(logger) {
if(config && config.settings && config.settings.trackPendingLookups){
pendingLookupCache.setEnabled(true);
}

if(typeof config.request.cert === 'string' && config.request.cert.length > 0){
requestOptionsIp.cert = fs.readFileSync(config.request.cert);
requestOptionsHash.cert = fs.readFileSync(config.request.cert);
}

if(typeof config.request.key === 'string' && config.request.key.length > 0){
requestOptionsIp.key = fs.readFileSync(config.request.key);
requestOptionsHash.key = fs.readFileSync(config.request.key);
}

if(typeof config.request.passphrase === 'string' && config.request.passphrase.length > 0){
requestOptionsIp.passphrase = config.request.passphrase;
requestOptionsHash.passphrase = config.request.passphrase;
}

if(typeof config.request.ca === 'string' && config.request.ca.length > 0){
requestOptionsIp.ca = fs.readFileSync(config.request.ca);
requestOptionsHash.ca = fs.readFileSync(config.request.ca);
}else if(Array.isArray(config.request.ca)){
requestOptionsIp
}

if(typeof config.request.proxy === 'string' && config.request.proxy.length > 0){
requestOptionsIp.proxy = config.request.proxy;
requestOptionsHash.proxy = config.request.proxy;
}

// Logger.info({requestOptionsIp: requestOptionsIp}, 'requestOptionsIp after load');
// Logger.info({requestOptionsHash: requestOptionsHash}, 'requestOptionsHash after load');
}

function _logLookupStats() {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"main": "./integration.js",
"name": "VirusTotal",
"version": "1.2.0-beta",
"version": "1.4.0-beta",
"private": true,
"options": [
{
Expand Down

0 comments on commit 3bee78b

Please sign in to comment.