-
Notifications
You must be signed in to change notification settings - Fork 0
/
vulnerability_scanner.py
162 lines (137 loc) · 5.81 KB
/
vulnerability_scanner.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
import requests
import socket
from urllib.parse import urljoin
class VulnerabilityScanner:
def __init__(self, site_map):
"""
Initialize the scanner with a site map.
@param site_map: List of URLs to scan.
"""
self.site_map = site_map
def run(self):
"""
Run all vulnerability tests.
"""
self.check_for_sql_injection()
self.check_for_xss()
def check_for_sql_injection(self):
"""
Check for SQL injection vulnerabilities.
"""
# Common SQL injection payloads to test against URLs.
sql_payloads = [
"'", "''", "\"", "\"\"", "1' OR '1'='1", "1\" OR \"1\"=\"1",
"admin'--", "admin' #", "admin'/*", "' or 1=1--", "\" or 1=1--"
]
# Iterate over each URL in the site map
for url in self.site_map:
# Test each payload against the URL
for payload in sql_payloads:
malicious_url = url + payload
response = requests.get(malicious_url)
# If a common SQL error is found in the response, report the URL
if "error" in response.text.lower():
print(f"[!] Potential SQL injection vulnerability found at {malicious_url}")
def check_for_xss(self):
"""
Check for XSS vulnerabilities.
"""
# Common XSS payloads to test in forms
xss_payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"<body onload=alert('XSS')>"
]
# Iterate over each URL in the site map
for url in self.site_map:
# Extract all forms from the URL
forms = self.extract_forms(url)
# Test each form with each XSS payload
for form in forms:
for payload in xss_payloads:
form_data = self.get_form_data(form, payload)
response = self.submit_form(form, form_data, url)
# If the payload is reflected in the response, report the URL
if payload in response.text:
print(f"[!] Potential XSS vulnerability found at {url}")
def check_for_ssrf(self, url):
"""
Check for Server-Side Request Forgery (SSRF) vulnerabilities.
@param url: The URL to test for SSRF vulnerabilities.
"""
ssrf_payload = "http://localhost" # Payload to test for SSRF
# Send a GET request with the SSRF payload
response = requests.get(url, params={"url_param": ssrf_payload})
# Check if the response contains an indicator of SSRF vulnerability
if "ssrf_vulnerable_indicator" in response.text:
print(f"[!] Potential SSRF vulnerability found at {url}")
def check_insecure_headers(self, url):
"""
Check for insecure headers in the response from the URL.
@param url: The URL to check headers for.
"""
# Send a GET request to the URL
response = requests.head(url)
headers = response.headers
# List to store insecure headers found
insecure_headers = []
# Check for missing or insecurely configured security headers
if "X-Content-Type-Options" not in headers:
insecure_headers.append("X-Content-Type-Options header missing")
if "X-Frame-Options" not in headers:
insecure_headers.append("X-Frame-Options header missing")
if "X-XSS-Protection" not in headers:
insecure_headers.append("X-XSS-Protection header missing")
# If any insecure headers are found, report them
if insecure_headers:
print(f"Insecure headers found at {url}:")
for header in insecure_headers:
print(f" - {header}")
@staticmethod
def extract_forms(url):
"""
Extract all forms from a given URL using the Crawler class.
@param url: The URL to extract forms from.
@returns: List of forms found on the page.
"""
from crawler import Crawler
crawler = Crawler(url)
return crawler.extract_forms(url)
@staticmethod
def get_form_data(form, value):
"""
Prepare form data with the provided value for each input field.
@param form: The form to prepare data for.
@param value: The value to insert into text or search input fields.
@returns: Dictionary of form data.
"""
form_data = {}
# Iterate over each input field in the form
for input_field in form.find_all("input"):
input_name = input_field.get("name")
input_type = input_field.get("type")
input_value = input_field.get("value")
# Use the provided value for text and search inputs
if input_type == "text" or input_type == "search":
form_data[input_name] = value
else:
form_data[input_name] = input_value
return form_data
@staticmethod
def submit_form(form, form_data, url):
"""
Submit a form with the given form data.
@param form: The form to submit.
@param form_data: The data to submit with the form.
@param url: The URL where the form is located.
@returns: The response from submitting the form.
"""
action = form.get("action")
method = form.get("method").lower()
form_url = urljoin(url, action)
# Submit the form using the appropriate HTTP method
if method == "post":
response = requests.post(form_url, data=form_data)
else:
response = requests.get(form_url, params=form_data)
return response