wmap 2.4.4

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.
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,333 @@
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
+
9
+ require "resolv"
10
+ require "netaddr"
11
+
12
+ # Main utility module to provide the common functions across different classes
13
+ module Wmap
14
+ module Utils
15
+ include Wmap::Utils::DomainRoot
16
+ include Wmap::Utils::UrlMagic
17
+ include Wmap::Utils::Logger
18
+ extend self
19
+
20
+ # Load entries from a text file and return an array
21
+ def file_2_list(f,lc=true)
22
+ puts "Loading records from file: #{f}" if @verbose
23
+ begin
24
+ list=Array.new
25
+ file = File.open(f, "r")
26
+ file.each_line do |line|
27
+ line=line.chomp.strip
28
+ next if line.nil?
29
+ next if line.empty?
30
+ next if line =~ /^\s*#/
31
+ line=line.downcase if lc==true
32
+ list.push(line.chomp.strip)
33
+ end
34
+ file.close
35
+ return list
36
+ rescue => ee
37
+ puts "Exception on method #{__method__} for file #{f}: #{ee}" if @verbose
38
+ return nil
39
+ end
40
+ end
41
+
42
+ # Save an array into a file
43
+ def list_2_file (list,file)
44
+ puts "Save list #{list} to plain file #{file}" if @verbose
45
+ begin
46
+ f = File.open(file, "w")
47
+ list.map do |ent|
48
+ #ent.strip!
49
+ # Append the unix line break
50
+ f.write("#{ent}\n")
51
+ end
52
+ f.close
53
+ rescue => ee
54
+ puts "Exception on method #{__method__} for file #{file}: #{ee}" if @verbose
55
+ return nil
56
+ end
57
+ end
58
+
59
+ # Load entries from a text file and return a hash
60
+ def file_2_hash(f,lc=true)
61
+ puts "Loading records from file: #{f}" if @verbose
62
+ begin
63
+ hs=Hash.new
64
+ file = File.open(f, "r")
65
+ file.each_line do |line|
66
+ line=line.chomp.strip
67
+ next if line.nil?
68
+ next if line.empty?
69
+ line=line.downcase if lc==true
70
+ next if line =~ /^\s*#/
71
+ hs[line]=true unless hs.key?(line)
72
+ end
73
+ file.close
74
+ return hs
75
+ rescue => ee
76
+ puts "Exception on method #{__method__} on #{f}: #{ee}" if @verbose
77
+ return nil
78
+ end
79
+ end
80
+
81
+ # Query the name-server to see if the dns record is still valid
82
+ def valid_dns_record? (hostname)
83
+ puts "Validate the hostname record: #{hostname}" if @verbose
84
+ begin
85
+ ips=Resolv.getaddresses(hostname)
86
+ if ips.empty?
87
+ return false
88
+ else
89
+ puts "Found: #{hostname}" if @verbose
90
+ return true
91
+ end
92
+ rescue => ee
93
+ puts "Exception on method #{__method__} for host #{hostname}: #{ee}" if @verbose
94
+ return false
95
+ end
96
+ end
97
+ alias_method :is_record? , :valid_dns_record?
98
+ alias_method :a_record? , :valid_dns_record?
99
+
100
+ # Test the DNS server if zone transfer is allowed. If allowed, save the found hosts into the class variable.
101
+ def zone_transferable?(domain)
102
+ puts "Check if the domain allows free zone transfer: #{domain}"
103
+ begin
104
+ transferable=false
105
+ domain=domain.downcase
106
+ nameservers = get_nameservers(domain)
107
+ raise "Unable to determine the name servers for domain #{domain}" if nameservers.nil?
108
+ puts "Retrieved name servers: #{nameservers}" if @verbose
109
+ nameservers.each do |nssrv|
110
+ begin
111
+ puts "Attempt zone transfer on name server: #{nssrv}"
112
+ if nssrv.nil?
113
+ abort "Method input variable error: no name server found!" if @verbose
114
+ next
115
+ end
116
+ zt = Dnsruby::ZoneTransfer.new
117
+ zt.server=(nssrv) if nssrv!=""
118
+ records = zt.transfer(domain)
119
+ if records==nil
120
+ puts "#{domain} zone transfer is not allowed on name server: #{nssrv}"
121
+ next
122
+ else
123
+ puts "#{domain} zone transfer is allowed!"
124
+ transferable=true
125
+ end
126
+ rescue Exception=>ee
127
+ puts "Exception on method zone_transferable? for domain #{domain}: #{ee}"
128
+ end
129
+ end
130
+ return transferable
131
+ rescue Exception => ee
132
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
133
+ return nil
134
+ end
135
+ end
136
+
137
+ # Test if it's a legitimate IP4 address
138
+ def is_ip? (ip)
139
+ puts "Validate the IP format is valid: #{ip}" if @verbose
140
+ begin
141
+ ip=ip.strip
142
+ raise "This is an URL: #{ip}" if is_url?(ip)
143
+ if ip =~ /\d+\.\d+\.\d+.\d+/ and ip !~ /\/\d+/
144
+ octs=ip.split('.')
145
+ return false unless octs.size==4
146
+ octs.map { |x| return false unless x.to_i >=0 and x.to_i <=255 }
147
+ else
148
+ return false
149
+ end
150
+ puts "Confirmed as a valid IP: #{ip}" if @verbose
151
+ return true
152
+ rescue => ee
153
+ puts "Exception on method is_ip? for #{ip}: #{ee}" if @verbose
154
+ return false
155
+ end
156
+ end
157
+ alias_method :is_valid_ip?, :is_ip?
158
+
159
+ # Simple test a host string format. Return true if it contains a valid internet domain sub-string. Note: Don't be confused with another method 'valid_dns_record?', which is a stricter and time-consuming test on the DNS server for a resolvable internet host.
160
+ def is_fqdn? (host)
161
+ puts "Validate the host-name format is valid: #{host}" if @verbose
162
+ begin
163
+ return false if is_ip?(host) or is_url?(host)
164
+ domain=get_domain_root(host)
165
+ if domain.nil?
166
+ return false
167
+ elsif is_domain_root?(domain)
168
+ return true
169
+ else
170
+ return false
171
+ end
172
+ rescue => ee
173
+ puts "Exception on method is_fqdn? for #{host}: #{ee}" if @verbose
174
+ return false
175
+ end
176
+ end
177
+ alias_method :is_host?, :is_fqdn?
178
+
179
+ # Simple test to determine if the entry is in valid network cidr format
180
+ def is_cidr?(cidr)
181
+ puts "Validate if the entry is valid CIDR format: #{cidr}" if @verbose
182
+ begin
183
+ cidr=cidr.strip
184
+ if cidr =~ /^(\d+\.\d+\.\d+.\d+)\/(\d+)$/
185
+ ip=$1
186
+ mask=$2.to_i
187
+ if is_ip?(ip)
188
+ if mask >0 and mask <=32
189
+ puts "confirmed as a valid CIDR entry: #{cidr}" if @verbose
190
+ return true
191
+ else
192
+ return false
193
+ end
194
+ else
195
+ return false
196
+ end
197
+ else
198
+ return false
199
+ end
200
+ rescue => ee
201
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
202
+ return false
203
+ end
204
+ end
205
+
206
+ # Sort an array of IPs in the ascendant order
207
+ def sort_ips (ips)
208
+ begin
209
+ "Sort the list of IP address in the ascendant order: #{ips}" if @verbose
210
+ return NetAddr.sort(ips)
211
+ rescue => ee
212
+ puts "Exception on method sort_ips for IPs #{ips}: #{ee}" # if @verbose
213
+ end
214
+ end
215
+
216
+ # Perform the DNS query on a hostname over the Internet. Return the resolved IP(s) in an array
217
+ def host_2_ips (hostname)
218
+ begin
219
+ ips=Array.new
220
+ if is_ip?(hostname)
221
+ ips.push(hostname)
222
+ return ips
223
+ else
224
+ ips = Resolv.getaddresses(hostname)
225
+ if (ips.empty?) then
226
+ puts "Failed to resolve #{hostname}" if @verbose
227
+ return nil
228
+ else
229
+ return ips
230
+ end
231
+ end
232
+ rescue => ee
233
+ puts "Exception on method host_2_ips for host #{hostname}: #{ee}" if @verbose
234
+ return nil
235
+ end
236
+ end
237
+ alias_method :ns_lookup, :host_2_ips
238
+
239
+ # Perform DNS query on a hostname. Return the first resolved IP as a string
240
+ def host_2_ip (hostname)
241
+ puts "Perform DNS query on host: #{hostname}" if @verbose
242
+ begin
243
+ ips=Array.new
244
+ if is_ip?(hostname)
245
+ puts "No change - same IP is returned. " if @verbose
246
+ return hostname.strip
247
+ else
248
+ ips=Resolv.getaddresses(hostname)
249
+ if (ips.empty?) then
250
+ puts "Failed to resolve #{hostname}" if @verbose
251
+ return nil
252
+ else
253
+ puts "IP found: #{ips.first}" if @verbose
254
+ return ips.first.strip
255
+ end
256
+ end
257
+ rescue => ee
258
+ puts "Exception on method host_2_ip for host #{hostname}: #{ee}" if @verbose
259
+ return nil
260
+ end
261
+ end
262
+
263
+ # Retrieve a list of the authoritative name servers from the Internet whois data repository for the host / subdomain / domain
264
+ def get_nameservers (host)
265
+ puts "Retrieve a list of authoritative name server for: #{host}" if @verbose
266
+ begin
267
+ domain=get_domain_root(host)
268
+ w=Wmap::Whois.new
269
+ ns = w.query(domain).nameservers.map! { |x| x.name }
270
+ if ns.empty?
271
+ puts "No name server found for domain root: #{domain}" if @verbose
272
+ return nil
273
+ else
274
+ return ns
275
+ end
276
+ rescue => ee
277
+ puts "Exception on method get_nameservers for #{host}: #{ee}" if @verbose
278
+ return nil
279
+ end
280
+ end
281
+
282
+ # Retrieve the first name server from the Internet whois data repository for the host / subdomain / domain
283
+ def get_nameserver (host)
284
+ puts "Retrieve the first authoritative name server for: #{host}" if @verbose
285
+ begin
286
+ domain=get_domain_root(host)
287
+ w=Wmap::Whois.new
288
+ ns = w.query(domain).nameservers.map! { |x| x.name }
289
+ if ns.empty?
290
+ puts "No name server found for domain root: #{domain}" if @verbose
291
+ return nil
292
+ else
293
+ return ns.first
294
+ end
295
+ rescue => ee
296
+ puts "Exception on method get_nameservers for #{host}: #{ee}" if @verbose
297
+ return nil
298
+ end
299
+ end
300
+ alias_method :get_ns, :get_nameserver
301
+
302
+ # Perform reverse dns lookup for an IP. Return the found 'hostname' if found, or the original IP if not
303
+ def reverse_dns_lookup (ip)
304
+ puts "Retrieve the hostname by the reverse DNS lookup on IP: #{ip}"
305
+ hostname = ip
306
+ begin
307
+ hostname = Socket.gethostbyaddr(ip.split('.').collect{ |x| x.to_i}.pack("CCCC"))[0]
308
+ return hostname.downcase
309
+ rescue => ee
310
+ puts "Exception on method reverse_dns_lookup: #{ee}" if @verbose
311
+ return hostname
312
+ end
313
+ end
314
+ alias_method :ip_2_host, :reverse_dns_lookup
315
+
316
+ # Convert a CIDR to a list of IPs: Input is a CIDR expression such as '192.168.1.1/30', output is an array of IPs
317
+ def cidr_2_ips (cidr)
318
+ puts "Method to convert a CIDR block into a list of IPs: #{cidr}" if @verbose
319
+ begin
320
+ cidr4 = NetAddr::CIDR.create(cidr)
321
+ ips = cidr4.enumerate(:Limit => 0, :Bitstep => 1)
322
+ #ips2 = ips.slice!(1, (ips.length-2))
323
+ return ips
324
+ rescue => ee
325
+ puts "Exception on method #{__method__}: #{ee}" if @verbose
326
+ return nil
327
+ end
328
+ end
329
+
330
+
331
+
332
+ end
333
+ end
data/lib/wmap/whois.rb ADDED
@@ -0,0 +1,76 @@
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 "whois"
9
+
10
+ # Wrapper class of the 'ruby-whois' library
11
+ class Wmap::Whois
12
+ include Wmap::Utils
13
+
14
+ attr_accessor :timeout, :verbose
15
+
16
+ # Set default instance variables
17
+ def initialize (params = {})
18
+ @verbose=params.fetch(:verbose, false)
19
+ @timeout=params.fetch(:timeout, 10)
20
+ end
21
+
22
+ # Wrapper for the Ruby Whois client class
23
+ def lookup(object)
24
+ puts "Perform whois lookup on: #{object}" if @verbose
25
+ return Whois.lookup(object)
26
+ end
27
+ alias_method :query, :lookup
28
+
29
+ # Method to extract the netname information from the whois data repository query for an IP
30
+ def get_netname (ip)
31
+ puts "Perform whois lookup on an IP address. Then extract the netname from the query result for the IP: #{ip}" if @verbose
32
+ begin
33
+ ip.strip!
34
+ raise "Unknown IP/CIDR format: #{ip}" unless is_ip?(ip) or is_cidr?(ip)
35
+ content_to_parse=query(ip).to_s
36
+ if content_to_parse =~ /^netname:(.+)\n/i
37
+ return $1.strip
38
+ elsif content_to_parse =~ /^.+\((NET\-.+)\).+\n/i
39
+ return $1.strip
40
+ else
41
+ return "UNKNOWN"
42
+ end
43
+ return "UNKNOWN"
44
+ rescue Exception => ee
45
+ puts "Exception on method get_netname: #{ee}" if @verbose
46
+ return "UNKNOWN"
47
+ end
48
+ end
49
+
50
+ # Method to extract the netname description from the whois data repository query for an IP
51
+ def get_net_desc (ip)
52
+ puts "Perform whois lookup on an IP address. Then extract the netname description from the query result for the IP: #{ip}" if @verbose
53
+ begin
54
+ ip.strip!
55
+ raise "Unknown IP/CIDR format: #{ip}" unless is_ip?(ip) or is_cidr?(ip)
56
+ desc=String.new
57
+ content_to_parse=query(ip).to_s
58
+ content_to_parse.scan(/^descr:(.+)\n/i).flatten.map do |entry|
59
+ desc=desc + " " + entry.strip
60
+ end
61
+ if desc.empty?
62
+ if content_to_parse =~ /^(.+)\((NET\-.+)\).+\n/i
63
+ desc=$1.strip
64
+ elsif content_to_parse =~ /^OrgName:(.+)\n/i
65
+ desc=$1.strip
66
+ else
67
+ desc="UNKNOWN"
68
+ end
69
+ end
70
+ return desc
71
+ rescue Exception => ee
72
+ puts "Exception on method get_net_desc: #{ee}" if @verbose
73
+ return "UNKNOWN"
74
+ end
75
+ end
76
+ end
data/lib/wmap.rb ADDED
@@ -0,0 +1,227 @@
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 'wmap/utils/domain_root'
9
+ require 'wmap/utils/url_magic'
10
+ require 'wmap/utils/logger'
11
+ require 'wmap/utils/utils'
12
+ require 'wmap/cidr_tracker'
13
+ require 'wmap/domain_tracker'
14
+ require 'wmap/domain_tracker/sub_domain'
15
+ require 'wmap/host_tracker'
16
+ require 'wmap/host_tracker/primary_host'
17
+ require 'wmap/whois'
18
+ require 'wmap/url_checker'
19
+ require 'wmap/network_profiler'
20
+ require 'wmap/port_scanner'
21
+ require 'wmap/url_crawler'
22
+ require 'wmap/dns_bruter'
23
+ require 'wmap/site_tracker'
24
+ require 'wmap/site_tracker/deactivated_site'
25
+ require 'wmap/geoip_tracker'
26
+ require 'wmap/google_search_scraper'
27
+
28
+ module Wmap
29
+
30
+ NAME = "Wmap"
31
+ GEM = "wmap"
32
+ VERSION = File.dirname(__FILE__) + "/../version.txt"
33
+
34
+ class << self
35
+ attr_accessor :known_internet_domains
36
+ attr_writer :verbose
37
+
38
+ # Simple parser for the project version file
39
+ def read_ver
40
+ ver=Hash.new
41
+ f=File.open(VERSION,'r')
42
+ f.each do |line|
43
+ line.chomp!
44
+ case line
45
+ when /^(\s)*#/
46
+ next
47
+ when /\=/
48
+ entry=line.split("=").map! {|x| x.strip}
49
+ ver[entry[0]]=entry[1]
50
+ end
51
+ end
52
+ f.close
53
+ return ver
54
+ end
55
+
56
+ # Project banner in ASCII Art 'soft' format, courtesy to http://patorjk.com/software/taag/
57
+ def banner
58
+ ver=read_ver
59
+ art=",--. ,--. ,--. ,--. ,--.
60
+ | | | | ,---. | |-. | `.' | ,--,--. ,---. ,---. ,---. ,--.--.
61
+ | |.'.| || .-. :| .-. ' | |'.'| |' ,-. || .-. || .-. || .-. :| .--'
62
+ | ,'. |\ --.| `-' | | | | |\ '-' || '-' '| '-' '\ --.| |
63
+ '--' '--' `----' `---' `--' `--' `--`--'| |-' | |-' `----'`--'
64
+ `--' `--' "
65
+ string = "-"*80 + "\n" + art + "\n" + "Version: " + ver["version"] + "\tRelease Date: " + ver["date"] + "\nDesigned and developed by: " + ver["author"] + "\nEmail: " + ver["email"] + "\tLinkedIn: " + ver["linkedin"] + "\n" + "-"*80
66
+ end
67
+
68
+ # Explorer to discover and inventory web application / service automatically
69
+ def wmap(seed)
70
+ cmd="bin/wmap" + " " + seed
71
+ system(cmd)
72
+ end
73
+
74
+ # Crawler to search url contents for new sites
75
+ def crawl(url)
76
+ crawler=Wmap::UrlCrawler.new
77
+ crawler.crawl(url)
78
+ end
79
+
80
+ # whois query and sort the result into structured data
81
+ def whois(domain)
82
+ whois=Wmap::Whois.new(:verbose=>false)
83
+ whois.query(domain)
84
+ end
85
+
86
+ # Fast tcp port scanner on a single host or IP
87
+ def scan(host)
88
+ scanner=Wmap::PortScanner.new
89
+ scanner.scan(host)
90
+ end
91
+
92
+ # Fast multi-processes tcp port scanner on a list of targets
93
+ def scans(target_list)
94
+ scanner=Wmap::PortScanner.new
95
+ scanner.scans(target_list)
96
+ end
97
+
98
+ # CIDR Tracking - check the host against the local CIDR seed file, return the CIDR tracking path if found
99
+ def track(host)
100
+ tracker=Wmap::CidrTracker.new
101
+ tracker.cidr_worker(host)
102
+ end
103
+
104
+ # GeoIP Tracking - check the host / IP against the GeoIP data repository, return the Geographic information if found
105
+ def geoip(host)
106
+ tracker=Wmap::GeoIPTracker.new
107
+ tracker.query(host)
108
+ end
109
+
110
+ # URL checker - check the status of the remote URL
111
+ def check(url)
112
+ checker=Wmap::UrlChecker.new(:verbose=>false)
113
+ checker.url_worker(url)
114
+ end
115
+
116
+ # Check if the IP is within the range of the known CIDR blocks
117
+ def ip_trusted?(ip)
118
+ tracker=Wmap::CidrTracker.new
119
+ tracker.ip_trusted?(ip)
120
+ end
121
+
122
+ # Domain Tracking - check with the trust domain seed file locally, to determine if it's a new internet domain
123
+ # NOT to confuse with the Internet 'whois' lookup
124
+ def domain_known?(domain)
125
+ tracker=Wmap::DomainTracker.new
126
+ tracker.domain_known?(domain)
127
+ end
128
+
129
+ # Host Tracking - check local hosts file to see if this is a hostname known from the host seed file
130
+ # NOT to confuse with a regular DNS lookup over the internet
131
+ def host_known?(host)
132
+ tracker=Wmap::HostTracker.new.host_known?(host)
133
+ end
134
+
135
+ # Sub-domain tracking - check local hosts file to see if the sub-domain is already known
136
+ def sub_domain_known?(host)
137
+ tracker=Wmap::HostTracker.new.sub_domain_known?(host)
138
+ end
139
+
140
+ # IP Tracking - check local hosts file to see if this is an IP known from the seed file
141
+ # NOT to confuse with a regular reverse DNS lookup over the internet
142
+ def ip_known?(ip)
143
+ tracker=Wmap::HostTracker.new.ip_known?(ip)
144
+ end
145
+
146
+ # DNS Brute Forcer
147
+ def dns_brute(domain)
148
+ bruter=Wmap::DnsBruter.new
149
+ bruter.query(domain)
150
+ end
151
+
152
+ # Retrieve root domain from a host
153
+ def domain_root(host)
154
+ Wmap::Utils.get_domain_root(host)
155
+ end
156
+
157
+ # Log the information into file
158
+ def wlog(msg,agent,log_file)
159
+ Wmap::Utils.wlog(msg,agent,log_file)
160
+ end
161
+
162
+ # Host-name mutation for catch easily guessable hostname, i.e. "ww1.example.com" => ["ww1,example.com","ww2.example.com",...]
163
+ def mutation (host)
164
+ Wmap::DnsBruter.new.hostname_mutation(host)
165
+ end
166
+
167
+ # Check URL/Site response code
168
+ def response_code(url)
169
+ checker=Wmap::UrlChecker.new
170
+ checker.response_code(url)
171
+ end
172
+
173
+ # Search the site repository for all entries that match the pattern
174
+ def search(pattern)
175
+ searcher=Wmap::SiteTracker.new
176
+ searcher.search(pattern)
177
+ end
178
+
179
+ # Dump out the unique sites into a plain file
180
+ def dump(file)
181
+ store=Wmap::SiteTracker.new
182
+ store.save_uniq_sites(file)
183
+ end
184
+
185
+ # Dump out the unique sites into a XML file
186
+ def dump_xml(file)
187
+ store=Wmap::SiteTracker.new
188
+ store.save_uniq_sites_xml(file)
189
+ end
190
+
191
+ # Refresh the site information in the local data repository
192
+ def refresh(site)
193
+ store=Wmap::SiteTracker.new
194
+ store.refresh(site)
195
+ store.save!
196
+ end
197
+
198
+ # Refresh the site information in the local data repository
199
+ def refresh_all
200
+ store=Wmap::SiteTracker.new
201
+ store.refresh_all
202
+ store.save!
203
+ end
204
+
205
+ # Search the Google engines and sort out sites known by Google
206
+ def google
207
+ sites=Wmap::GoogleSearchScraper.new.workers.keys
208
+ end
209
+
210
+ # Print a site's full information from the repository
211
+ def print(site)
212
+ searcher=Wmap::SiteTracker.new
213
+ searcher.print_site(site)
214
+ end
215
+
216
+ # Print a site's full information from the repository
217
+ def print_all
218
+ searcher=Wmap::SiteTracker.new
219
+ searcher.print_all_sites
220
+ end
221
+
222
+ private
223
+
224
+
225
+
226
+ end
227
+ end
data/logs/wmap.log ADDED
@@ -0,0 +1,17 @@
1
+ 2018-01-10 16:23:21 -0500: wmap: Execute the command: wmap /Users/ylee/www_wmap/uploads/1/seed
2
+ 2018-01-10 16:39:40 -0500: wmap: Execute the command: wmap uploads/1/seed
3
+ 2018-01-10 16:53:13 -0500: wmap: Execute the command: wmap /Users/ylee/www_wmap/uploads/1/seed
4
+ 2018-01-10 17:04:02 -0500: wmap: Execute the command: wmap uploads/1/seed
5
+ 2018-01-11 14:33:42 -0500: wmap: Execute the command: wmap uploads/1/seed
6
+ 2018-01-11 14:43:00 -0500: wmap: Execute the command: wmap /Users/ylee/www_wmap/uploads/1/seed
7
+ 2018-01-11 14:47:02 -0500: wmap: Execute the command: wmap uploads/1/seed
8
+ 2018-01-11 14:52:09 -0500: wmap: Execute the command: wmap www.cnn.com
9
+ 2018-01-11 15:25:26 -0500: wmap: Execute the command: wmap uploads/1/seed
10
+ 2018-01-11 15:25:39 -0500: wdump: Execute the command: wdump
11
+ 2018-01-11 15:25:46 -0500: wdump: Execute the command: wdump /tmp/out
12
+ 2018-01-11 15:30:42 -0500: wmap: Execute the command: wmap uploads/1/seed
13
+ 2018-01-11 15:46:13 -0500: wmap: Execute the command: wmap uploads/1/seed
14
+ 2018-01-11 15:54:04 -0500: wmap: Execute the command: wmap uploads/1/seed
15
+ 2018-01-11 15:56:46 -0500: wmap: Execute the command: wmap uploads/1/seed
16
+ 2018-01-12 14:04:50 -0500: wmap: Execute the command: wmap /Users/ylee/www_wmap/uploads/1/seed
17
+ 2018-01-16 11:25:58 -0500: wmap: Execute the command: wmap 206.156.53.0/24