passivedns-client 2.0.6 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +6 -0
- data/Rakefile +8 -0
- data/lib/passivedns/client.rb +14 -7
- data/lib/passivedns/client/cli.rb +34 -6
- data/lib/passivedns/client/passivedb.rb +6 -1
- data/lib/passivedns/client/provider/bfk.rb +102 -0
- data/lib/passivedns/client/provider/circl.rb +111 -0
- data/lib/passivedns/client/provider/cn360.rb +108 -0
- data/lib/passivedns/client/provider/dnsdb.rb +110 -0
- data/lib/passivedns/client/provider/mnemonic.rb +98 -0
- data/lib/passivedns/client/provider/passivetotal.rb +103 -0
- data/lib/passivedns/client/provider/riskiq.rb +130 -0
- data/lib/passivedns/client/provider/tcpiputils.rb +118 -0
- data/lib/passivedns/client/provider/virustotal.rb +105 -0
- data/lib/passivedns/client/state.rb +30 -2
- data/lib/passivedns/client/version.rb +4 -2
- data/test/test_cli.rb +6 -5
- data/test/test_passivedns-client.rb +33 -8
- metadata +11 -10
- data/lib/passivedns/client/providers/bfk.rb +0 -77
- data/lib/passivedns/client/providers/circl.rb +0 -79
- data/lib/passivedns/client/providers/cn360.rb +0 -80
- data/lib/passivedns/client/providers/dnsdb.rb +0 -85
- data/lib/passivedns/client/providers/mnemonic.rb +0 -72
- data/lib/passivedns/client/providers/passivetotal.rb +0 -77
- data/lib/passivedns/client/providers/tcpiputils.rb +0 -92
- data/lib/passivedns/client/providers/virustotal.rb +0 -78
@@ -1,72 +0,0 @@
|
|
1
|
-
# DESCRIPTION: Module to query Mnemonic's passive DNS repository
|
2
|
-
# CONTRIBUTOR: Drew Hunt (pinowudi@yahoo.com)
|
3
|
-
require 'net/http'
|
4
|
-
require 'net/https'
|
5
|
-
require 'openssl'
|
6
|
-
|
7
|
-
module PassiveDNS
|
8
|
-
class Mnemonic < PassiveDB
|
9
|
-
# override
|
10
|
-
def self.name
|
11
|
-
"Mnemonic"
|
12
|
-
end
|
13
|
-
#override
|
14
|
-
def self.config_section_name
|
15
|
-
"mnemonic"
|
16
|
-
end
|
17
|
-
#override
|
18
|
-
def self.option_letter
|
19
|
-
"m"
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_accessor :debug
|
23
|
-
def initialize(options={})
|
24
|
-
@debug = options[:debug] || false
|
25
|
-
@apikey = options["APIKEY"] || raise("#{self.class.name} requires an APIKEY")
|
26
|
-
@url = options["URL"] || "https://passivedns.mnemonic.no/api1/?apikey="
|
27
|
-
end
|
28
|
-
|
29
|
-
def parse_json(page,query,response_time=0)
|
30
|
-
res = []
|
31
|
-
# need to remove the json_class tag or the parser will crap itself trying to find a class to align it to
|
32
|
-
data = JSON.parse(page)
|
33
|
-
if data['result']
|
34
|
-
data['result'].each do |row|
|
35
|
-
if row['query']
|
36
|
-
res << PDNSResult.new(self.class.name,response_time,row['query'],row['answer'],row['type'].upcase,row['ttl'],row['first'],row['last'])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
res
|
41
|
-
rescue Exception => e
|
42
|
-
$stderr.puts "#{self.class.name} Exception: #{e}"
|
43
|
-
raise e
|
44
|
-
end
|
45
|
-
|
46
|
-
def lookup(label, limit=nil)
|
47
|
-
$stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
|
48
|
-
Timeout::timeout(240) {
|
49
|
-
url = "#{@url}#{@apikey}&query=#{label}&method=exact"
|
50
|
-
$stderr.puts "DEBUG: #{self.class.name} url = #{url}" if @debug
|
51
|
-
url = URI.parse url
|
52
|
-
http = Net::HTTP.new(url.host, url.port)
|
53
|
-
http.use_ssl = (url.scheme == 'https')
|
54
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
55
|
-
http.verify_depth = 5
|
56
|
-
request = Net::HTTP::Get.new(url.path+"?"+url.query)
|
57
|
-
request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
|
58
|
-
t1 = Time.now
|
59
|
-
response = http.request(request)
|
60
|
-
t2 = Time.now
|
61
|
-
recs = parse_json(response.body, label, t2-t1)
|
62
|
-
if limit
|
63
|
-
recs[0,limit]
|
64
|
-
else
|
65
|
-
recs
|
66
|
-
end
|
67
|
-
}
|
68
|
-
rescue Timeout::Error => e
|
69
|
-
$stderr.puts "#{self.class.name} lookup timed out: #{label}"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# DESCRIPTION: Module to query PassiveTotal's passive DNS repository
|
2
|
-
|
3
|
-
require 'net/http'
|
4
|
-
require 'net/https'
|
5
|
-
require 'openssl'
|
6
|
-
|
7
|
-
module PassiveDNS
|
8
|
-
class PassiveTotal < PassiveDB
|
9
|
-
# override
|
10
|
-
def self.name
|
11
|
-
"PassiveTotal"
|
12
|
-
end
|
13
|
-
#override
|
14
|
-
def self.config_section_name
|
15
|
-
"passivetotal"
|
16
|
-
end
|
17
|
-
#override
|
18
|
-
def self.option_letter
|
19
|
-
"p"
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_accessor :debug
|
23
|
-
def initialize(options={})
|
24
|
-
@debug = options[:debug] || false
|
25
|
-
@apikey = options["APIKEY"] || raise("#{self.class.name} requires an APIKEY")
|
26
|
-
@url = options["URL"] || "https://www.passivetotal.org/api/passive"
|
27
|
-
end
|
28
|
-
|
29
|
-
def parse_json(page,query,response_time=0)
|
30
|
-
res = []
|
31
|
-
# need to remove the json_class tag or the parser will crap itself trying to find a class to align it to
|
32
|
-
data = JSON.parse(page)
|
33
|
-
if data['results']
|
34
|
-
query = data['results']['value']
|
35
|
-
data['results']['resolutions'].each do |row|
|
36
|
-
first_seen = row['firstSeen']
|
37
|
-
last_seen = row['lastSeen']
|
38
|
-
value = row['value']
|
39
|
-
source = row['source'].join(",")
|
40
|
-
res << PDNSResult.new(self.class.name+"/"+source,response_time,
|
41
|
-
query, value, "A", 0, first_seen, last_seen)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
res
|
45
|
-
rescue Exception => e
|
46
|
-
$stderr.puts "#{self.class.name} Exception: #{e}"
|
47
|
-
raise e
|
48
|
-
end
|
49
|
-
|
50
|
-
def lookup(label, limit=nil)
|
51
|
-
$stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
|
52
|
-
Timeout::timeout(240) {
|
53
|
-
url = @url
|
54
|
-
$stderr.puts "DEBUG: #{self.class.name} url = #{url}" if @debug
|
55
|
-
url = URI.parse url
|
56
|
-
http = Net::HTTP.new(url.host, url.port)
|
57
|
-
http.use_ssl = (url.scheme == 'https')
|
58
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
59
|
-
http.verify_depth = 5
|
60
|
-
request = Net::HTTP::Post.new(url.request_uri)
|
61
|
-
request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
|
62
|
-
request.set_form_data({"apikey" => @apikey, "value" => label})
|
63
|
-
t1 = Time.now
|
64
|
-
response = http.request(request)
|
65
|
-
t2 = Time.now
|
66
|
-
recs = parse_json(response.body, label, t2-t1)
|
67
|
-
if limit
|
68
|
-
recs[0,limit]
|
69
|
-
else
|
70
|
-
recs
|
71
|
-
end
|
72
|
-
}
|
73
|
-
rescue Timeout::Error => e
|
74
|
-
$stderr.puts "#{self.class.name} lookup timed out: #{label}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'net/https'
|
3
|
-
require 'openssl'
|
4
|
-
require 'json'
|
5
|
-
|
6
|
-
# Please read http://www.tcpiputils.com/terms-of-service under automated requests
|
7
|
-
|
8
|
-
module PassiveDNS
|
9
|
-
class TCPIPUtils < PassiveDB
|
10
|
-
# override
|
11
|
-
def self.name
|
12
|
-
"TCPIPUtils"
|
13
|
-
end
|
14
|
-
#override
|
15
|
-
def self.config_section_name
|
16
|
-
"tcpiputils"
|
17
|
-
end
|
18
|
-
#override
|
19
|
-
def self.option_letter
|
20
|
-
"t"
|
21
|
-
end
|
22
|
-
|
23
|
-
attr_accessor :debug
|
24
|
-
def initialize(options={})
|
25
|
-
@debug = options[:debug] || false
|
26
|
-
@apikey = options["APIKEY"] || raise("#{self.class.name} requires an APIKEY. See README.md")
|
27
|
-
@url = options["URL"] || "https://www.utlsapi.com/api.php?version=1.0&apikey="
|
28
|
-
end
|
29
|
-
|
30
|
-
def format_recs(reply_data, question, delta)
|
31
|
-
recs = []
|
32
|
-
reply_data.each do |key, data|
|
33
|
-
case key
|
34
|
-
when "ipv4"
|
35
|
-
data.each do |rec|
|
36
|
-
recs << PDNSResult.new(self.class.name, delta, question, rec["ip"], "A", nil, nil, rec["updatedate"], nil)
|
37
|
-
end
|
38
|
-
when "ipv6"
|
39
|
-
data.each do |rec|
|
40
|
-
recs << PDNSResult.new(self.class.name, delta, question, rec["ip"], "AAAA", nil, nil, rec["updatedate"], nil)
|
41
|
-
end
|
42
|
-
when "dns"
|
43
|
-
data.each do |rec|
|
44
|
-
recs << PDNSResult.new(self.class.name, delta, question, rec["dns"], "NS", nil, nil, rec["updatedate"], nil)
|
45
|
-
end
|
46
|
-
when "mx"
|
47
|
-
data.each do |rec|
|
48
|
-
recs << PDNSResult.new(self.class.name, delta, question, rec["dns"], "MX", nil, nil, rec["updatedate"], nil)
|
49
|
-
end
|
50
|
-
when "domains"
|
51
|
-
data.each do |rec|
|
52
|
-
recs << PDNSResult.new(self.class.name, delta, rec, question, "A", nil, nil, nil, nil)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
recs
|
57
|
-
end
|
58
|
-
|
59
|
-
def lookup(label, limit=nil)
|
60
|
-
$stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
|
61
|
-
type = (label.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)) ? "domainneighbors" : "domainipdnshistory"
|
62
|
-
url = "#{@url}#{@apikey}&type=#{type}&q=#{label}"
|
63
|
-
recs = []
|
64
|
-
Timeout::timeout(240) {
|
65
|
-
url = URI.parse url
|
66
|
-
http = Net::HTTP.new(url.host, url.port)
|
67
|
-
http.use_ssl = (url.scheme == 'https')
|
68
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
69
|
-
http.verify_depth = 5
|
70
|
-
request = Net::HTTP::Get.new(url.path+"?"+url.query)
|
71
|
-
request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
|
72
|
-
t1 = Time.now
|
73
|
-
response = http.request(request)
|
74
|
-
delta = (Time.now - t1).to_f
|
75
|
-
reply = JSON.parse(response.body)
|
76
|
-
if reply["status"] and reply["status"] == "succeed"
|
77
|
-
question = reply["data"]["question"]
|
78
|
-
recs = format_recs(reply["data"], question, delta)
|
79
|
-
elsif reply["status"] and reply["status"] == "error"
|
80
|
-
raise "#{self.class.name}: error from web API: #{reply["data"]}"
|
81
|
-
end
|
82
|
-
if limit
|
83
|
-
recs[0,limit]
|
84
|
-
else
|
85
|
-
recs
|
86
|
-
end
|
87
|
-
}
|
88
|
-
rescue Timeout::Error => e
|
89
|
-
$stderr.puts "#{self.class.name} lookup timed out: #{label}"
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# DESCRIPTION: this is a module for pdns.rb, primarily used by pdnstool.rb, to query VirusTotal's passive DNS database
|
2
|
-
require 'net/http'
|
3
|
-
require 'net/https'
|
4
|
-
require 'openssl'
|
5
|
-
|
6
|
-
module PassiveDNS
|
7
|
-
class VirusTotal < PassiveDB
|
8
|
-
# override
|
9
|
-
def self.name
|
10
|
-
"VirusTotal"
|
11
|
-
end
|
12
|
-
#override
|
13
|
-
def self.config_section_name
|
14
|
-
"virustotal"
|
15
|
-
end
|
16
|
-
#override
|
17
|
-
def self.option_letter
|
18
|
-
"v"
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_accessor :debug
|
22
|
-
def initialize(options={})
|
23
|
-
@debug = options[:debug] || false
|
24
|
-
@apikey = options["APIKEY"] || raise("#{self.class.name} requires an APIKEY. See README.md")
|
25
|
-
@url = options["URL"] || "https://www.virustotal.com/vtapi/v2/"
|
26
|
-
end
|
27
|
-
|
28
|
-
def parse_json(page,query,response_time=0)
|
29
|
-
res = []
|
30
|
-
# need to remove the json_class tag or the parser will crap itself trying to find a class to align it to
|
31
|
-
data = JSON.parse(page)
|
32
|
-
if data['resolutions']
|
33
|
-
data['resolutions'].each do |row|
|
34
|
-
if row['ip_address']
|
35
|
-
res << PDNSResult.new(self.class.name,response_time,query,row['ip_address'],'A',nil,nil,row['last_resolved'])
|
36
|
-
elsif row['hostname']
|
37
|
-
res << PDNSResult.new(self.class.name,response_time,row['hostname'],query,'A',nil,nil,row['last_resolved'])
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
res
|
42
|
-
rescue Exception => e
|
43
|
-
$stderr.puts "VirusTotal Exception: #{e}"
|
44
|
-
raise e
|
45
|
-
end
|
46
|
-
|
47
|
-
def lookup(label, limit=nil)
|
48
|
-
$stderr.puts "DEBUG: #{self.class.name}.lookup(#{label})" if @debug
|
49
|
-
Timeout::timeout(240) {
|
50
|
-
url = nil
|
51
|
-
if label =~ /^[\d\.]+$/
|
52
|
-
url = "#{@url}ip-address/report?ip=#{label}&apikey=#{@apikey}"
|
53
|
-
else
|
54
|
-
url = "#{@url}domain/report?domain=#{label}&apikey=#{@apikey}"
|
55
|
-
end
|
56
|
-
$stderr.puts "DEBUG: #{self.class.name} url = #{url}" if @debug
|
57
|
-
url = URI.parse url
|
58
|
-
http = Net::HTTP.new(url.host, url.port)
|
59
|
-
http.use_ssl = (url.scheme == 'https')
|
60
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
61
|
-
http.verify_depth = 5
|
62
|
-
request = Net::HTTP::Get.new(url.path+"?"+url.query)
|
63
|
-
request.add_field("User-Agent", "Ruby/#{RUBY_VERSION} passivedns-client rubygem v#{PassiveDNS::Client::VERSION}")
|
64
|
-
t1 = Time.now
|
65
|
-
response = http.request(request)
|
66
|
-
t2 = Time.now
|
67
|
-
recs = parse_json(response.body, label, t2-t1)
|
68
|
-
if limit
|
69
|
-
recs[0,limit]
|
70
|
-
else
|
71
|
-
recs
|
72
|
-
end
|
73
|
-
}
|
74
|
-
rescue Timeout::Error => e
|
75
|
-
$stderr.puts "#{self.class.name} lookup timed out: #{label}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|