-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathsfp_tool_wafw00f.py
More file actions
160 lines (126 loc) · 4.75 KB
/
Copy pathsfp_tool_wafw00f.py
File metadata and controls
160 lines (126 loc) · 4.75 KB
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
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------------
# Name: sfp_tool_wafw00f
# Purpose: SpiderFoot plug-in for using the WAFW00F tool.
# Tool: https://github.com/EnableSecurity/wafw00f
#
# Author: <bcoles@gmail.com>
#
# Created: 2021-03-10
# Copyright: (c) bcoles 2021
# Licence: MIT
# -------------------------------------------------------------------------------
import json
import os.path
import tempfile
from subprocess import PIPE, Popen
from spiderfoot import SpiderFootEvent, SpiderFootPlugin, SpiderFootHelpers
class sfp_tool_wafw00f(SpiderFootPlugin):
meta = {
'name': "Tool - WAFW00F",
'summary': "Identify what web application firewall (WAF) is in use on the specified website.",
'flags': ["tool"],
'useCases': ["Footprint", "Investigate"],
'categories': ["Crawling and Scanning"],
'toolDetails': {
'name': "WAFW00F",
'description': "WAFW00F allows one to identify and fingerprint Web Application Firewall (WAF) products protecting a website.",
'website': 'https://github.com/EnableSecurity/wafw00f',
'repository': 'https://github.com/EnableSecurity/wafw00f'
},
}
opts = {
'python_path': 'python3',
'wafw00f_path': ''
}
optdescs = {
'python_path': "Path to Python 3 interpreter to use for wafw00f. If just 'python3' then it must be in your $PATH.",
'wafw00f_path': "Path to the wafw00f executable file. Must be set."
}
results = None
errorState = False
def setup(self, sfc, userOpts=dict()):
self.sf = sfc
self.results = dict()
self.errorState = False
self.__dataSource__ = "Target Website"
for opt in userOpts.keys():
self.opts[opt] = userOpts[opt]
def watchedEvents(self):
return ['INTERNET_NAME']
def producedEvents(self):
return ['RAW_RIR_DATA', 'WEBSERVER_TECHNOLOGY']
def handleEvent(self, event):
eventName = event.eventType
srcModuleName = event.module
eventData = event.data
self.debug(f"Received event, {eventName}, from {srcModuleName}")
if self.errorState:
return
if eventData in self.results:
self.debug(f"Skipping {eventData} as already scanned.")
return
self.results[eventData] = True
if not self.opts['wafw00f_path']:
self.error("You enabled sfp_tool_wafw00f but did not set a path to the tool!")
self.errorState = True
return
exe = self.opts['wafw00f_path']
if self.opts['wafw00f_path'].endswith('/'):
exe = exe + 'wafw00f'
if not os.path.isfile(exe):
self.error(f"File does not exist: {exe}")
self.errorState = True
return
url = eventData
if not SpiderFootHelpers.sanitiseInput(url):
self.error("Invalid input, refusing to run.")
return
output_file = tempfile.mktemp(suffix=".json")
args = [
self.opts['python_path'],
exe,
'-a',
'-o',
output_file,
url
]
try:
p = Popen(args, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(input=None)
except Exception as e:
self.error(f"Unable to run wafw00f: {e}")
return
if p.returncode != 0:
self.error(f"Unable to read wafw00f output\nstderr: {stderr}\nstdout: {stdout}")
return
try:
with open(output_file, "r") as f:
result_json = json.load(f)
except Exception as e:
self.error(f"Could not parse wafw00f output as JSON from file: {e}")
return
finally:
if os.path.exists(output_file):
os.remove(output_file)
if not result_json:
self.debug(f"wafw00f returned no output for {eventData}")
return
evt = SpiderFootEvent('RAW_RIR_DATA', json.dumps(result_json), self.__name__, event)
self.notifyListeners(evt)
for waf in result_json:
if not waf:
continue
firewall = waf.get('firewall')
if not firewall:
continue
if firewall == 'Generic':
continue
manufacturer = waf.get('manufacturer')
if not manufacturer:
continue
software = ' '.join(filter(None, [manufacturer, firewall]))
if software:
evt = SpiderFootEvent('WEBSERVER_TECHNOLOGY', software, self.__name__, event)
self.notifyListeners(evt)
# End of sfp_tool_wafw00f class