// Use pt-enrichment for IP, URL and domain enrichment if (command === 'url' || command === 'ip' || command === 'domain') { if (command === 'url') { // Need to extract the domain from the URL var u = args.url.toLowerCase(); // Strip prefix u = u.replace('http://', '').replace('https://', '').replace('hxxp://', '').replace('hxxps://', ''); // Strip path and everything after if (u.indexOf('/') > 0) { u = u.substring(0, u.indexOf('/')); } // Strip parameters and after just in case there is no path separator if (u.indexOf('?') > 0) { u = u.substring(0, u.indexOf('?')); } // Strip credentials if (u.indexOf('@') > 0) { u = u.substring(u.indexOf('@') + 1); } // Strip port if (u.indexOf(':') > 0) { u = u.substring(0, u.indexOf(':')); } args.query = u; delete args.url; } else if (command === 'domain') { args.query = args.domain; delete args.domain; } else { args.query = args.ip; delete args.ip; } command = 'pt-enrichment'; } var serverUrl = params.ServerURL; if (serverUrl[serverUrl.length - 1] !== '/') { serverUrl += '/'; } if (!params.hasOwnProperty('proxy')) { params.proxy = true; } // Handle upgrade scenarios where there is no default var tags = params.tags; if (tags === undefined) { tags = 'malware,blacklist,phishing,typo-squatting'; } var doReq = function(method, path, parameters, body) { var result = http( serverUrl + path + encodeToURLQuery(parameters), { Headers: {'Content-Type': ['application/json']}, Method: method, Username: params.Username, Password: params.APIKey, Body: body ? body : '' }, params.insecure || false, params.proxy ); if (result.StatusCode !== 200 && result.StatusCode !== 201) { throw 'Failed to perform request ' + path + ', request status code: ' + result.StatusCode + ', request body: ' + result.Body; } return result.Body; }; var commandToPath = { 'pt-get-subdomains': 'v2/enrichment/subdomains', 'pt-account': 'v2/account', 'pt-monitors': 'v2/account/monitors', 'pt-passive-dns': 'v2/dns/passive', 'pt-passive-unique': 'v2/dns/passive/unique', 'pt-dns-keyword': 'v2/dns/search/keyword', 'pt-enrichment': 'v2/enrichment', 'pt-malware': 'v2/enrichment/malware', 'pt-osint': 'v2/enrichment/osint', 'pt-whois': 'v2/whois', 'pt-whois-keyword': 'v2/whois/search/keyword', 'pt-whois-search': 'v2/whois/search', 'pt-get-components': 'v2/host-attributes/components', 'pt-get-pairs': 'v2/host-attributes/pairs', 'pt-ssl-cert': 'v2/ssl-certificate', 'pt-ssl-cert-history': 'v2/ssl-certificate/history', 'pt-ssl-cert-keyword': 'v2/ssl-certificate/search/keyword', 'pt-ssl-cert-search': 'v2/ssl-certificate/search' }; // This is the call made when pressing the integration test button. if (command === 'test-module') { var res = doReq('GET', 'v2/account'); if (JSON.parse(res).username) return true; throw 'Unable to retrieve username'; } var res = doReq('GET', commandToPath[command], args); var jsonRes = JSON.parse(res); // The command input arg holds the command sent from the user. switch (command) { case 'pt-get-subdomains': var md = '## Subdomains for ' + args.query + '\n'; md += objToMd(jsonRes); return {Type: entryTypes.note, Contents: jsonRes, ContentsFormat: formats.json, HumanReadable: md, EntryContext: {subdomains: jsonRes.subdomains}}; case 'pt-account': var md = '## PassiveTotal Account\n'; md += objToMd(jsonRes); return {Type: entryTypes.note, Contents: jsonRes, ContentsFormat: formats.json, HumanReadable: md, EntryContext: {'passivetotal.username': jsonRes.username}}; case 'pt-monitors': var md = '## PassiveTotal Monitors\n'; md += arrToMd(jsonRes); return {Type: entryTypes.note, Contents: jsonRes, ContentsFormat: formats.json, HumanReadable: md}; case 'pt-passive-dns': var md = '## PassiveTotal Passive DNS for ' + args.query + ' [' + jsonRes.queryType + '] - total: ' + jsonRes.totalRecords + '\n'; if (jsonRes.pager) { md += 'Pager:\n'; md += objToMd(jsonRes.pager) + '\n'; } var contextDomain = {Name: args.query, DNS: []}; if (jsonRes.results && jsonRes.results.length > 0) { md += 'Query Type | First Seen | Last Seen\n'; md += '---------- | ---------- | ---------\n'; md += jsonRes.queryType + ' | ' + jsonRes.firstSeen + ' | ' + jsonRes.lastSeen + '\n\n'; md += 'Source | Resolve | First Seen | Last Seen\n'; md += '------ | ------- | ---------- | ---------\n'; for (var i=0; i 0) { var frequency = jsonRes.frequency.reduce(function(f, v) {f[v[0]] = v[1]; return f;}, {}); md += 'Result | Frequency\n'; md += '------ | ---------\n'; for (var i=0; i 0) { md += arrToMd(jsonRes.results); } else { md += 'No results found!'; } return {Type: entryTypes.note, Contents: jsonRes, ContentsFormat: formats.json, HumanReadable: md}; case 'pt-enrichment': var md = '## PassiveTotal Metadata Enrichment for: ' + args.query + '\n'; var mal = false; if (jsonRes.classification === 'malicious') { mal = true; } else { var badTags = argToList(tags); var allTags = [jsonRes.tags, jsonRes.system_tags, jsonRes.global_tags]; for (var i=0; i= 0) { mal = true; } } } } jsonKeys = Object.keys(jsonRes); if (jsonKeys.length > 20) { limit = 20; } else { limit = jsonKeys.length; } var jsonMd = {}; for (var i=0; i 0) { // Sort based on date to display the latest jsonRes.results.sort(function(a, b) { if (a.collectionDate < b.collectionDate) { return 1; } else if (a.collectionDate > b.collectionDate) { return -1; } return 0; }); md += 'Source | Sample | Date\n'; md += '------ | ------ | ----\n'; for (var i=0; i= args.threshold) { dbotScore = 3; if (isIp(args.query)) { addMalicious(context, outputPaths.ip, { Address: args.query, Malicious: {Vendor: 'PassiveTotal', Description: 'Recent sample count: ' + recentSampleCount} }); } else { addMalicious(context, outputPaths.domain, { Name: args.query, Malicious: {Vendor: 'PassiveTotal', Description: 'Recent sample count: ' + recentSampleCount} }); } } else if (recentSampleCount >= args.threshold / 2) { dbotScore = 2; } else { dbotScore = 1; } context.DBotScore.push({Indicator: args.query, Type: 'domain', Vendor: 'PassiveTotal', Score: dbotScore}); } else { md += 'No results found!'; } return {Type: entryTypes.note, Contents: jsonRes, ContentsFormat: formats.json, HumanReadable: md, EntryContext: context}; case 'pt-osint': var md = '## PassiveTotal OSINT Report for: ' + args.query + '\n'; if (jsonRes.results && jsonRes.results.length > 0) { md += 'Source | Report | Tags\n'; md += '------ | ------ | ----\n'; for (var i=0; i 0) { md += 'Focus Point | Match Type | Field\n'; md += '----------- | ---------- | -----\n'; for (var i=0; i 0) { for (var i=0; i 0) { md += 'Category | Label | First Seen | Last Seen | Hostname\n'; md += '-------- | ----- | ---------- | --------- | --------\n'; for (var i=0; i 0) { md += 'Parent | Child | Cause | First Seen | Last Seen\n'; md += '------ | ----- | ----- | ---------- | ---------\n'; for (var i=0; i