forked from smicallef/spiderfoot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sfp_googlemaps.py
165 lines (137 loc) · 5.48 KB
/
sfp_googlemaps.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------------
# Name: sfp_googlemaps
# Purpose: SpiderFoot plug-in to identify historical certificates for a domain
# from googlemaps.sh, and from this identify hostnames.
#
# Author: Steve Micallef <steve@binarypool.com>
#
# Created: 18/03/2017
# Copyright: (c) Steve Micallef 2017
# Licence: MIT
# -------------------------------------------------------------------------------
import json
import urllib
from spiderfoot import SpiderFootEvent, SpiderFootPlugin
class sfp_googlemaps(SpiderFootPlugin):
meta = {
'name': "Google Maps",
'summary': "Identifies potential physical addresses and latitude/longitude coordinates.",
'flags': ["apikey"],
'useCases': ["Footprint", "Investigate", "Passive"],
'categories': ["Real World"],
'dataSource': {
'website': "https://cloud.google.com/maps-platform/",
'model': "FREE_AUTH_LIMITED",
'references': [
"https://developers.google.com/maps/documentation/?_ga=2.135220017.1220421370.1587340370-900596925.1587340370"
],
'apiKeyInstructions': [
"Visit https://cloud.google.com/maps-platform/",
"Register a free Google account",
"Click on 'Get Started'",
"Click on 'API'",
"Select the type of API",
"Navigate to https://console.cloud.google.com/apis/credentials",
"Click on 'Credentials'",
"The API Key will be listed under 'API Keys'"
],
'favIcon': "https://www.gstatic.com/devrel-devsite/prod/v2210deb8920cd4a55bd580441aa58e7853afc04b39a9d9ac4198e1cd7fbe04ef/cloud/images/favicons/onecloud/favicon.ico",
'logo': "https://www.gstatic.com/devrel-devsite/prod/v2210deb8920cd4a55bd580441aa58e7853afc04b39a9d9ac4198e1cd7fbe04ef/cloud/images/cloud-logo.svg",
'description': "Explore where real-world insights and immersive location experiences can take your business.\n"
"Build with reliable, comprehensive data for over 200 countries and territories.\n"
"has been done here. If line breaks are needed for breaking up\n"
"Scale confidently, backed by our infrastructure.",
}
}
opts = {
"api_key": ""
}
optdescs = {
"api_key": "Google Geocoding API Key."
}
results = None
errorState = False
def setup(self, sfc, userOpts=dict()):
self.sf = sfc
self.results = self.tempStorage()
self.errorState = False
for opt in list(userOpts.keys()):
self.opts[opt] = userOpts[opt]
def watchedEvents(self):
return ['DOMAIN_NAME', 'PHYSICAL_ADDRESS']
def producedEvents(self):
return ["PHYSICAL_ADDRESS", "PHYSICAL_COORDINATES", "RAW_RIR_DATA"]
def query(self, address):
params = urllib.parse.urlencode({
'key': self.opts['api_key'],
'address': address.encode('raw_unicode_escape').decode("ascii", errors='replace')
})
res = self.sf.fetchUrl(
f"https://maps.googleapis.com/maps/api/geocode/json?{params}",
timeout=self.opts['_fetchtimeout'],
useragent=self.opts['_useragent']
)
if res['content'] is None:
self.info(f"No location info found for {address}")
return None
return res
def handleEvent(self, event):
eventName = event.eventType
srcModuleName = event.module
eventData = event.data
if self.errorState:
return
if eventData in self.results:
self.debug(f"Skipping {eventData}, already checked.")
return
self.results[eventData] = True
self.debug(f"Received event, {eventName}, from {srcModuleName}")
if self.opts["api_key"] == "":
self.error(
f"You enabled {self.__class__.__name__} but did not set an API key!"
)
self.errorState = True
return
res = self.query(eventData)
if not res:
self.debug(f"No information found for {eventData}")
return
evt = SpiderFootEvent(
"RAW_RIR_DATA",
res['content'],
self.__name__,
event
)
self.notifyListeners(evt)
try:
data = json.loads(res['content'])['results'][0]
except Exception as e:
self.debug(f"Error processing JSON response: {e}")
return
if srcModuleName == "sfp_googlemaps":
return
geometry = data.get('geometry')
if geometry:
location = data.get('location')
if location:
lat = location.get('lat')
lng = location.get('lng')
if lat and lng:
evt = SpiderFootEvent(
"PHYSICAL_COORDINATES",
f"{lat},{lng}",
self.__name__,
event
)
self.notifyListeners(evt)
formatted_address = data.get('formatted_address')
if formatted_address:
evt = SpiderFootEvent(
"PHYSICAL_ADDRESS",
data['formatted_address'],
self.__name__,
event
)
self.notifyListeners(evt)
# End of sfp_googlemaps class