diff --git a/analyzers/Zetalytics/Zetalytics_cname2qname.json b/analyzers/Zetalytics/Zetalytics_cname2qname.json new file mode 100644 index 000000000..0cd5f2853 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_cname2qname.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_cname2qname", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for cname2qname", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "cname2qname" + } +} diff --git a/analyzers/Zetalytics/Zetalytics_domain2aaaa.json b/analyzers/Zetalytics/Zetalytics_domain2aaaa.json new file mode 100644 index 000000000..06597ef88 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2aaaa.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2aaaa", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2aaaa", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2aaaa" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2cname.json b/analyzers/Zetalytics/Zetalytics_domain2cname.json new file mode 100644 index 000000000..779622535 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2cname.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2cname", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2cname", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2cname" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2d8s.json b/analyzers/Zetalytics/Zetalytics_domain2d8s.json new file mode 100644 index 000000000..f6d02c928 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2d8s.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2d8s", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2d8s", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2d8s" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2ip.json b/analyzers/Zetalytics/Zetalytics_domain2ip.json new file mode 100644 index 000000000..bcd85fef0 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2ip.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2ip", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2ip", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2ip" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2malwaredns.json b/analyzers/Zetalytics/Zetalytics_domain2malwaredns.json new file mode 100644 index 000000000..e844df9cc --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2malwaredns.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2malwaredns", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2malwaredns", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2malwaredns" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2malwarehttp.json b/analyzers/Zetalytics/Zetalytics_domain2malwarehttp.json new file mode 100644 index 000000000..373ab3e30 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2malwarehttp.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2malwarehttp", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2malwarehttp", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2malwarehttp" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2mx.json b/analyzers/Zetalytics/Zetalytics_domain2mx.json new file mode 100644 index 000000000..3afda15ce --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2mx.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2mx", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2mx", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2mx" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2ns.json b/analyzers/Zetalytics/Zetalytics_domain2ns.json new file mode 100644 index 000000000..a44b34bc0 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2ns.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2ns", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2ns", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2ns" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2nsglue.json b/analyzers/Zetalytics/Zetalytics_domain2nsglue.json new file mode 100644 index 000000000..09a573453 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2nsglue.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2nsglue", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2nsglue", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2nsglue" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2ptr.json b/analyzers/Zetalytics/Zetalytics_domain2ptr.json new file mode 100644 index 000000000..f0f6fd3ba --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2ptr.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2ptr", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2ptr", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2ptr" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2txt.json b/analyzers/Zetalytics/Zetalytics_domain2txt.json new file mode 100644 index 000000000..1f812a774 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2txt.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2txt", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2txt", + "dataTypeList": ["domain","fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2txt" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_domain2whois.json b/analyzers/Zetalytics/Zetalytics_domain2whois.json new file mode 100644 index 000000000..bf421fad0 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_domain2whois.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_domain2whois", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for domain2whois", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "domain2whois" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_email-address.json b/analyzers/Zetalytics/Zetalytics_email-address.json new file mode 100644 index 000000000..c0c095a08 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_email-address.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_email_address", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for email_address", + "dataTypeList": ["mail"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "email_address" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_email-domain.json b/analyzers/Zetalytics/Zetalytics_email-domain.json new file mode 100644 index 000000000..50afc0501 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_email-domain.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_email_domain", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for email_domain", + "dataTypeList": ["mail"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "email_domain" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_email-user.json b/analyzers/Zetalytics/Zetalytics_email-user.json new file mode 100644 index 000000000..2b9e78515 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_email-user.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_email_user", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for email_user", + "dataTypeList": ["mail"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "email_user" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_firstseen.json b/analyzers/Zetalytics/Zetalytics_firstseen.json new file mode 100644 index 000000000..8c9ecd763 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_firstseen.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_firstseen", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for firstseen", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "firstseen" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_hash2malwaredns.json b/analyzers/Zetalytics/Zetalytics_hash2malwaredns.json new file mode 100644 index 000000000..fbe7bc6cb --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_hash2malwaredns.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_hash2malwaredns", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for hash2malwaredns", + "dataTypeList": ["hash"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "hash2malwaredns" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_hash2malwarehttp.json b/analyzers/Zetalytics/Zetalytics_hash2malwarehttp.json new file mode 100644 index 000000000..95f135cb3 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_hash2malwarehttp.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_hash2malwarehttp", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for hash2malwarehttp", + "dataTypeList": ["hash"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "hash2malwarehttp" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_hostname.json b/analyzers/Zetalytics/Zetalytics_hostname.json new file mode 100644 index 000000000..95bbb62c3 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_hostname.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_hostname", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for hostname", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "hostname" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_ip.json b/analyzers/Zetalytics/Zetalytics_ip.json new file mode 100644 index 000000000..a465ebde4 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_ip.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_ip", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for ip", + "dataTypeList": ["ip"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "ip" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_ip2malwaredns.json b/analyzers/Zetalytics/Zetalytics_ip2malwaredns.json new file mode 100644 index 000000000..428924d66 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_ip2malwaredns.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_ip2malwaredns", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for ip2malwaredns", + "dataTypeList": ["ip"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "ip2malwaredns" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_ip2malwarehttp.json b/analyzers/Zetalytics/Zetalytics_ip2malwarehttp.json new file mode 100644 index 000000000..2d1e2d67a --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_ip2malwarehttp.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_ip2malwarehttp", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for ip2malwarehttp", + "dataTypeList": ["ip"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "ip2malwarehttp" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_ip2nsglue.json b/analyzers/Zetalytics/Zetalytics_ip2nsglue.json new file mode 100644 index 000000000..edbd1b574 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_ip2nsglue.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_ip2nsglue", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for ip2nsglue", + "dataTypeList": ["ip"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "ip2nsglue" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_mx2domain.json b/analyzers/Zetalytics/Zetalytics_mx2domain.json new file mode 100644 index 000000000..465cd1638 --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_mx2domain.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_mx2domain", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for mx2domain", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "mx2domain" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_ns2domain.json b/analyzers/Zetalytics/Zetalytics_ns2domain.json new file mode 100644 index 000000000..e31da253b --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_ns2domain.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_ns2domain", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for ns2domain", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "ns2domain" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/Zetalytics_subdomains.json b/analyzers/Zetalytics/Zetalytics_subdomains.json new file mode 100644 index 000000000..c2f57ddfc --- /dev/null +++ b/analyzers/Zetalytics/Zetalytics_subdomains.json @@ -0,0 +1,23 @@ +{ + "name": "Zetalytics_subdomains", + "version": "1.0", + "author": "Ben", + "url": "None", + "license": "None", + "description": "Zetalytics transform for subdomains", + "dataTypeList": ["domain", "fqdn"], + "baseConfig": "Zetalytics", + "command": "Zetalytics/zetalytics.py", + "configurationItems": [ + { + "name": "key", + "description": "API key for Zetalytics", + "type": "string", + "multi": false, + "required": true + } + ], + "config": { + "service": "subdomains" + } +} \ No newline at end of file diff --git a/analyzers/Zetalytics/requirements.txt b/analyzers/Zetalytics/requirements.txt new file mode 100644 index 000000000..e7f865c64 --- /dev/null +++ b/analyzers/Zetalytics/requirements.txt @@ -0,0 +1,2 @@ +requests~=2.21.0 +zetalytics-api \ No newline at end of file diff --git a/analyzers/Zetalytics/zetalytics-api.py b/analyzers/Zetalytics/zetalytics-api.py new file mode 100644 index 000000000..a3b152ff7 --- /dev/null +++ b/analyzers/Zetalytics/zetalytics-api.py @@ -0,0 +1,472 @@ +import requests +import sys +import json + + +class Zetalytics(object): + """ + You can preconfigure all services globally with a ``config`` dict. + Example:: + zl = Zetalytics(token='AABBCCDDEEFFGG') + """ + + def __init__(self, **kwargs): + self.requester = requests.session() + self.config = { + 'base_url': 'https://zonecruncher.com/api/v1/' + } + self.config.update(kwargs) + if len(self.config.get('token')) != 32: + #TODO: Figure out server response for wrong API token + raise ValueError("Incorrect API token provided") + self.set_token(self.config.get('token')) + self.__set_params(self.config) + + def set_token(self, token): + if token: + self.requester.params['token'] = token + + def __set_params(self, config): + if config.get('verbose'): + self.requester.config = {'verbose': config['verbose']} + if config.get('timeout'): + self.requester.timeout = config['timeout'] + + def check_integrity(self, arg_dict, **params): + print(params) + # TODO: Type checking + for k, v in params.items(): + if k not in arg_dict and v['required']: + raise ValueError("Missing required parameter " + k) + elif k not in arg_dict: + raise ValueError("Unknown parameter " + k) + elif k in arg_dict: + print(arg_dict[k]) + if arg_dict[k]['constraints']: + for _k, _v in arg_dict[k]['constraints'].items(): + if _k == 'length': + if not len(v) == _v: + raise ValueError("Parameter " + k + " does not have a length of " + str(_v['length'])) + if _k == 'range': + if not _v[0] <= int(v) <= _v[1]: + raise ValueError( + "Parameter " + k + " is not in allowed range of " + str(_v[0]) + "-" + str(_v[1])) + if _k == 'multi': + print(v) + print(_v) + if v not in _v: + raise ValueError("Parameter " + v + " in " + k + " is not an allowed value") + return True + + def dateToEpoch(self, date): + pass + + def cname2qname(self, **params): + """ + Params; + q: Domain name + toBaseDomain: Boolean, if true convert to base domain + size: Result size + start: Epoch time to start search from + end: Epoch time to end search at + tsfield: Shows first seen, last seen, or both 'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"] + """ + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2aaaa(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2cname(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2d8s(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'live': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2ip(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2malwaredns(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2malwarehttp(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2mx(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2ns(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2nsglue(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2ptr(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2txt(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def domain2whois(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def email_address(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def email_domain(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def email_user(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def firstseen(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'cctld': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["indexTS", "date"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def hash2malwaredns(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def hash2malwarehttp(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def hostname(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def ip(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def ip2malwaredns(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def ip2malwarehttp(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def ip2nsglue(self, **params): + params.update(token=self.config.get('token')) + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def mx2domain(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def ns2domain(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'size': {'type': 'Integer', 'constraints': {'range': [0, 100000]}, 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) + + def subdomains(self, **params): + endpoint = sys._getframe().f_code.co_name + args_allowed = {'q': {'type': 'String', 'constraints': None, 'required': True}, + 'token': {'type': 'String', 'constraints': {'length': 32}, 'required': True}, + 'toBaseDomain': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'v': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'vv': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'vvv': {'type': 'Boolean', 'constraints': None, 'required': False}, + 'sort': {'type': 'String', + 'constraints': {'multi': ["first", "last", "first:desc", "last:asc"]}, + 'required': False}, + 't': {'type': 'String', + 'constraints': { + 'multi': ["a", "aaaa", "cname", "mx", "name", "ns", "ptr", "soa_email", "soa_server", + "txt"]}, + 'required': False}, + 'start': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'end': {'type': 'Epoch', 'constraints': None, 'required': False}, + 'tsfield': {'type': 'String', + 'constraints': {'multi': ["first_seen", "first_ts", "last_seen", "last_ts", "all"]}, + 'required': False} + } + if (self.check_integrity(args_allowed, **params)): + return json.loads(self.requester.get(self.config['base_url'] + endpoint, params=params).text) diff --git a/analyzers/Zetalytics/zetalytics.py b/analyzers/Zetalytics/zetalytics.py new file mode 100644 index 000000000..fa2deb2c4 --- /dev/null +++ b/analyzers/Zetalytics/zetalytics.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python3 + +import requests +from zetalytics-api import Zetalytics + +from cortexutils.analyzer import Analyzer + + + +class ZetalyticsAnalyzer(Analyzer): + """ + Zetalytics APIv1 + """ + + def __init__(self): + Analyzer.__init__(self) + self.service = self.get_param('config.service', None, 'Service parameter is missing') + self.zetalytics_key = self.get_param('config.key', None, 'Missing Zetalytics API key') + self.polling_interval = self.get_param('config.polling_interval', 60) + self.proxies = self.get_param('config.proxy', None) + self.zl = Zetalytics(token=self.zetalytics_key) + + def call_api(self, instance, data, func_name): + return getattr(instance, func_name)(q=data) + + def run(self): + + try: + data = self.get_data() + try: + response = self.call_api(self.zl, data, self.service) + print(response) + json_response = response + response_list = json_response if isinstance(json_response, list) else [json_response] + self.report({'values': response_list}) + except Exception as e: + self.error(e) + except Exception as e: + self.unexpectedError(e) + + def artifacts(self, raw): + artifacts = [] + #TODO: Collect more information and check for and remove duplicates + if raw and 'values' in raw: + if self.service == "cname2qname": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['value']))) + if self.service == "domain2aaaa": + for result in raw['values'][0]['results']: + for result in raw['values']['results']: + artifacts.append(self.build_artifact('ip', str(result['value']))) + if self.service == "domain2cname": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + if self.service == "domain2d8s": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('other', str(result['response']['o']))) + artifacts.append(self.build_artifact('domain', str(result['hname']))) + artifacts.append(self.build_artifact('domain', str(result['server']))) + artifacts.append(self.build_artifact('domain', str(result['refer']))) + artifacts.append(self.build_artifact('other', str(result['response']['r']))) + artifacts.append(self.build_artifact('mail', str(result['response'['x']['owner']]))) + artifacts.append(self.build_artifact('mail', str(result['response']['x']['tech']))) + artifacts.append(self.build_artifact('mail', str(result['response']['x']['admin']))) + for n in raw['values'][0]['results']: + artifacts.append(self.build_artifact('fqdn', str(n))) + if self.service == "domain2ip": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('ip', str(result['value']))) + if self.service == "domain2malwaredns": + # artifacts.append({'type': 'autonomous-system', 'value': str(raw['as'])}) + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "domain2malwarehttp": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "domain2mx": + for result in raw['values'][0]['results']: + artifacts.append({'type': 'domain', 'value': str(result['value'])}) + if self.service == "domain2ns": + for result in raw['values'][0]['results']: + artifacts.append({'type': 'fqdn', 'value': str(result['value'])}) + if self.service == "domain2nsglue": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('fqdn', str(result['hname']))) + artifacts.append(self.build_artifact('ip', str(result['ip']))) + if self.service == "domain2ptr": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + artifacts.append(self.build_artifact('other', str(result['hname']))) + if self.service == "domain2txt": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + artifacts.append(self.build_artifact('other', str(result['value']))) + if self.service == "domain2whois": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('other', str(result['whois']))) + artifacts.append(self.build_artifact('fqdn', str(result['server']))) + artifacts.append(self.build_artifact('fqdn', str(result['refer']))) + if self.service == "email_address": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['d']))) + artifacts.append(self.build_artifact('other', str(result['r']))) + artifacts.append(self.build_artifact('other', str(result['o']))) + for n in result['n']: + artifacts.append(self.build_artifact('fqdn', str(n))) + for email in result['emails']: + artifacts.append(self.build_artifact('mail', str(email['addr']))) + if self.service == "email_domain": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['d']))) + artifacts.append(self.build_artifact('other', str(result['r']))) + artifacts.append(self.build_artifact('other', str(result['o']))) + for n in result['n']: + artifacts.append(self.build_artifact('fqdn', str(n))) + for email in result['emails']: + artifacts.append(self.build_artifact('mail', str(email['addr']))) + if self.service == "email_user": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['d']))) + artifacts.append(self.build_artifact('other', str(result['r']))) + artifacts.append(self.build_artifact('other', str(result['o']))) + for n in result['n']: + artifacts.append(self.build_artifact('fqdn', str(n))) + for email in result['emails']: + artifacts.append(self.build_artifact('mail', str(email['addr']))) + if self.service == "hash2malwaredns": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "hash2malwarehttp": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "hostname": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + artifacts.append(self.build_artifact('fqdn', str(result['value']))) + if self.service == "ip": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + artifacts.append(self.build_artifact('ip', str(result['value']))) + if self.service == "ip2malwaredns": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "ip2malwarehttp": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['hname']))) + for ip in result['iplog']: + artifacts.append(self.build_artifact('ip', str(ip['ip']))) + artifacts.append(self.build_artifact('hash', str(result['hash']))) + if self.service == "ip2nsglue": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('fqdn', str(result['hname']))) + artifacts.append(self.build_artifact('ip', str(result['ip']))) + if self.service == "mx2domain": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + artifacts.append(self.build_artifact('domain', str(result['value']))) + if self.service == "ns2domain": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('domain', str(result['domain']))) + for ns in result['ns']: + artifacts.append(self.build_artifact('fqdn', str(ns))) + if self.service == "subdomains": + for result in raw['values'][0]['results']: + artifacts.append(self.build_artifact('fqdn', str(result['qname']))) + return artifacts + + def summary(self, raw): + taxonomies = [] + #TODO: Detect the different types of results and turn them into meaninful reports + if raw and 'values' in raw and raw['values'][0]['returning'] > 0: + taxonomies.append(self.build_taxonomy('info','Zetalytics', 'Records', raw['values'][0]['returning'])) + else: + taxonomies.append(self.build_taxonomy('info','Zetalytics', 'Records', 0)) + + return {"taxonomies": taxonomies} + + +if __name__ == '__main__': + ZetalyticsAnalyzer().run()