wmap 2.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +141 -0
  3. data/LICENSE.txt +15 -0
  4. data/README.rdoc +98 -0
  5. data/TODO +13 -0
  6. data/bin/deprime +21 -0
  7. data/bin/distrust +38 -0
  8. data/bin/googleBot +23 -0
  9. data/bin/prime +21 -0
  10. data/bin/refresh +26 -0
  11. data/bin/run_tests +16 -0
  12. data/bin/spiderBot +26 -0
  13. data/bin/trust +38 -0
  14. data/bin/updateAll +57 -0
  15. data/bin/wadd +25 -0
  16. data/bin/wadds +26 -0
  17. data/bin/wcheck +28 -0
  18. data/bin/wdel +25 -0
  19. data/bin/wdump +21 -0
  20. data/bin/wmap +151 -0
  21. data/bin/wscan +32 -0
  22. data/data/cidrs +2 -0
  23. data/data/deactivated_sites +1 -0
  24. data/data/domains +2 -0
  25. data/data/hosts +1 -0
  26. data/data/prime_hosts +1 -0
  27. data/data/sites +2 -0
  28. data/data/sub_domains +2 -0
  29. data/demos/bruter.rb +27 -0
  30. data/demos/dns_brutes.rb +28 -0
  31. data/demos/filter_cidr.rb +18 -0
  32. data/demos/filter_crawls.rb +5 -0
  33. data/demos/filter_domain.rb +25 -0
  34. data/demos/filter_geoip.rb +26 -0
  35. data/demos/filter_known_services.rb +59 -0
  36. data/demos/filter_netinfo.rb +23 -0
  37. data/demos/filter_prime.rb +25 -0
  38. data/demos/filter_profiler.rb +3 -0
  39. data/demos/filter_redirection.rb +19 -0
  40. data/demos/filter_site.rb +40 -0
  41. data/demos/filter_siteip.rb +31 -0
  42. data/demos/filter_status.rb +17 -0
  43. data/demos/filter_timestamp.rb +23 -0
  44. data/demos/filter_url.rb +19 -0
  45. data/demos/new_fnd.rb +66 -0
  46. data/demos/nmap_parser.pl +138 -0
  47. data/demos/site_format.rb +18 -0
  48. data/demos/whois_domain.rb +78 -0
  49. data/dicts/GeoIP.dat +0 -0
  50. data/dicts/GeoIPASNum.dat +0 -0
  51. data/dicts/GeoLiteCity.dat +0 -0
  52. data/dicts/ccsld.txt +2646 -0
  53. data/dicts/cctld.txt +243 -0
  54. data/dicts/gtld.txt +25 -0
  55. data/dicts/hostnames-dict.big +1402 -0
  56. data/dicts/hostnames-dict.txt +101 -0
  57. data/lib/wmap/cidr_tracker.rb +327 -0
  58. data/lib/wmap/dns_bruter.rb +308 -0
  59. data/lib/wmap/domain_tracker/sub_domain.rb +142 -0
  60. data/lib/wmap/domain_tracker.rb +342 -0
  61. data/lib/wmap/geoip_tracker.rb +72 -0
  62. data/lib/wmap/google_search_scraper.rb +177 -0
  63. data/lib/wmap/host_tracker/primary_host.rb +130 -0
  64. data/lib/wmap/host_tracker.rb +550 -0
  65. data/lib/wmap/network_profiler.rb +144 -0
  66. data/lib/wmap/port_scanner.rb +208 -0
  67. data/lib/wmap/site_tracker/deactivated_site.rb +85 -0
  68. data/lib/wmap/site_tracker.rb +937 -0
  69. data/lib/wmap/url_checker.rb +314 -0
  70. data/lib/wmap/url_crawler.rb +381 -0
  71. data/lib/wmap/utils/domain_root.rb +184 -0
  72. data/lib/wmap/utils/logger.rb +53 -0
  73. data/lib/wmap/utils/url_magic.rb +343 -0
  74. data/lib/wmap/utils/utils.rb +333 -0
  75. data/lib/wmap/whois.rb +76 -0
  76. data/lib/wmap.rb +227 -0
  77. data/logs/wmap.log +17 -0
  78. data/ruby_whois_patches/base_cocca2.rb +149 -0
  79. data/ruby_whois_patches/kero.yachay.pe.rb +120 -0
  80. data/ruby_whois_patches/whois.PublicDomainRegistry.com.rb +124 -0
  81. data/ruby_whois_patches/whois.above.com.rb +61 -0
  82. data/ruby_whois_patches/whois.adamsnames.tc.rb +107 -0
  83. data/ruby_whois_patches/whois.aeda.net.ae.rb +105 -0
  84. data/ruby_whois_patches/whois.ai.rb +112 -0
  85. data/ruby_whois_patches/whois.arnes.si.rb +121 -0
  86. data/ruby_whois_patches/whois.ascio.com.rb +91 -0
  87. data/ruby_whois_patches/whois.cnnic.cn.rb +123 -0
  88. data/ruby_whois_patches/whois.corporatedomains.com.rb +67 -0
  89. data/ruby_whois_patches/whois.crsnic.net.rb +108 -0
  90. data/ruby_whois_patches/whois.denic.de.rb +174 -0
  91. data/ruby_whois_patches/whois.dk-hostmaster.dk.rb +120 -0
  92. data/ruby_whois_patches/whois.dns.be.rb +134 -0
  93. data/ruby_whois_patches/whois.dns.lu.rb +129 -0
  94. data/ruby_whois_patches/whois.dns.pl.rb +150 -0
  95. data/ruby_whois_patches/whois.dns.pt.rb +119 -0
  96. data/ruby_whois_patches/whois.domain.kg.rb +126 -0
  97. data/ruby_whois_patches/whois.domainregistry.my.rb +123 -0
  98. data/ruby_whois_patches/whois.domreg.lt.rb +110 -0
  99. data/ruby_whois_patches/whois.dot.tk.rb +140 -0
  100. data/ruby_whois_patches/whois.hkirc.hk.rb +121 -0
  101. data/ruby_whois_patches/whois.isnic.is.rb +130 -0
  102. data/ruby_whois_patches/whois.je.rb +119 -0
  103. data/ruby_whois_patches/whois.jprs.jp.rb +137 -0
  104. data/ruby_whois_patches/whois.kenic.or.ke.rb +140 -0
  105. data/ruby_whois_patches/whois.markmonitor.com.rb +118 -0
  106. data/ruby_whois_patches/whois.melbourneit.com.rb +58 -0
  107. data/ruby_whois_patches/whois.nic.as.rb +96 -0
  108. data/ruby_whois_patches/whois.nic.at.rb +109 -0
  109. data/ruby_whois_patches/whois.nic.ch.rb +141 -0
  110. data/ruby_whois_patches/whois.nic.cl.rb +117 -0
  111. data/ruby_whois_patches/whois.nic.ec.rb +157 -0
  112. data/ruby_whois_patches/whois.nic.im.rb +120 -0
  113. data/ruby_whois_patches/whois.nic.it.rb +170 -0
  114. data/ruby_whois_patches/whois.nic.lv.rb +116 -0
  115. data/ruby_whois_patches/whois.nic.ly.rb +127 -0
  116. data/ruby_whois_patches/whois.nic.mu.rb +27 -0
  117. data/ruby_whois_patches/whois.nic.mx.rb +123 -0
  118. data/ruby_whois_patches/whois.nic.net.sa.rb +111 -0
  119. data/ruby_whois_patches/whois.nic.or.kr.rb +101 -0
  120. data/ruby_whois_patches/whois.nic.tel.rb +129 -0
  121. data/ruby_whois_patches/whois.nic.tr.rb +133 -0
  122. data/ruby_whois_patches/whois.nic.us.rb +129 -0
  123. data/ruby_whois_patches/whois.nic.ve.rb +135 -0
  124. data/ruby_whois_patches/whois.norid.no.rb +127 -0
  125. data/ruby_whois_patches/whois.pandi.or.id.rb +118 -0
  126. data/ruby_whois_patches/whois.psi-usa.info.rb +63 -0
  127. data/ruby_whois_patches/whois.registro.br.rb +109 -0
  128. data/ruby_whois_patches/whois.registrygate.com.rb +55 -0
  129. data/ruby_whois_patches/whois.rrpproxy.net.rb +61 -0
  130. data/ruby_whois_patches/whois.sgnic.sg.rb +130 -0
  131. data/ruby_whois_patches/whois.srs.net.nz.rb +166 -0
  132. data/ruby_whois_patches/whois.tucows.com.rb +70 -0
  133. data/ruby_whois_patches/whois.twnic.net.tw.rb +133 -0
  134. data/settings/discovery_ports +24 -0
  135. data/settings/google_keywords.txt +9 -0
  136. data/settings/google_locator.txt +23 -0
  137. data/test/domain_tracker_test.rb +31 -0
  138. data/test/utils_test.rb +168 -0
  139. data/version.txt +13 -0
  140. data/wmap.gemspec +49 -0
  141. metadata +202 -0
@@ -0,0 +1,308 @@
1
+ #--
2
+ # Wmap
3
+ #
4
+ # A pure Ruby library for the Internet web application discovery and tracking.
5
+ #
6
+ # Copyright (c) 2012-2015 Yang Li <yang.li@owasp.org>
7
+ #++
8
+ require "dnsruby"
9
+ require "parallel"
10
+
11
+
12
+ # Class to discover valid hosts through either zone transfer or DNS brute-force methods
13
+ class Wmap::DnsBruter
14
+ include Wmap::Utils
15
+
16
+ attr_accessor :hosts_dict, :verbose, :max_parallel, :data_dir
17
+ attr_reader :discovered_hosts_from_dns_bruter, :fail_domain_cnt
18
+
19
+ # Set default instance variables
20
+ def initialize (params = {})
21
+ # Change to your brute-force dictionary file here if necessary
22
+ @data_dir=params.fetch(:data_dir, File.dirname(__FILE__)+'/../../data/')
23
+ @file_hosts = @data_dir + 'hosts'
24
+ @file_hosts_dict = File.dirname(__FILE__)+'/../../dicts/hostnames-dict.txt'
25
+
26
+ @verbose=params.fetch(:verbose, false)
27
+ @discovered_hosts_from_dns_bruter=Hash.new
28
+ @hosts_dict=params.fetch(:hosts_dict, @file_hosts_dict)
29
+ @max_parallel=params.fetch(:max_parallel, 30)
30
+ @fail_domain_cnt=Hash.new
31
+ end
32
+
33
+ # Main worker to perform the brute-forcing on an Internet domain
34
+ def dns_brute_worker(host)
35
+ puts "Start DNS brute forcer on: #{host}"
36
+ results=Hash.new
37
+ domain=get_domain_root(host)
38
+ begin
39
+ host=host.strip.downcase
40
+ raise "Invalid internet host format: #{host}" unless is_fqdn?(host)
41
+ domain=get_domain_root(host)
42
+ # If we can do the zone transfer, then the brute-force process can be skipped.
43
+ if zone_transferable?(domain)
44
+ hosts=zone_transfer(domain)
45
+ else
46
+ hosts=brute_force_dns(host)
47
+ end
48
+ results[domain]=hosts
49
+ puts "Finish discovery on #{host}: #{results}"
50
+ return results
51
+ rescue Exception=>ee
52
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
53
+ return results
54
+ end
55
+ end
56
+ alias_method :query, :dns_brute_worker
57
+ alias_method :brute, :dns_brute_worker
58
+
59
+ # Parallel DNS brute-forcer operating on target domain list - by utilizing fork manager to spawn multiple child processes on multiple domains simultaneously
60
+ def dns_brute_workers(list,num=@max_parallel)
61
+ puts "Start the parallel engine one the domain list: #{list} \nMaximum brute-forcing session: #{num} "
62
+ begin
63
+ targets=list.uniq.keep_if { |x| is_fqdn?(x) }
64
+ results=Hash.new
65
+ Parallel.map(targets, :in_processes => num) { |target|
66
+ dns_brute_worker(target)
67
+ }.each do |process|
68
+ if process.nil?
69
+ next
70
+ elsif process.empty?
71
+ #do nothing in case of thrown an empty array
72
+ else
73
+ #domain=get_domain_root(process.first).downcase
74
+ results.merge!(process)
75
+ end
76
+ end
77
+ puts "Parallel DNS brute-force results: #{results}" if @verbose
78
+ @discovered_hosts_from_dns_bruter.merge!(results)
79
+ return results
80
+ rescue Exception => ee
81
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
82
+ end
83
+ end
84
+ alias_method :queries, :dns_brute_workers
85
+ alias_method :brutes, :dns_brute_workers
86
+
87
+ # Parallel DNS brute-forcer operating on target domain file - by utilizing fork manager to spawn multiple child processes on multiple domains simultaneously
88
+ def dns_brute_file(file_target,num=@max_parallel)
89
+ puts "Start the parallel brute-forcing with multiple child processes on target file #{file_target}: #{num}"
90
+ begin
91
+ hosts=Array.new
92
+ targets=file_2_list(file_target)
93
+ hosts=dns_brute_workers(targets,num)
94
+ return hosts
95
+ rescue Exception => ee
96
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
97
+ return hosts
98
+ end
99
+ end
100
+
101
+ # Perform zone transfer on a domain, return found host entries in an array
102
+ def zone_transfer(domain)
103
+ puts "Perform zone transfer on zone: #{domain}"
104
+ domain=domain.downcase
105
+ nameservers = get_nameservers(domain)
106
+ hosts=Array.new
107
+ puts "Retrieved name servers: #{nameservers}" if @verbose
108
+ nameservers.each do |nssrv|
109
+ begin
110
+ puts "Attempt zone transfer on name server: #{nssrv}"
111
+ if nssrv.nil?
112
+ abort "Method input variable error: no name server found!" if @verbose
113
+ next
114
+ end
115
+ zt = Dnsruby::ZoneTransfer.new
116
+ zt.server=nssrv unless nssrv.empty?
117
+ records = zt.transfer(domain)
118
+ if records==nil
119
+ puts "Zone transfer failed for zone #{domain} on: #{nssrv}"
120
+ next
121
+ else
122
+ puts "Zone transfer successfully for zone #{domain} on the name server: #{nssrv}"
123
+ records = records.delete_if {|x| not x.to_s=~/(\s+|\t+)IN/ }
124
+ records.each { |line| puts line.to_s } if @verbose
125
+ hosts=records.collect {|x| x.to_s.split(/\.(\s+|\t+)/).first}
126
+ hosts=hosts.sort!.uniq!
127
+ puts "Found hosts: #{hosts}" if @verbose
128
+ @discovered_hosts_from_dns_bruter[domain] = hosts
129
+ return hosts
130
+ end
131
+ rescue Exception=>ee
132
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
133
+ end
134
+ end
135
+ return hosts
136
+ end
137
+
138
+ # Test the DNS server if zone transfer is allowed. If allowed, save the found hosts into the class variable.
139
+ def get_vulnerable_ns(domain)
140
+ puts "Identify the vulnerable DNS servers if zone transfer is allowed."
141
+ domain=domain.strip.downcase
142
+ vuln=Array.new
143
+ begin
144
+ nameservers = get_nameservers(domain)
145
+ nameservers.each do |nssrv|
146
+ zt = Dnsruby::ZoneTransfer.new
147
+ zt.server=nssrv unless nssrv.empty?
148
+ records = zt.transfer(domain)
149
+ unless records==nil
150
+ vuln.push(nssrv)
151
+ end
152
+ end
153
+ return vuln
154
+ rescue Exception=>ee
155
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
156
+ end
157
+ end
158
+
159
+ # Return a list of valid hosts by brute-forcing the name servers
160
+ def brute_force_dns (host)
161
+ puts "Start dictionary attacks on the DNS server for: #{host}" if @verbose
162
+ begin
163
+ host=host.strip
164
+ valid_hosts = Array.new
165
+ my_host_tracker = Wmap::HostTracker.new(:data_dir=>@data_dir)
166
+ # build the host dictionary for the brute force method
167
+ dict = Array.new
168
+ if File.exists?(@hosts_dict)
169
+ dict = file_2_list(@hosts_dict)
170
+ elsif File.exists?(@file_hosts)
171
+ dict = my_host_tracker.top_hostname(200)
172
+ my_host_tracker.list_2_file(dict,@hosts_dict)
173
+ else
174
+ abort "Error: Non-existing common hosts dictionary file - #{@host_dict} or hosts file #{@file_hosts}. Please check your file path and name setting again."
175
+ end
176
+ domain=String.new
177
+ unless is_root_domain?(host) or my_host_tracker.sub_domain_known?(host)
178
+ my_hosts=hostname_mutation(host).map {|x| x.split('.')[0]}
179
+ dict+=my_hosts unless my_hosts.empty?
180
+ end
181
+ if is_domain?(host) or my_host_tracker.sub_domain_known?(host)
182
+ domain=host
183
+ elsif
184
+ array_h=host.split('.')
185
+ array_h.shift
186
+ domain=array_h.join('.')
187
+ puts "Domain for #{host}: #{domain}" if @verbose
188
+ end
189
+ dict+=[host.split(".")[0],""]
190
+ puts "Choose Brute-force Dictionary: #{dict}" if @verbose
191
+ cnt=0
192
+ dict.each do |x|
193
+ # 10/09/2013 add logic to skip brute-forcing the domain in case of experiencing more than 2 Dnsruby::ServFail conditions
194
+ if @fail_domain_cnt.key?(domain)
195
+ if @fail_domain_cnt[domain]>2
196
+ puts "Error! Multiple ServFail conditions detected in method #{__method__}. Now skip remaining works on: #{sub_domain}" if @verbose
197
+ return valid_hosts
198
+ end
199
+ end
200
+ cnt=cnt+1
201
+ if x.nil?
202
+ next
203
+ elsif x.empty?
204
+ host=domain
205
+ else
206
+ host=[x,".",domain].join.downcase
207
+ end
208
+ valid_hosts.push(host) if valid_dns_record?(host)
209
+ # Logic to detecting the bluff if the DNS server return hostname we threw to it
210
+ if cnt==10 && valid_hosts.size>=10
211
+ valid_hosts=[host]
212
+ puts "Brute force method fail, as the DNS server response to every host-name threw at it!"
213
+ break
214
+ end
215
+ end
216
+ puts "Found DNS records on domain #{host}: #{valid_hosts}" if @verbose
217
+ @discovered_hosts_from_dns_bruter[host] = valid_hosts
218
+ my_host_tracker = nil
219
+ return valid_hosts.uniq
220
+ rescue Exception => ee
221
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
222
+ end
223
+ end
224
+
225
+ # Parallel DNS brute-forcer operating on the trusted domains - by utilizing fork manager to spawn multiple child processes on multiple sub_domain domains from the local hosts table simultaneously
226
+ def dns_brute_domains(targets,num=@max_parallel)
227
+ puts "Start the parallel brute-forcing with multiple child processes: #{num}"
228
+ begin
229
+ hosts=Array.new
230
+ # Sliced to chunks of 1,000 domains for each process time, to avoid potential overflow of large array ?
231
+ puts "Brute-forcing the following domain: #{targets}" if @verbose
232
+ targets.each_slice(1000).to_a.map do |slice|
233
+ hosts_new=dns_brute_workers(slice,num)
234
+ hosts << hosts_new
235
+ end
236
+ puts "Parallel bruting result: #{hosts.flatten}" if @verbose
237
+ return hosts.flatten
238
+ rescue Exception => ee
239
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
240
+ return hosts.flatten
241
+ end
242
+ end
243
+
244
+ # Parallel DNS brute-force all existing domains
245
+ def brute_all(num=@max_parallel)
246
+ puts "Start the parallel brute-forcing all domains with maximum child processes: #{num}"
247
+ begin
248
+ hosts=Array.new
249
+ my_dis=Wmap::HostTracker.new(:data_dir=>@data_dir)
250
+ known_domains=my_dis.dump_root_domains
251
+ hosts=dns_brute_domains(num, known_domains)
252
+ my_dis.adds(hosts)
253
+ my_dis.save!
254
+ my_dis=nil
255
+ hosts
256
+ rescue Exception => ee
257
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
258
+ end
259
+ end
260
+
261
+ # Return a list of hosts in the mutation form from the original, i.e. "ww1.example.com" => ["ww1,example.com","ww2.example.com",...]
262
+ def hostname_mutation(host)
263
+ puts "Start host mutation emulation on: #{host}" if @verbose
264
+ begin
265
+ hosts=Array.new
266
+ host=host.strip.downcase
267
+ raise "Invalid host format: #{host}" unless is_fqdn?(host)
268
+ unless is_domain_root?(host)
269
+ hostname=host.split('.')[0]
270
+ hosts.push(host)
271
+ case hostname
272
+ when /\d+/
273
+ #first form of mutation, i.e. "ww1" => ["ww1","ww2",...]
274
+ hostname.scan(/\d+/).map do |x|
275
+ y=x.to_i
276
+ 5.times do |i|
277
+ z=y+i+1
278
+ w=(y-i-1).abs
279
+ mut1=host.sub_domain(x,z.to_s)
280
+ mut2=host.sub_domain(x,w.to_s)
281
+ hosts.push(mut1,mut2)
282
+ end
283
+ end
284
+ else
285
+ puts "No mutation found for: #{host}" if @verbose
286
+ end
287
+ end
288
+ puts "Host mutation found: #{hosts.uniq}" if @verbose
289
+ return hosts.uniq
290
+ rescue Exception => ee
291
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
292
+ return hosts # fail-safe
293
+ end
294
+ end
295
+ alias_method :mutation, :hostname_mutation
296
+
297
+ # Print summary report of found hosts from the brute force attacks
298
+ def print_discovered_hosts_from_bruter
299
+ puts "\nSummary Report of the Discovered Hosts:"
300
+ @discovered_hosts_from_dns_bruter.each do |domain,hosts|
301
+ puts "Domain: #{domain}"
302
+ puts "Found hosts:"
303
+ puts @discovered_hosts_from_dns_bruter[domain]['hosts']
304
+ end
305
+ puts "End of the summary"
306
+ end
307
+ alias_method :print, :print_discovered_hosts_from_bruter
308
+ end
@@ -0,0 +1,142 @@
1
+ #--
2
+ # Wmap
3
+ #
4
+ # A pure Ruby library for Internet web application discovery and tracking.
5
+ #
6
+ # Copyright (c) 2012-2015 Yang Li <yang.li@owasp.org>
7
+ #++
8
+ #require "singleton"
9
+
10
+
11
+ module Wmap
12
+ class DomainTracker
13
+
14
+ # Class to differentiate the sub-domain from the top domain for the enterprise. This is needed for better managing
15
+ # of the sub-domains and the associated entities
16
+ class SubDomain < Wmap::DomainTracker
17
+ include Wmap::Utils
18
+ #include Singleton
19
+
20
+ attr_accessor :verbose, :domains_file, :max_parallel, :data_dir
21
+ attr_reader :known_internet_sub_domains
22
+
23
+ # Set default instance variables
24
+ def initialize (params = {})
25
+ @verbose=params.fetch(:verbose, false)
26
+ @data_dir=params.fetch(:data_dir, File.dirname(__FILE__)+'/../../../data/')
27
+ @max_parallel=params.fetch(:max_parallel, 40)
28
+ # Hash table to hold the trusted domains
29
+ @file_sub_domains=@data_dir + 'sub_domains'
30
+ File.write(@file_sub_domains, "") unless File.exist?(@file_sub_domains)
31
+ @known_internet_sub_domains=load_domains_from_file(@file_sub_domains) #unless @known_internet_sub_domains.size>0
32
+ end
33
+
34
+ # 'setter' to add sub-domain entry to the cache one at a time
35
+ def add(sub)
36
+ puts "Add entry to the local sub domain cache table: #{sub}" if @verbose
37
+ begin
38
+ record=Hash.new
39
+ sub=sub.strip.downcase
40
+ if @known_internet_sub_domains.key?(sub)
41
+ puts "Skip on known sub-domain: #{sub}" if @verbose
42
+ return nil
43
+ end
44
+ if zone_transferable?(sub)
45
+ record[sub]=true
46
+ else
47
+ record[sub]=false
48
+ end
49
+ puts "Adding new record into the data store: #{record}" if @verbose
50
+ @known_internet_sub_domains.merge!(record)
51
+ return record
52
+ rescue => ee
53
+ puts "Exception on method #{__method__} for #{sub}: #{ee}" if @verbose
54
+ end
55
+ end
56
+
57
+ # 'setter' to add domain entry to the cache in batch (from a list)
58
+ def bulk_add(list, num=@max_parallel)
59
+ puts "Add entries to the local domains cache table from list: #{list}" if @verbose
60
+ begin
61
+ results=Hash.new
62
+ domains=list
63
+ if domains.size > 0
64
+ Parallel.map(list, :in_processes => num) { |target|
65
+ add(target)
66
+ }.each do |process|
67
+ if process.nil?
68
+ next
69
+ elsif process.empty?
70
+ #do nothing
71
+ else
72
+ results.merge!(process)
73
+ end
74
+ end
75
+ @known_internet_sub_domains.merge!(results)
76
+ puts "Done loading entries."
77
+ return results
78
+ else
79
+ puts "Error: no entry is loaded. Please check your list and try again."
80
+ end
81
+ return results
82
+ rescue => ee
83
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
84
+ end
85
+ end
86
+ alias_method :adds, :bulk_add
87
+
88
+ # Procedures to identify sub-domain from the hosts store
89
+ def update_from_host_store!
90
+ puts "Invoke internal procedures to update the sub-domain list from the host store."
91
+ begin
92
+ # Step 1 - obtain the latest sub-domains
93
+ subs = Wmap::HostTracker.new(:data_dir=>@data_dir).dump_sub_domains - [nil,""]
94
+ # Step 2 - update the sub-domain list
95
+ unless subs.empty?
96
+ #subs.map { |x| self.add(x) unless domain_known?(x) }
97
+ self.bulk_add(subs,@max_parallel)
98
+ end
99
+ puts "Update discovered sub-domains into the store: #{@known_internet_sub_domains}"
100
+ self.save!(file_domains=@file_sub_domains, domains=@known_internet_sub_domains)
101
+ rescue Exception => ee
102
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
103
+ return nil
104
+ end
105
+ end
106
+ alias_method :update!, :update_from_host_store!
107
+
108
+ # Save the current domain hash table into a file
109
+ def save_sub_domains_to_file!(file_domains=@file_sub_domains, domains=@known_internet_sub_domains)
110
+ puts "Saving the current domains cache table from memory to file: #{file_domains} ..." if @verbose
111
+ begin
112
+ timestamp=Time.now
113
+ f=File.open(file_domains, 'w')
114
+ f.write "# Local domains file created by class #{self.class} method #{__method__} at: #{timestamp}\n"
115
+ f.write "# domain name, free zone transfer detected?\n"
116
+ domains.keys.sort.map do |key|
117
+ if domains[key]
118
+ f.write "#{key}, yes\n"
119
+ else
120
+ f.write "#{key}, no\n"
121
+ end
122
+ end
123
+ f.close
124
+ puts "Domain cache table is successfully saved: #{file_domains}"
125
+ rescue => ee
126
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
127
+ end
128
+ end
129
+ alias_method :save!, :save_sub_domains_to_file!
130
+ end
131
+
132
+ # Print summary report on all known / trust domains in the domain cache table
133
+ def print_known_sub_domains
134
+ puts "\nSummary of known Internet Sub-domains:"
135
+ self.known_internet_sub_domains.keys.sort.each do |domain|
136
+ puts domain
137
+ end
138
+ puts "End of the summary"
139
+ end
140
+
141
+ end
142
+ end