CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/rex/google/geolocation.rb
Views: 11779
1
#!/usr/bin/env ruby
2
3
require 'net/http'
4
require 'json'
5
6
module Rex
7
module Google
8
# @example
9
# g = Rex::Google::Geolocation.new
10
# g.set_api_key('example')
11
# g.add_wlan("00:11:22:33:44:55", "example", -80)
12
# g.fetch!
13
# puts g, g.google_maps_url
14
class Geolocation
15
GOOGLE_API_URI = "https://www.googleapis.com/geolocation/v1/geolocate?key="
16
17
attr_accessor :accuracy
18
attr_accessor :latitude
19
attr_accessor :longitude
20
21
def initialize
22
@uri = URI.parse(URI::DEFAULT_PARSER.escape(GOOGLE_API_URI))
23
@wlan_list = []
24
end
25
26
# Ask Google's Maps API for the location of a given set of BSSIDs (MAC
27
# addresses of access points), ESSIDs (AP names), and signal strengths.
28
def fetch!
29
request = Net::HTTP::Post.new(@uri.request_uri)
30
request.body = {'wifiAccessPoints' => @wlan_list}.to_json
31
request['Content-Type'] = 'application/json'
32
http = Net::HTTP.new(@uri.host, @uri.port)
33
http.use_ssl = true
34
response = http.request(request)
35
36
msg = "Failure connecting to Google for location lookup."
37
if response && response.code == '200'
38
results = JSON.parse(response.body)
39
self.latitude = results["location"]["lat"]
40
self.longitude = results["location"]["lng"]
41
self.accuracy = results["accuracy"]
42
elsif response && response.body && response.code != '404' # we can json load and get a good error message
43
results = JSON.parse(response.body)
44
msg += " Code #{results['error']['code']} for query #{@uri} with error #{results['error']['message']}"
45
fail msg
46
else
47
msg += " Code #{response.code} for query #{@uri}" if response
48
fail msg
49
end
50
end
51
52
# Add an AP to the list to send to Google when {#fetch!} is called.
53
#
54
# @param mac [String] in the form "00:11:22:33:44:55"
55
# @param signal_strength [String] a thing like
56
def add_wlan(mac, signal_strength)
57
@wlan_list.push({ :macAddress => mac.upcase.to_s, :signalStrength => signal_strength.to_s })
58
end
59
60
def set_api_key(key)
61
@uri = URI.parse(URI::DEFAULT_PARSER.escape(GOOGLE_API_URI + key))
62
end
63
64
def google_maps_url
65
"https://maps.google.com/?q=#{latitude},#{longitude}"
66
end
67
68
def to_s
69
"Google indicates the device is within #{accuracy} meters of #{latitude},#{longitude}."
70
end
71
end
72
end
73
end
74
75