mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-02-25 13:25:20 +00:00
153 lines
5.1 KiB
Python
153 lines
5.1 KiB
Python
"""
|
|
NeuroSploit v3 - Infrastructure Vulnerability Testers
|
|
|
|
Testers for Security Headers, SSL/TLS, HTTP Methods
|
|
"""
|
|
import re
|
|
from typing import Tuple, Dict, Optional
|
|
from backend.core.vuln_engine.testers.base_tester import BaseTester
|
|
|
|
|
|
class SecurityHeadersTester(BaseTester):
|
|
"""Tester for Missing Security Headers"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.name = "security_headers"
|
|
self.required_headers = {
|
|
"Strict-Transport-Security": "HSTS not configured",
|
|
"X-Content-Type-Options": "X-Content-Type-Options not set",
|
|
"X-Frame-Options": "X-Frame-Options not set",
|
|
"Content-Security-Policy": "CSP not configured",
|
|
"X-XSS-Protection": "X-XSS-Protection not set (legacy but still useful)",
|
|
"Referrer-Policy": "Referrer-Policy not configured"
|
|
}
|
|
|
|
def analyze_response(
|
|
self,
|
|
payload: str,
|
|
response_status: int,
|
|
response_headers: Dict,
|
|
response_body: str,
|
|
context: Dict
|
|
) -> Tuple[bool, float, Optional[str]]:
|
|
"""Check for missing security headers"""
|
|
missing = []
|
|
headers_lower = {k.lower(): v for k, v in response_headers.items()}
|
|
|
|
for header, message in self.required_headers.items():
|
|
if header.lower() not in headers_lower:
|
|
missing.append(message)
|
|
|
|
# Check for weak CSP
|
|
csp = headers_lower.get("content-security-policy", "")
|
|
if csp:
|
|
weak_csp = []
|
|
if "unsafe-inline" in csp:
|
|
weak_csp.append("unsafe-inline")
|
|
if "unsafe-eval" in csp:
|
|
weak_csp.append("unsafe-eval")
|
|
if "*" in csp:
|
|
weak_csp.append("wildcard sources")
|
|
if weak_csp:
|
|
missing.append(f"Weak CSP: {', '.join(weak_csp)}")
|
|
|
|
if missing:
|
|
confidence = min(0.3 + len(missing) * 0.1, 0.8)
|
|
return True, confidence, f"Missing/weak headers: {'; '.join(missing[:3])}"
|
|
|
|
return False, 0.0, None
|
|
|
|
|
|
class SSLTester(BaseTester):
|
|
"""Tester for SSL/TLS Issues"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.name = "ssl_issues"
|
|
|
|
def analyze_response(
|
|
self,
|
|
payload: str,
|
|
response_status: int,
|
|
response_headers: Dict,
|
|
response_body: str,
|
|
context: Dict
|
|
) -> Tuple[bool, float, Optional[str]]:
|
|
"""Check for SSL/TLS issues"""
|
|
issues = []
|
|
|
|
# Check HSTS
|
|
hsts = response_headers.get("Strict-Transport-Security", "")
|
|
if not hsts:
|
|
issues.append("HSTS not enabled")
|
|
else:
|
|
# Check HSTS max-age
|
|
max_age_match = re.search(r'max-age=(\d+)', hsts)
|
|
if max_age_match:
|
|
max_age = int(max_age_match.group(1))
|
|
if max_age < 31536000: # Less than 1 year
|
|
issues.append(f"HSTS max-age too short: {max_age}s")
|
|
|
|
if "includeSubDomains" not in hsts:
|
|
issues.append("HSTS missing includeSubDomains")
|
|
|
|
# Check for HTTP resources on HTTPS page
|
|
if "https://" in (context.get("url", "") or ""):
|
|
http_resources = re.findall(r'(?:src|href)=["\']http://[^"\']+', response_body)
|
|
if http_resources:
|
|
issues.append(f"Mixed content: {len(http_resources)} HTTP resources")
|
|
|
|
if issues:
|
|
return True, 0.6, f"SSL/TLS issues: {'; '.join(issues)}"
|
|
|
|
return False, 0.0, None
|
|
|
|
|
|
class HTTPMethodsTester(BaseTester):
|
|
"""Tester for Dangerous HTTP Methods"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.name = "http_methods"
|
|
self.dangerous_methods = ["TRACE", "TRACK", "PUT", "DELETE", "CONNECT"]
|
|
|
|
def build_request(self, endpoint, payload: str) -> Tuple[str, Dict, Dict, Optional[str]]:
|
|
"""Build OPTIONS request to check allowed methods"""
|
|
headers = {
|
|
"User-Agent": "NeuroSploit/3.0"
|
|
}
|
|
# payload is the HTTP method to test
|
|
return endpoint.url, {}, headers, None
|
|
|
|
def analyze_response(
|
|
self,
|
|
payload: str,
|
|
response_status: int,
|
|
response_headers: Dict,
|
|
response_body: str,
|
|
context: Dict
|
|
) -> Tuple[bool, float, Optional[str]]:
|
|
"""Check for dangerous HTTP methods"""
|
|
# Check Allow header from OPTIONS response
|
|
allow = response_headers.get("Allow", "")
|
|
dangerous_found = []
|
|
|
|
for method in self.dangerous_methods:
|
|
if method in allow.upper():
|
|
dangerous_found.append(method)
|
|
|
|
# TRACE method enables XST attacks
|
|
if "TRACE" in dangerous_found or "TRACK" in dangerous_found:
|
|
return True, 0.7, f"Dangerous methods enabled: {', '.join(dangerous_found)} (XST risk)"
|
|
|
|
if dangerous_found:
|
|
return True, 0.5, f"Potentially dangerous methods: {', '.join(dangerous_found)}"
|
|
|
|
# Check if specific method test succeeded
|
|
if payload.upper() in self.dangerous_methods:
|
|
if response_status == 200:
|
|
return True, 0.6, f"{payload} method accepted"
|
|
|
|
return False, 0.0, None
|