ziffir commited on
Commit
6cd2daf
·
verified ·
1 Parent(s): 17575c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +381 -1592
app.py CHANGED
@@ -1,15 +1,27 @@
1
-
2
- #═══════════════════════════════════════════════════════════════════════════════
3
- # PRIVATE RED TEAM WEB RECONNAISSANCE FRAMEWORK v3.0 - PART 1
4
- #─────────────────────────────────────────────────────────────────────────
5
- # Bölümler: 1-7 (Konfigürasyonu, Data Models, Stealth, OSINT, Active Recon,
6
- #Threat Modeling, Attack Graph)
7
- #═══════════════════════════════════════════════════════════════════════════════
 
 
 
 
 
 
 
 
 
 
 
8
 
9
  import gradio as gr
10
  import asyncio
11
  import json
12
  import aiohttp
 
13
  from typing import Dict, List, Tuple, Set, Optional
14
  from dataclasses import dataclass, asdict
15
  from datetime import datetime
@@ -20,1775 +32,552 @@ import random
20
  import time
21
  import hashlib
22
  from enum import Enum
23
- import requests
24
  from bs4 import BeautifulSoup
25
  import networkx as nx
26
  import plotly.graph_objects as go
27
- import plotly.express as px
28
- from io import BytesIO
29
- import base64
30
  import ssl
31
  import socket
32
- import subprocess
33
- from urllib.parse import urljoin, urlparse
 
 
 
 
 
 
34
 
35
  # ════════════════════════════════════════════════════════════════════════════
36
- # SECTION 1: CONFIGURATION & CONSTANTS
37
  # ════════════════════════════════════════════════════════════════════════════
38
 
39
  class ThreatLevel(Enum):
40
- """Threat/Risk Assessment Levels"""
41
  LOW = 0
42
  MEDIUM = 1
43
  HIGH = 2
44
  CRITICAL = 3
45
 
46
  class CVESSeverity(Enum):
47
- """CVSS Severity Ratings"""
48
  CRITICAL = (9.0, 10.0)
49
  HIGH = (7.0, 8.9)
50
  MEDIUM = (4.0, 6.9)
51
  LOW = (0.1, 3.9)
52
 
53
- # STRIDE Threat Model
54
- STRIDE_THREATS = {
55
- "Spoofing": {
56
- "description": "Identity spoofing",
57
- "techniques": ["T1027", "T1556"],
58
- "mitigations": ["MFA", "SAML", "OAuth"]
59
- },
60
- "Tampering": {
61
- "description": "Data/Code manipulation",
62
- "techniques": ["T1565", "T1491"],
63
- "mitigations": ["Input validation", "WAF", "HTTPS"]
64
- },
65
- "Repudiation": {
66
- "description": "Action denial",
67
- "techniques": ["T1562"],
68
- "mitigations": ["Logging", "Audit trails"]
69
- },
70
- "InformationDisclosure": {
71
- "description": "Data leakage",
72
- "techniques": ["T1041", "T1048"],
73
- "mitigations": ["Encryption", "DLP"]
74
- },
75
- "DenialOfService": {
76
- "description": "Service unavailability",
77
- "techniques": ["T1561"],
78
- "mitigations": ["Rate limiting", "DDoS protection"]
79
- },
80
- "ElevationOfPrivilege": {
81
- "description": "Privilege escalation",
82
- "techniques": ["T1134", "T1548"],
83
- "mitigations": ["RBAC", "Least privilege"]
84
- }
85
  }
86
- # Extended MITRE ATT&CK Matrix
87
- MITRE_TECHNIQUES = {
88
- "Reconnaissance": {
89
- "T1592": "Gather Victim Host Information",
90
- "T1593": "Search Open Websites/Domains",
91
- "T1594": "Search Victim-Owned Websites",
92
- "T1595": "Active Scanning",
93
- "T1596": "Search Open Technical Databases",
94
- "T1597": "Search Closed Sources",
95
- "T1598": "Phishing for Information"
96
- },
97
- "Initial Access": {
98
- "T1190": "Exploit Public-Facing Application",
99
- "T1199": "Trusted Relationship",
100
- "T1566": "Phishing"
101
- },
102
- "Execution": {
103
- "T1059": "Command and Scripting Interpreter",
104
- "T1203": "Exploitation for Client Execution"
105
- },
106
- "Persistence": {
107
- "T1078": "Valid Accounts",
108
- "T1547": "Boot or Logon Autostart Execution"
109
- },
110
- "Privilege Escalation": {
111
- "T1134": "Access Token Manipulation",
112
- "T1548": "Abuse Elevation Control Mechanism"
113
- },
114
- "Defense Evasion": {
115
- "T1562": "Impair Defenses",
116
- "T1036": "Masquerading"
117
- },
118
- "Credential Access": {
119
- "T1110": "Brute Force",
120
- "T1187": "Forced Authentication"
121
- },
122
- "Discovery": {
123
- "T1526": "Enumerate External Remote Systems",
124
- "T1087": "Account Discovery"
125
- },
126
- "Lateral Movement": {
127
- "T1021": "Remote Services",
128
- "T1570": "Lateral Tool Transfer"
129
- },
130
- "Collection": {
131
- "T1113": "Screen Capture",
132
- "T1115": "Clipboard Data"
133
- },
134
- "Command and Control": {
135
- "T1071": "Application Layer Protocol",
136
- "T1572": "Protocol Tunneling"
137
- },
138
- "Exfiltration": {
139
- "T1041": "Exfiltration Over C2 Channel",
140
- "T1048": "Exfiltration Over Alternative Protocol"
141
- },
142
- "Impact": {
143
- "T1531": "Account Access Removal",
144
- "T1561": "Disk Wipe"
145
- }
146
  }
147
- # Technology fingerprints - Extended
148
  TECH_FINGERPRINTS = {
149
  "Web Servers": {
150
- "Apache": [r"Server: Apache", r"X-Powered-By: Apache"],
151
- "Nginx": [r"Server: nginx", r"X-Nginx"],
152
  "IIS": [r"Server: Microsoft-IIS"],
153
- "Cloudflare": [r"CF-RAY", r"Cloudflare"],
154
- "AWS": [r"X-Amz", r"AmazonS3"],
155
- "Azure": [r"Azure", r"Microsoft-IIS"]
156
  },
157
  "CMS": {
158
- "WordPress": [r"/wp-admin", r"wp-content", r"wp_.*"],
159
- "Drupal": [r"/sites/default", r"drupal\\.css"],
160
- "Joomla": [r"/administrator", r"com_content"],
161
- "Magento": [r"/skin/frontend", r"Mage.Cookies"],
162
- "Shopify": [r"cdn.shopify.com", r"Shopify.theme"]
163
  },
164
  "Frameworks": {
165
  "Django": [r"CSRF", r"django_session"],
166
- "Flask": [r"werkzeug", r"Flask"],
167
- "Laravel": [r"XSRF-TOKEN", r"laravel_session"],
168
- "Spring": [r"JSESSIONID", r"spring"],
169
- "Ruby on Rails": [r"_rails", r"authenticity_token"],
170
- "ASP.NET": [r"ASP.NET_SessionId", r"__VIEWSTATE"]
171
- },
172
- "JavaScript": {
173
- "React": [r"__REACT", r"react\\.js"],
174
- "Vue": [r"__VUE", r"vue\\.js"],
175
- "Angular": [r"ng-app", r"angular\\.js"],
176
- "jQuery": [r"jquery", r"jQuery"],
177
- "Bootstrap": [r"bootstrap", r"data-toggle"]
178
  },
179
- "Databases": {
180
- "MySQL": [r"MySQL", r"sqlstate"],
181
- "PostgreSQL": [r"PostgreSQL", r"pg_query"],
182
- "MongoDB": [r"MongoDB", r"mongod"],
183
- "Redis": [r"Redis", r"redis-cli"]
184
- }
185
  }
186
 
187
- # Security Headers to check
188
  SECURITY_HEADERS = {
189
  "Strict-Transport-Security": "HSTS",
190
  "Content-Security-Policy": "CSP",
191
  "X-Frame-Options": "Clickjacking Protection",
192
- "X-Content-Type-Options": "MIME Sniffing Protection",
193
- "X-XSS-Protection": "XSS Filter",
194
- "Referrer-Policy": "Referrer Control",
195
- "Permissions-Policy": "Feature Policy"
196
  }
197
 
198
- # Common endpoints for discovery
199
  COMMON_ENDPOINTS = [
200
- "", "admin", "api", "login", "test", "debug", "config",
201
- "api/users", "api/admin", "api/auth", "api/data", "api/v1",
202
- "wp-admin", "wp-login", "administrator", "phpmyadmin",
203
- "robots.txt", "sitemap.xml", ".env", ".git", ".htaccess",
204
- "backup", "db", "database", "dump", "sql", "old",
205
- "dev", "staging", "beta", "uat", "demo",
206
- "swagger", "api-docs", "graphql", "graphiql",
207
- "actuator", "health", "metrics", "prometheus"
208
  ]
209
 
210
  # ════════════════════════════════════════════════════════════════════════════
211
- # SECTION 2: DATA MODELS
212
  # ════════════════════════════════════════════════════════════════════════════
213
 
214
- @dataclass
215
- class IntelligenceIndicator:
216
- """IOC - Indicator of Compromise"""
217
- type: str
218
- value: str
219
- confidence: float
220
- source: str
221
- timestamp: str
222
- metadata: Optional[Dict] = None
223
-
224
  @dataclass
225
  class ThreatVector:
226
- """Attack surface element"""
227
- category: str
228
- location: str
229
- risk_score: float
230
- techniques: List[str]
231
- description: str
232
- cvss_score: Optional[float] = None
233
- cwe_id: Optional[str] = None
234
- evidence: Optional[str] = None
235
 
236
  @dataclass
237
  class AttackPath:
238
- """End-to-end attack chain"""
239
- entry_point: str
240
- intermediate_steps: List[str]
241
- objective: str
242
- risk_level: str
243
- complexity: float
244
- mitre_techniques: List[str] = None
245
-
246
- def __post_init__(self):
247
- if self.mitre_techniques is None:
248
- self.mitre_techniques = []
249
 
250
  @dataclass
251
  class Vulnerability:
252
- """Vulnerability finding"""
253
  name: str
 
254
  description: str
255
  severity: str
256
  cvss_score: float
257
- cvss_vector: str
258
- location: str
259
- evidence: str
260
  remediation: str
261
- cwe_id: Optional[str] = None
262
- owasp_category: Optional[str] = None
263
- mitre_techniques: List[str] = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- def __post_init__(self):
266
- if self.mitre_techniques is None:
267
- self.mitre_techniques = []
 
 
 
 
 
 
 
 
 
268
 
269
  # ════════════════════════════════════════════════════════════════════════════
270
- # SECTION 3: STEALTH & OPSEC ENGINE
271
  # ════════════════════════════════════════════════════════════════════════════
272
 
273
  class StealthConfig:
274
- """Anti-detection & evasion configuration"""
275
-
276
- def __init__(self, threat_level: ThreatLevel = ThreatLevel.MEDIUM):
277
  self.threat_level = threat_level
278
-
279
- self.delay_ranges = {
280
- ThreatLevel.LOW: (100, 300),
281
- ThreatLevel.MEDIUM: (500, 2000),
282
- ThreatLevel.HIGH: (2000, 5000),
283
- ThreatLevel.CRITICAL: (5000, 15000)
284
- }
285
-
286
- self.max_concurrent = {
287
- ThreatLevel.LOW: 1,
288
- ThreatLevel.MEDIUM: 2,
289
- ThreatLevel.HIGH: 5,
290
- ThreatLevel.CRITICAL: 10
291
- }
292
 
293
  self.user_agents = [
294
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
295
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
296
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
297
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
298
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
299
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/120.0.0.0"
300
  ]
301
-
302
- self.proxies = []
303
- self.current_proxy = 0
304
-
305
- def get_delay(self) -> float:
306
- """Random delay to avoid pattern detection"""
307
- min_d, max_d = self.delay_ranges[self.threat_level]
308
- return random.uniform(min_d, max_d) / 1000
309
-
310
- def get_headers(self) -> Dict[str, str]:
311
- """Anti-fingerprinting headers"""
312
- headers = {
313
- "User-Agent": random.choice(self.user_agents),
314
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
315
- "Accept-Encoding": random.choice(["gzip, deflate", "gzip, deflate, br"]),
316
- "Accept-Language": random.choice(["en-US,en;q=0.9", "en-US,en;q=0.9,pt;q=0.8", "en-GB,en;q=0.9"]),
317
- "Cache-Control": "no-cache",
318
- "DNT": "1",
319
- "Connection": "keep-alive",
320
- "Upgrade-Insecure-Requests": "1",
321
- "Sec-Fetch-Dest": "document",
322
- "Sec-Fetch-Mode": "navigate",
323
- "Sec-Fetch-Site": "none",
324
- "Sec-Fetch-User": "?1"
325
- }
326
- return headers
327
-
328
- def get_proxy(self) -> Optional[Dict]:
329
- """Rotate proxies if available"""
330
- if not self.proxies:
331
- return None
332
- proxy = self.proxies[self.current_proxy % len(self.proxies)]
333
- self.current_proxy += 1
334
- return proxy
335
 
336
  # ════════════════════════════════════════════════════════════════════════════
337
- # SECTION 4: PASSIVE OSINT ENGINE
338
  # ════════════════════════════════════════════════════════════════════════════
 
339
  class PassiveOSINTEngine:
340
- """Passive reconnaissance without alerting target"""
341
-
342
- def __init__(self, config: StealthConfig):
343
- self.config = config
344
- self.indicators: Dict[str, List[IntelligenceIndicator]] = defaultdict(list)
345
- self.logger = self._setup_logging()
346
 
347
- def _setup_logging(self):
348
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
349
- return logging.getLogger("PassiveOSINT")
350
-
351
- async def gather_dns_intel(self, domain: str) -> Dict:
352
- """DNS records, subdomains from public sources"""
353
- intel = {
354
- "subdomains": [],
355
- "mx_records": [],
356
- "ns_records": [],
357
- "txt_records": [],
358
- "a_records": [],
359
- "aaaa_records": [],
360
- "cname_records": []
361
- }
362
 
363
  try:
364
- import dns.resolver
365
-
366
- # Try common subdomains
367
- common_subs = [
368
- "www", "mail", "ftp", "admin", "api", "dev", "staging",
369
- "cdn", "test", "blog", "shop", "support", "docs", "app",
370
- "portal", "secure", "vpn", "remote", "webmail", "mx",
371
- "ns1", "ns2", "dns", "autodiscover", "autoconfig"
372
- ]
373
 
374
- for sub in common_subs:
 
 
375
  try:
376
- full_domain = f"{sub}.{domain}"
377
- result = dns.resolver.resolve(full_domain, 'A')
378
- for rdata in result:
379
- intel["subdomains"].append({
380
- "subdomain": full_domain,
381
- "ip": str(rdata),
382
- "type": "A"
383
- })
384
  except:
385
  pass
386
-
387
- # Try AAAA records
388
- try:
389
- full_domain = f"{sub}.{domain}"
390
- result = dns.resolver.resolve(full_domain, 'AAAA')
391
- for rdata in result:
392
- intel["aaaa_records"].append({
393
- "subdomain": full_domain,
394
- "ipv6": str(rdata)
395
- })
396
- except:
397
- pass
398
-
399
- # MX records
400
- try:
401
- mx = dns.resolver.resolve(domain, 'MX')
402
- intel["mx_records"] = [{"preference": r.preference, "exchange": str(r.exchange)} for r in mx]
403
- except:
404
- pass
405
-
406
- # NS records
407
- try:
408
- ns = dns.resolver.resolve(domain, 'NS')
409
- intel["ns_records"] = [str(r) for r in ns]
410
- except:
411
- pass
412
-
413
- # TXT records (SPF, DKIM, DMARC)
414
- try:
415
- txt = dns.resolver.resolve(domain, 'TXT')
416
- intel["txt_records"] = [str(r) for r in txt]
417
- except:
418
- pass
419
-
420
- except ImportError:
421
- self.logger.warning("dnspython not installed")
422
-
423
- return intel
424
-
425
- async def gather_ssl_cert_intel(self, domain: str) -> Dict:
426
- """SSL certificate analysis for subdomains"""
427
- cert_intel = {
428
- "subject": None,
429
- "issuer": None,
430
- "valid_from": None,
431
- "valid_to": None,
432
- "subjectAltNames": [],
433
- "serial_number": None,
434
- "signature_algorithm": None,
435
- "version": None,
436
- "expired": False,
437
- "valid": False
438
- }
439
-
440
- try:
441
- context = ssl.create_default_context()
442
- with socket.create_connection((domain, 443), timeout=5) as sock:
443
- with context.wrap_socket(sock, server_hostname=domain) as ssock:
444
- cert = ssock.getpeercert()
445
- cipher = ssock.cipher()
446
- version = ssock.version()
447
-
448
- cert_intel["subject"] = dict(x[0] for x in cert['subject'])
449
- cert_intel["issuer"] = dict(x[0] for x in cert['issuer'])
450
- cert_intel["valid_from"] = cert['notBefore']
451
- cert_intel["valid_to"] = cert['notAfter']
452
- cert_intel["serial_number"] = cert.get('serialNumber')
453
- cert_intel["signature_algorithm"] = cert.get('signatureAlgorithm')
454
- cert_intel["version"] = version
455
- cert_intel["cipher"] = cipher
456
-
457
- # Check expiration
458
- from datetime import datetime
459
- expiry = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
460
- cert_intel["expired"] = expiry < datetime.now()
461
- cert_intel["valid"] = True
462
-
463
- # Extract SANs
464
- for alt_name in cert.get('subjectAltName', []):
465
- if alt_name[0] == 'DNS':
466
- cert_intel["subjectAltNames"].append(alt_name[1])
467
- except Exception as e:
468
- self.logger.error(f"SSL cert grab failed: {e}")
469
-
470
- return cert_intel
471
-
472
- async def crt_sh_lookup(self, domain: str) -> List[str]:
473
- """Query Certificate Transparency logs via crt.sh"""
474
- subdomains = set()
475
- try:
476
- url = f"https://crt.sh/?q=%.{domain}&output=json"
477
- headers = self.config.get_headers()
478
-
479
- async with aiohttp.ClientSession() as session:
480
- async with session.get(url, headers=headers, timeout=10) as resp:
481
- if resp.status == 200:
482
- data = await resp.json()
483
- for entry in data:
484
- name = entry.get('name_value', '')
485
- if name and '*' not in name:
486
- subdomains.add(name)
487
- except Exception as e:
488
- self.logger.error(f"crt.sh lookup failed: {e}")
489
-
490
- return list(subdomains)
491
-
492
- async def github_reconnaissance(self, org_name: str) -> Dict:
493
- """Search GitHub for organization info"""
494
- github_intel = {
495
- "repositories": [],
496
- "leaked_patterns": [],
497
- "technology_hints": [],
498
- "members": [],
499
- "gists": []
500
- }
501
-
502
- try:
503
- # Search repos
504
- endpoint = f"https://api.github.com/users/{org_name}/repos"
505
- headers = self.config.get_headers()
506
-
507
- async with aiohttp.ClientSession() as session:
508
- async with session.get(endpoint, headers=headers, timeout=10) as resp:
509
- if resp.status == 200:
510
- repos = await resp.json()
511
- for repo in repos[:20]: # Limit to 20
512
- github_intel["repositories"].append({
513
- "name": repo.get("name"),
514
- "url": repo.get("html_url"),
515
- "description": repo.get("description"),
516
- "language": repo.get("language"),
517
- "stars": repo.get("stargazers_count"),
518
- "forks": repo.get("forks_count"),
519
- "updated": repo.get("updated_at")
520
- })
521
-
522
- if repo.get("language"):
523
- github_intel["technology_hints"].append(repo.get("language"))
524
-
525
- # Check for common leaked patterns in repo names/descriptions
526
- desc = (repo.get("description") or "").lower()
527
- if any(x in desc for x in ['password', 'secret', 'key', 'token', 'credential']):
528
- github_intel["leaked_patterns"].append({
529
- "repo": repo.get("name"),
530
- "pattern": "Potential secret in description"
531
- })
532
-
533
- # Search for gists
534
- gist_endpoint = f"https://api.github.com/users/{org_name}/gists"
535
- async with aiohttp.ClientSession() as session:
536
- async with session.get(gist_endpoint, headers=headers, timeout=10) as resp:
537
- if resp.status == 200:
538
- gists = await resp.json()
539
- for gist in gists[:10]:
540
- github_intel["gists"].append({
541
- "id": gist.get("id"),
542
- "description": gist.get("description"),
543
- "url": gist.get("html_url")
544
- })
545
- except Exception as e:
546
- self.logger.error(f"GitHub recon failed: {e}")
547
-
548
- return github_intel
549
-
550
- async def wayback_machine_lookup(self, domain: str) -> List[str]:
551
- """Query Wayback Machine for historical URLs"""
552
- urls = []
553
- try:
554
- endpoint = f"http://web.archive.org/cdx/search/cdx?url=*.{domain}/*&output=json&fl=original&collapse=urlkey"
555
- headers = self.config.get_headers()
556
-
557
- async with aiohttp.ClientSession() as session:
558
- async with session.get(endpoint, headers=headers, timeout=15) as resp:
559
- if resp.status == 200:
560
- data = await resp.json()
561
- if len(data) > 1: # First row is headers
562
- urls = [row[0] for row in data[1:]]
563
- except Exception as e:
564
- self.logger.error(f"Wayback lookup failed: {e}")
565
-
566
- return urls[:100] # Limit to 100
567
-
568
- async def exposed_data_check(self, domain: str) -> List[Dict]:
569
- """Check if domain in breach databases"""
570
- breaches = []
571
-
572
- try:
573
- # HIBP API (requires key in production, placeholder here)
574
- # endpoint = f"https://haveibeenpwned.com/api/v3/breaches?domain={domain}"
575
- # headers = {"User-Agent": "RedTeamFramework/3.0", "hibp-api-key": "YOUR_API_KEY"}
576
- # resp = requests.get(endpoint, headers=headers, timeout=5)
577
- # if resp.status_code == 200:
578
- # breaches = resp.json()
579
- pass
580
- except:
581
- pass
582
-
583
- return breaches
584
-
585
- async def shodan_lookup(self, domain: str) -> Dict:
586
- """Shodan host lookup (requires API key)"""
587
- shodan_data = {
588
- "ip": None,
589
- "ports": [],
590
- "services": [],
591
- "vulnerabilities": [],
592
- "hostnames": [],
593
- "location": {}
594
- }
595
-
596
- try:
597
- # Placeholder - requires Shodan API key
598
- # import shodan
599
- # api = shodan.Shodan("YOUR_API_KEY")
600
- # host = api.host(domain)
601
- # shodan_data = {
602
- # "ip": host['ip_str'],
603
- # "ports": host['ports'],
604
- # "services": [match['product'] for match in host['data']],
605
- # "vulnerabilities": host.get('vulns', []),
606
- # "hostnames": host.get('hostnames', []),
607
- # "location": host.get('location', {})
608
- # }
609
- pass
610
  except:
611
  pass
612
 
613
- return shodan_data
614
-
615
- # ════════════════════════════════════════════════════════════════════════════
616
- # SECTION 5: ACTIVE RECONNAISSANCE ENGINE
617
- # ════════════════════════════════════════════════════════════════════════════
618
 
619
  class ActiveReconEngine:
620
- """Active scanning with OPSEC measures"""
621
-
622
- def __init__(self, config: StealthConfig):
623
- self.config = config
624
- self.findings = []
625
- self.logger = logging.getLogger("ActiveRecon")
626
 
627
- async def fingerprint_technologies(self, url: str) -> Dict:
628
- """Identify technologies from headers, HTML, JS"""
629
- technologies = {
630
- "web_server": None,
631
- "cms": [],
632
- "frameworks": [],
633
- "javascript": [],
634
- "databases": [],
635
- "analytics": [],
636
- "cdn": [],
637
- "security_headers": {},
638
- "missing_headers": []
639
- }
640
 
641
  try:
642
- headers = self.config.get_headers()
643
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False, allow_redirects=True)
644
-
645
- # Server header analysis
646
- if "Server" in resp.headers:
647
- server = resp.headers["Server"]
648
- technologies["web_server"] = server
649
-
650
- # X-Powered-By
651
- if "X-Powered-By" in resp.headers:
652
- technologies["frameworks"].append(resp.headers["X-Powered-By"])
653
-
654
- # X-Generator (CMS)
655
- if "X-Generator" in resp.headers:
656
- technologies["cms"].append(resp.headers["X-Generator"])
657
-
658
- # CDN detection
659
- if "CF-RAY" in resp.headers or "Cloudflare" in resp.headers.get("Server", ""):
660
- technologies["cdn"].append("Cloudflare")
661
- if "X-Cache" in resp.headers or "Fastly" in str(resp.headers):
662
- technologies["cdn"].append("Fastly")
663
-
664
- # Security headers analysis
665
- for header, description in SECURITY_HEADERS.items():
666
- if header in resp.headers:
667
- technologies["security_headers"][header] = resp.headers[header]
668
- else:
669
- technologies["missing_headers"].append(header)
670
-
671
- content = resp.text
672
-
673
- # CMS/Framework detection
674
- patterns = {
675
- "WordPress": r"wp-content|wp-includes|/wp-admin|wordpress",
676
- "Drupal": r"sites/default/files|drupal\\.css|drupal.js",
677
- "Joomla": r"Joomla|com_content|/media/jui",
678
- "Magento": r"skin/frontend|Mage.Cookies|magento",
679
- "Django": r"Django|csrfmiddlewaretoken|django",
680
- "Flask": r"Flask|werkzeug",
681
- "Laravel": r"XSRF-TOKEN|laravel_session|csrf-token",
682
- "React": r"__REACT_DEVTOOLS__|react\\.js|reactjs",
683
- "Vue": r"__VUE__|vue\\.js|vuejs",
684
- "Angular": r"ng-app|angular\\.js|angularjs",
685
- "jQuery": r"jquery|jQuery",
686
- "Bootstrap": r"bootstrap|data-toggle",
687
- "Google Analytics": r"google-analytics|gtag|_ga",
688
- "Mixpanel": r"mixpanel",
689
- "Hotjar": r"hotjar|hjSiteSettings"
690
- }
691
-
692
- for tech, pattern in patterns.items():
693
- if re.search(pattern, content, re.IGNORECASE):
694
- if tech in ["WordPress", "Drupal", "Joomla", "Magento"]:
695
- if tech not in technologies["cms"]:
696
- technologies["cms"].append(tech)
697
- elif tech in ["Django", "Flask", "Laravel"]:
698
- if tech not in technologies["frameworks"]:
699
- technologies["frameworks"].append(tech)
700
- elif tech in ["React", "Vue", "Angular", "jQuery", "Bootstrap"]:
701
- if tech not in technologies["javascript"]:
702
- technologies["javascript"].append(tech)
703
- elif tech in ["Google Analytics", "Mixpanel", "Hotjar"]:
704
- if tech not in technologies["analytics"]:
705
- technologies["analytics"].append(tech)
706
-
707
- # Check for cookies
708
- if "Set-Cookie" in resp.headers:
709
- cookies = resp.headers["Set-Cookie"]
710
- if "PHPSESSID" in cookies:
711
- technologies["frameworks"].append("PHP")
712
- if "session" in cookies.lower():
713
- technologies["frameworks"].append("Session-based Auth")
714
 
715
- except Exception as e:
716
- self.logger.error(f"Fingerprinting failed: {e}")
 
 
 
 
 
 
 
 
 
 
 
717
 
718
- return technologies
719
 
720
- async def discover_endpoints(self, url: str, wordlist: List[str] = None) -> List[Dict]:
721
- """Endpoint discovery with smart filtering"""
722
- discovered = []
723
- wordlist = wordlist or COMMON_ENDPOINTS
724
 
725
- for path in wordlist[:50]: # Limit wordlist
726
  try:
727
- full_url = f"https://{url.rstrip('/')}/{path.lstrip('/')}"
728
- headers = self.config.get_headers()
729
-
730
- await asyncio.sleep(self.config.get_delay())
731
-
732
- resp = requests.get(full_url, headers=headers, timeout=5, verify=False, allow_redirects=False)
733
-
734
- if resp.status_code in [200, 301, 302, 401, 403, 405]:
735
- discovered.append({
736
- "path": path,
737
- "url": full_url,
738
  "status": resp.status_code,
739
- "size": len(resp.text),
740
- "title": self._extract_title(resp.text),
741
- "server": resp.headers.get("Server", "Unknown")
742
  })
743
  except:
744
  pass
745
 
746
- return discovered
747
 
748
- def _extract_title(self, html: str) -> str:
749
- """Extract page title from HTML"""
750
- try:
751
- soup = BeautifulSoup(html, 'html.parser')
752
- title = soup.find('title')
753
- return title.text.strip() if title else "No Title"
754
- except:
755
- return "Error"
756
-
757
- async def analyze_forms(self, url: str) -> List[Dict]:
758
- """Form detection and analysis"""
759
  forms = []
760
 
761
  try:
762
- headers = self.config.get_headers()
763
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False)
 
 
 
 
764
  soup = BeautifulSoup(resp.text, 'html.parser')
765
 
766
  for form in soup.find_all('form'):
767
  form_data = {
768
  "action": form.get('action', ''),
769
  "method": form.get('method', 'GET').upper(),
770
- "enctype": form.get('enctype', ''),
771
- "id": form.get('id', ''),
772
- "class": form.get('class', []),
773
- "fields": [],
774
- "vulnerabilities": []
775
  }
776
 
777
- for field in form.find_all(['input', 'textarea', 'select']):
778
- field_info = {
779
  "name": field.get('name', ''),
780
- "type": field.get('type', 'text'),
781
- "id": field.get('id', ''),
782
- "required": field.get('required') is not None,
783
- "placeholder": field.get('placeholder', '')
784
- }
785
- form_data["fields"].append(field_info)
786
-
787
- # Check for potential vulnerabilities
788
- if field.get('type') == 'password':
789
- form_data["vulnerabilities"].append("Password field detected - check for brute force protection")
790
- if field.get('type') == 'file':
791
- form_data["vulnerabilities"].append("File upload - check for upload restrictions")
792
-
793
- # Check for CSRF protection
794
- has_csrf = any('csrf' in str(f.get('name', '')).lower() or
795
- 'token' in str(f.get('name', '')).lower()
796
- for f in form_data["fields"])
797
- if not has_csrf and form_data["method"] == "POST":
798
- form_data["vulnerabilities"].append("No CSRF token detected")
799
 
800
  forms.append(form_data)
801
-
802
- except Exception as e:
803
- self.logger.error(f"Form analysis failed: {e}")
804
 
805
  return forms
806
 
807
- async def extract_javascript_endpoints(self, url: str) -> List[Dict]:
808
- """Extract API endpoints from JavaScript"""
809
- endpoints = []
810
 
811
  try:
812
- headers = self.config.get_headers()
813
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False)
814
-
815
- # Find all script tags
 
816
  soup = BeautifulSoup(resp.text, 'html.parser')
817
- scripts = []
818
-
819
- for script in soup.find_all('script'):
820
- if script.string:
821
- scripts.append(script.string)
822
- elif script.get('src'):
823
- # Fetch external scripts
824
- try:
825
- src = script['src']
826
- if src.startswith('http'):
827
- js_resp = requests.get(src, headers=headers, timeout=5)
828
- scripts.append(js_resp.text)
829
- elif src.startswith('/'):
830
- js_url = f"https://{url.rstrip('/')}{src}"
831
- js_resp = requests.get(js_url, headers=headers, timeout=5)
832
- scripts.append(js_resp.text)
833
- except:
834
- pass
835
-
836
- # Extract API patterns
837
- api_patterns = [
838
- r'["\']/(api|v[0-9]|rest|graphql)/[^"\'\\s]+["\']',
839
- r'(https?://[^"\'\\s]+/api/[^"\'\\s]+)',
840
- r'["\']/(admin|dashboard|internal)/[^"\'\\s]+["\']',
841
- r'fetch\\(["\']([^"\']+)["\']',
842
- r'axios\\.(get|post|put|delete)\\(["\']([^"\']+)["\']',
843
- r'\\$\\.ajax\\({\\s*url\\s*:\\s*["\']([^"\']+)["\']'
844
- ]
845
-
846
- for script_content in scripts:
847
- for pattern in api_patterns:
848
- matches = re.findall(pattern, script_content)
849
- for match in matches:
850
- if isinstance(match, tuple):
851
- match = match[-1] # Get the last group
852
- if match and match not in [e["endpoint"] for e in endpoints]:
853
- endpoints.append({
854
- "endpoint": match,
855
- "source": "inline_js" if script_content in [s.string for s in soup.find_all('script') if s.string] else "external_js",
856
- "type": "api"
857
- })
858
-
859
- # Look for hardcoded secrets
860
- secret_patterns = [
861
- (r'api[_-]?key["\']?\\s*[:=]\\s*["\']([a-zA-Z0-9_\\-]{16,})["\']', "API Key"),
862
- (r'secret[_-]?key["\']?\\s*[:=]\\s*["\']([a-zA-Z0-9_\\-]{16,})["\']', "Secret Key"),
863
- (r'password["\']?\\s*[:=]\\s*["\']([^"\']{8,})["\']', "Password"),
864
- (r'token["\']?\\s*[:=]\\s*["\']([a-zA-Z0-9_\\-\\.]{20,})["\']', "Token"),
865
- (r'aws_access_key_id["\']?\\s*[:=]\\s*["\'](AKIA[0-9A-Z]{16})["\']', "AWS Key"),
866
- (r'private[_-]?key["\']?\\s*[:=]\\s*["\'](-----BEGIN)', "Private Key")
867
- ]
868
 
869
- for script_content in scripts:
870
- for pattern, secret_type in secret_patterns:
871
- matches = re.findall(pattern, script_content, re.IGNORECASE)
872
- for match in matches:
873
- endpoints.append({
874
- "endpoint": f"[{secret_type} DETECTED - REDACTED]",
875
- "source": "js_analysis",
876
- "type": "secret",
877
- "secret_type": secret_type
878
- })
879
-
880
- except Exception as e:
881
- self.logger.error(f"JS extraction failed: {e}")
882
 
883
- return endpoints
884
 
885
- async def analyze_security_headers(self, url: str) -> Dict:
886
- """Analyze security headers"""
887
- headers_analysis = {
888
- "present": {},
889
- "missing": [],
890
- "recommendations": [],
891
- "score": 0
892
- }
893
 
894
  try:
895
- resp = requests.get(f"https://{url}", headers=self.config.get_headers(), timeout=10, verify=False)
896
-
897
- security_headers = {
898
- "Strict-Transport-Security": {"weight": 3, "recommendation": "Implement HSTS"},
899
- "Content-Security-Policy": {"weight": 3, "recommendation": "Implement CSP"},
900
- "X-Frame-Options": {"weight": 2, "recommendation": "Set X-Frame-Options to DENY or SAMEORIGIN"},
901
- "X-Content-Type-Options": {"weight": 2, "recommendation": "Set X-Content-Type-Options to nosniff"},
902
- "X-XSS-Protection": {"weight": 1, "recommendation": "Set X-XSS-Protection"},
903
- "Referrer-Policy": {"weight": 1, "recommendation": "Implement Referrer-Policy"},
904
- "Permissions-Policy": {"weight": 1, "recommendation": "Implement Permissions-Policy"}
905
- }
906
-
907
- total_weight = sum(h["weight"] for h in security_headers.values())
908
- current_score = 0
909
 
910
- for header, info in security_headers.items():
911
  if header in resp.headers:
912
- headers_analysis["present"][header] = resp.headers[header]
913
- current_score += info["weight"]
914
  else:
915
- headers_analysis["missing"].append(header)
916
- headers_analysis["recommendations"].append(info["recommendation"])
917
-
918
- headers_analysis["score"] = (current_score / total_weight) * 100
919
-
920
- except Exception as e:
921
- self.logger.error(f"Security headers analysis failed: {e}")
922
 
923
- return headers_analysis
924
 
925
- async def check_common_vulnerabilities(self, url: str) -> List[Vulnerability]:
926
- """Check for common vulnerability patterns"""
927
- vulnerabilities = []
928
 
929
  try:
930
- headers = self.config.get_headers()
931
-
932
- # Check for exposed .env
933
- try:
934
- env_resp = requests.get(f"https://{url}/.env", headers=headers, timeout=5, verify=False)
935
- if env_resp.status_code == 200 and "=" in env_resp.text:
936
- vuln = Vulnerability(
937
- name="Exposed Environment File",
938
- description="The .env file is publicly accessible, potentially exposing sensitive configuration",
939
- severity="CRITICAL",
940
- cvss_score=7.5,
941
- cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
942
- location=f"https://{url}/.env",
943
- evidence=".env file accessible without authentication",
944
- remediation="Restrict access to .env files via web server configuration",
945
- cwe_id="CWE-200",
946
- owasp_category="A01:2021 - Broken Access Control",
947
- mitre_techniques=["T1083"]
948
- )
949
- vulnerabilities.append(vuln)
950
- except:
951
- pass
952
-
953
- # Check for exposed .git
954
- try:
955
- git_resp = requests.get(f"https://{url}/.git/HEAD", headers=headers, timeout=5, verify=False)
956
- if git_resp.status_code == 200 and "ref:" in git_resp.text:
957
- vuln = Vulnerability(
958
- name="Exposed Git Repository",
959
- description="Git repository is publicly accessible, potentially exposing source code",
960
- severity="HIGH",
961
- cvss_score=7.5,
962
- cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
963
- location=f"https://{url}/.git/",
964
- evidence="Git HEAD file accessible",
965
- remediation="Restrict access to .git directory via web server configuration",
966
- cwe_id="CWE-200",
967
- owasp_category="A01:2021 - Broken Access Control",
968
- mitre_techniques=["T1083"]
969
- )
970
- vulnerabilities.append(vuln)
971
- except:
972
- pass
973
-
974
- # Check for directory listing
975
- try:
976
- dir_resp = requests.get(f"https://{url}/images/", headers=headers, timeout=5, verify=False)
977
- if dir_resp.status_code == 200 and "Index of" in dir_resp.text:
978
- vuln = Vulnerability(
979
- name="Directory Listing Enabled",
980
- description="Directory listing is enabled, exposing file structure",
981
- severity="MEDIUM",
982
- cvss_score=5.3,
983
- cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
984
- location=f"https://{url}/images/",
985
- evidence="Directory index page displayed",
986
- remediation="Disable directory listing in web server configuration",
987
- cwe_id="CWE-548",
988
- owasp_category="A01:2021 - Broken Access Control",
989
- mitre_techniques=["T1083"]
990
- )
991
- vulnerabilities.append(vuln)
992
- except:
993
- pass
994
-
995
- # Check for SQL injection in URL parameters
996
- test_url = f"https://{url}/?id=1'"
997
- try:
998
- sql_resp = requests.get(test_url, headers=headers, timeout=5, verify=False)
999
- sql_errors = [
1000
- "sql syntax", "mysql_fetch", "pg_query", "ORA-",
1001
- "Microsoft OLE DB", "ODBC SQL Server", "SQLite3::"
1002
- ]
1003
- if any(error.lower() in sql_resp.text.lower() for error in sql_errors):
1004
- vuln = Vulnerability(
1005
- name="SQL Injection",
1006
- description="Potential SQL injection vulnerability detected in URL parameters",
1007
- severity="CRITICAL",
1008
- cvss_score=9.8,
1009
- cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
1010
- location=test_url,
1011
- evidence="SQL error message in response",
1012
- remediation="Use parameterized queries and input validation",
1013
- cwe_id="CWE-89",
1014
- owasp_category="A03:2021 - Injection",
1015
- mitre_techniques=["T1190"]
1016
- )
1017
- vulnerabilities.append(vuln)
1018
- except:
1019
- pass
1020
-
1021
- # Check for XSS
1022
- test_xss_url = f"https://{url}/?q=<script>alert(1)</script>"
1023
- try:
1024
- xss_resp = requests.get(test_xss_url, headers=headers, timeout=5, verify=False)
1025
- if "<script>alert(1)</script>" in xss_resp.text:
1026
- vuln = Vulnerability(
1027
- name="Cross-Site Scripting (XSS)",
1028
- description="Reflected XSS vulnerability detected",
1029
- severity="HIGH",
1030
- cvss_score=6.1,
1031
- cvss_vector="CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N",
1032
- location=test_xss_url,
1033
- evidence="Script tag reflected in response without encoding",
1034
- remediation="Implement output encoding and CSP headers",
1035
- cwe_id="CWE-79",
1036
- owasp_category="A03:2021 - Injection",
1037
- mitre_techniques=["T1189"]
1038
- )
1039
- vulnerabilities.append(vuln)
1040
- except:
1041
- pass
1042
-
1043
- except Exception as e:
1044
- self.logger.error(f"Vulnerability check failed: {e}")
1045
 
1046
- return vulnerabilities
1047
 
1048
  # ════════════════════════════════════════════════════════════════════════════
1049
- # SECTION 6: THREAT MODELING ENGINE (STRIDE + MITRE ATT&CK)
1050
  # ════════════════════════════════════════════════════════════════════════════
1051
 
1052
  class ThreatModelingEngine:
1053
- """Advanced threat modeling"""
1054
-
1055
- def __init__(self):
1056
- self.threats: List[Dict] = []
1057
- self.attack_paths: List[AttackPath] = []
1058
-
1059
- def analyze_web_app(self, recon_data: Dict) -> List[ThreatVector]:
1060
- """Map reconnaissance to threats"""
1061
- threat_vectors = []
1062
-
1063
- # Forms = injection vectors
1064
- for form in recon_data.get("forms", []):
1065
- risk = 7.5
1066
- techniques = ["T1565.001", "T1598.003"]
1067
-
1068
- if "password" in str(form).lower():
1069
- risk = 8.5
1070
- techniques.append("T1110")
1071
-
1072
- threat_vectors.append(ThreatVector(
1073
- category="web_form",
1074
- location=form.get("action", ""),
1075
- risk_score=risk,
1076
- techniques=techniques,
1077
- description=f"Form {form.get('action')}: SQL Injection, XSS, CSRF potential",
1078
- cvss_score=risk,
1079
- cwe_id="CWE-89",
1080
- evidence=f"Form method: {form.get('method')}, Fields: {len(form.get('fields', []))}"
1081
  ))
1082
 
1083
- # JavaScript = gadget chains
1084
- for js_file in recon_data.get("js_files", []):
1085
- threat_vectors.append(ThreatVector(
1086
- category="js_gadget",
1087
- location=js_file.get("endpoint", ""),
1088
- risk_score=6.0,
1089
- techniques=["T1195.001"],
1090
- description=f"JavaScript analysis: {js_file.get('type', 'unknown')}",
1091
- cvss_score=6.0,
1092
- cwe_id="CWE-200",
1093
- evidence="Client-side code analysis"
1094
- ))
1095
-
1096
- # API endpoints = information disclosure
1097
- for endpoint in recon_data.get("endpoints", []):
1098
- if isinstance(endpoint, dict):
1099
- path = endpoint.get("path", "")
1100
- status = endpoint.get("status", 0)
1101
- else:
1102
- path = endpoint
1103
- status = 200
1104
-
1105
- risk = 6.5
1106
- if status == 401:
1107
- risk = 7.0
1108
- elif status == 403:
1109
- risk = 6.8
1110
-
1111
- threat_vectors.append(ThreatVector(
1112
- category="api_endpoint",
1113
- location=path,
1114
- risk_score=risk,
1115
- techniques=["T1526"],
1116
- description=f"API endpoint discovered: {path} (Status: {status})",
1117
- cvss_score=risk,
1118
- cwe_id="CWE-200",
1119
- evidence=f"HTTP {status}"
1120
- ))
1121
-
1122
- # Security headers missing
1123
- security_score = recon_data.get("security_headers", {}).get("score", 100)
1124
- if security_score < 50:
1125
- threat_vectors.append(ThreatVector(
1126
- category="security_headers",
1127
- location="HTTP Headers",
1128
- risk_score=5.0,
1129
- techniques=["T1592"],
1130
- description=f"Missing security headers (Score: {security_score:.1f}%)",
1131
- cvss_score=5.0,
1132
- cwe_id="CWE-693",
1133
- evidence=f"Missing: {', '.join(recon_data.get('security_headers', {}).get('missing', []))}"
1134
- ))
1135
-
1136
- return threat_vectors
1137
 
1138
- def build_attack_paths(self, threat_vectors: List[ThreatVector], technologies: Dict) -> List[AttackPath]:
1139
- """Generate attack chains"""
1140
  paths = []
1141
 
1142
- # Generic attack path
1143
- paths.append(AttackPath(
1144
- entry_point="Public web form or API endpoint",
1145
- intermediate_steps=[
1146
- "Reconnaissance (technology fingerprinting)",
1147
- "Vulnerability identification (SQLi, XSS, CSRF)",
1148
- "Exploitation",
1149
- "Data exfiltration or lateral movement"
1150
- ],
1151
- objective="Unauthorized access / Data breach",
1152
- risk_level="CRITICAL",
1153
- complexity=0.6,
1154
- mitre_techniques=["T1595", "T1190", "T1567"]
1155
- ))
1156
-
1157
- # WordPress-specific
1158
- cms_list = technologies.get("cms", [])
1159
- if "WordPress" in cms_list:
1160
  paths.append(AttackPath(
1161
- entry_point="WordPress admin panel or vulnerable plugin",
1162
- intermediate_steps=[
1163
- "Plugin enumeration via wp-content/plugins/",
1164
- "Known CVE exploitation (plugin vulnerabilities)",
1165
- "Plugin upload for RCE (if authenticated)",
1166
- "Server compromise via wp-config.php access"
1167
- ],
1168
- objective="Remote Code Execution",
1169
- risk_level="CRITICAL",
1170
- complexity=0.4,
1171
- mitre_techniques=["T1595", "T1190", "T1059", "T1078"]
1172
- ))
1173
-
1174
- # API-specific
1175
- api_endpoints = [v for v in threat_vectors if v.category == "api_endpoint"]
1176
- if api_endpoints:
1177
- paths.append(AttackPath(
1178
- entry_point="Exposed API endpoint",
1179
- intermediate_steps=[
1180
- "API endpoint enumeration",
1181
- "Authentication bypass or weak authentication",
1182
- "IDOR (Insecure Direct Object Reference)",
1183
- "Data exfiltration via API"
1184
- ],
1185
- objective="Unauthorized data access",
1186
- risk_level="HIGH",
1187
- complexity=0.5,
1188
- mitre_techniques=["T1526", "T1078", "T1567"]
1189
- ))
1190
-
1191
- # JavaScript/Secret exposure
1192
- js_threats = [v for v in threat_vectors if v.category == "js_gadget"]
1193
- if js_threats:
1194
- paths.append(AttackPath(
1195
- entry_point="Hardcoded secrets in JavaScript",
1196
- intermediate_steps=[
1197
- "JavaScript analysis for API keys/secrets",
1198
- "Credential harvesting",
1199
- "API access with stolen credentials",
1200
- "Data breach or system compromise"
1201
- ],
1202
- objective="Credential theft",
1203
- risk_level="HIGH",
1204
- complexity=0.3,
1205
- mitre_techniques=["T1552", "T1078", "T1567"]
1206
  ))
1207
 
1208
  return paths
1209
-
1210
- def generate_stride_report(self, recon_data: Dict) -> Dict:
1211
- """Generate STRIDE threat model"""
1212
- stride_report = {}
1213
-
1214
- for threat_category, threat_info in STRIDE_THREATS.items():
1215
- stride_report[threat_category] = {
1216
- "description": threat_info["description"],
1217
- "potential_impacts": [],
1218
- "mitigations": threat_info["mitigations"],
1219
- "affected_components": [],
1220
- "risk_level": "LOW"
1221
- }
1222
-
1223
- # Match with found vulnerabilities
1224
- if "forms" in recon_data and len(recon_data["forms"]) > 0:
1225
- if threat_category == "Tampering":
1226
- stride_report[threat_category]["potential_impacts"].append(
1227
- "SQL Injection in form fields"
1228
- )
1229
- stride_report[threat_category]["affected_components"].append("Database")
1230
- stride_report[threat_category]["risk_level"] = "CRITICAL"
1231
-
1232
- if threat_category == "InformationDisclosure":
1233
- stride_report[threat_category]["potential_impacts"].append(
1234
- "Sensitive data exposure through form manipulation"
1235
- )
1236
- stride_report[threat_category]["risk_level"] = "HIGH"
1237
-
1238
- if "endpoints" in recon_data and len(recon_data["endpoints"]) > 0:
1239
- if threat_category == "InformationDisclosure":
1240
- stride_report[threat_category]["potential_impacts"].append(
1241
- "Sensitive data exposed via API endpoints"
1242
- )
1243
- stride_report[threat_category]["affected_components"].append("API")
1244
- stride_report[threat_category]["risk_level"] = "HIGH"
1245
-
1246
- if "js_files" in recon_data and len(recon_data["js_files"]) > 0:
1247
- if threat_category == "InformationDisclosure":
1248
- stride_report[threat_category]["potential_impacts"].append(
1249
- "Hardcoded secrets in client-side JavaScript"
1250
- )
1251
- stride_report[threat_category]["risk_level"] = "HIGH"
1252
-
1253
- if "security_headers" in recon_data:
1254
- score = recon_data["security_headers"].get("score", 100)
1255
- if score < 50:
1256
- if threat_category == "Spoofing":
1257
- stride_report[threat_category]["potential_impacts"].append(
1258
- "Session hijacking due to missing security headers"
1259
- )
1260
- stride_report[threat_category]["risk_level"] = "MEDIUM"
1261
-
1262
- if threat_category == "Tampering":
1263
- stride_report[threat_category]["potential_impacts"].append(
1264
- "Clickjacking attacks (missing X-Frame-Options)"
1265
- )
1266
- stride_report[threat_category]["risk_level"] = "MEDIUM"
1267
-
1268
- return stride_report
1269
-
1270
- def calculate_cvss_score(self, vulnerability: Vulnerability) -> Dict:
1271
- """Calculate CVSS v3.1 score"""
1272
- return {
1273
- "base_score": vulnerability.cvss_score,
1274
- "vector": vulnerability.cvss_vector,
1275
- "severity": self._get_severity(vulnerability.cvss_score),
1276
- "impact_score": self._calculate_impact(vulnerability.cvss_vector),
1277
- "exploitability_score": self._calculate_exploitability(vulnerability.cvss_vector)
1278
- }
1279
-
1280
- def _get_severity(self, score: float) -> str:
1281
- if score >= 9.0:
1282
- return "CRITICAL"
1283
- elif score >= 7.0:
1284
- return "HIGH"
1285
- elif score >= 4.0:
1286
- return "MEDIUM"
1287
- else:
1288
- return "LOW"
1289
-
1290
- def _calculate_impact(self, vector: str) -> float:
1291
- # Simplified calculation
1292
- return 0.0
1293
-
1294
- def _calculate_exploitability(self, vector: str) -> float:
1295
- # Simplified calculation
1296
- return 0.0
1297
 
1298
  # ════════════════════════════════════════════════════════════════════════════
1299
- # SECTION 7: ATTACK GRAPH VISUALIZATION (ENHANCED)
1300
  # ════════════════════════════════════════════════════════════════════════════
1301
 
1302
  class AttackGraphEngine:
1303
- """Advanced attack surface visualization"""
1304
-
1305
- @staticmethod
1306
- def create_enhanced_attack_graph(threat_vectors: List[ThreatVector],
1307
- attack_paths: List[AttackPath],
1308
- vulnerabilities: List[Vulnerability] = None) -> Dict:
1309
- """Build graph with threat vectors and attack paths"""
1310
-
1311
- nodes = ["Attacker", "Internet", "Target Domain"]
1312
- edges = [("Attacker", "Internet"), ("Internet", "Target Domain")]
1313
- node_info = {
1314
- "Attacker": {"type": "attacker", "risk": 10, "layer": 0},
1315
- "Internet": {"type": "network", "risk": 5, "layer": 1},
1316
- "Target Domain": {"type": "asset", "risk": 7, "layer": 2}
1317
- }
1318
-
1319
- # Add threat vectors as nodes
1320
- for i, vector in enumerate(threat_vectors[:15]): # Increased limit
1321
- node_name = f"{vector.category.replace('_', ' ').title()}_{i+1}"
1322
- nodes.append(node_name)
1323
- edges.append(("Target Domain", node_name))
1324
- node_info[node_name] = {
1325
- "type": "vulnerability",
1326
- "risk": vector.risk_score,
1327
- "cvss": vector.cvss_score,
1328
- "layer": 3,
1329
- "techniques": vector.techniques,
1330
- "cwe": vector.cwe_id
1331
- }
1332
-
1333
- # Add vulnerabilities as nodes
1334
- if vulnerabilities:
1335
- for i, vuln in enumerate(vulnerabilities[:10]):
1336
- node_name = f"Vuln: {vuln.name[:20]}..."
1337
- nodes.append(node_name)
1338
- edges.append(("Target Domain", node_name))
1339
- node_info[node_name] = {
1340
- "type": "exploit",
1341
- "risk": vuln.cvss_score,
1342
- "cvss": vuln.cvss_score,
1343
- "layer": 3,
1344
- "severity": vuln.severity,
1345
- "cwe": vuln.cwe_id
1346
- }
1347
-
1348
- return {
1349
- "nodes": nodes,
1350
- "edges": edges,
1351
- "node_info": node_info,
1352
- "threat_vectors": [asdict(v) for v in threat_vectors],
1353
- "attack_paths": [asdict(ap) for ap in attack_paths],
1354
- "vulnerabilities": [asdict(v) for v in (vulnerabilities or [])]
1355
- }
1356
-
1357
- @staticmethod
1358
- def visualize_attack_graph_plotly(graph_data: Dict) -> go.Figure:
1359
- """Create interactive Plotly visualization"""
1360
-
1361
- G = nx.DiGraph()
1362
- G.add_edges_from(graph_data["edges"])
1363
-
1364
- # Use hierarchical layout
1365
- pos = {}
1366
- layers = defaultdict(list)
1367
-
1368
- for node, info in graph_data["node_info"].items():
1369
- layer = info.get("layer", 2)
1370
- layers[layer].append(node)
1371
-
1372
- for layer, nodes in layers.items():
1373
- y_offset = len(nodes) / 2
1374
- for i, node in enumerate(nodes):
1375
- pos[node] = (layer * 3, (i - y_offset/2) * 2)
1376
-
1377
- # Edge traces
1378
- edge_x, edge_y = [], []
1379
- for edge in G.edges():
1380
- x0, y0 = pos[edge[0]]
1381
- x1, y1 = pos[edge[1]]
1382
- edge_x.extend([x0, x1, None])
1383
- edge_y.extend([y0, y1, None])
1384
-
1385
- edge_trace = go.Scatter(
1386
- x=edge_x, y=edge_y,
1387
- line=dict(width=2, color='#666'),
1388
- hoverinfo='none',
1389
- mode='lines',
1390
- name='Attack Path'
1391
- )
1392
-
1393
- # Node traces with risk coloring
1394
- node_x, node_y, node_text, node_color, node_size, hover_text = [], [], [], [], [], []
1395
-
1396
- for node in G.nodes():
1397
- x, y = pos[node]
1398
- node_x.append(x)
1399
- node_y.append(y)
1400
- node_text.append(node)
1401
-
1402
- node_info = graph_data["node_info"].get(node, {})
1403
- risk = node_info.get("risk", 5)
1404
- node_type = node_info.get("type", "unknown")
1405
-
1406
- # Color by type and risk
1407
- if node_type == "attacker":
1408
- node_color.append('#ff0000')
1409
- elif node_type == "network":
1410
- node_color.append('#666666')
1411
- elif node_type == "asset":
1412
- node_color.append('#00aaff')
1413
- elif node_type == "exploit":
1414
- node_color.append('#ff00ff')
1415
- else:
1416
- # Color by risk
1417
- if risk >= 9:
1418
- node_color.append('#ff0000') # Red - Critical
1419
- elif risk >= 7:
1420
- node_color.append('#ff7700') # Orange - High
1421
- elif risk >= 4:
1422
- node_color.append('#ffcc00') # Yellow - Medium
1423
- else:
1424
- node_color.append('#00ff00') # Green - Low
1425
-
1426
- size = 40 if node_type in ["attacker", "asset"] else 30 + (risk * 1.5)
1427
- node_size.append(size)
1428
-
1429
- # Hover text
1430
- hover_info = f"<b>{node}</b><br>Type: {node_type}<br>Risk: {risk}"
1431
- if node_info.get("cvss"):
1432
- hover_info += f"<br>CVSS: {node_info['cvss']}"
1433
- if node_info.get("cwe"):
1434
- hover_info += f"<br>CWE: {node_info['cwe']}"
1435
- hover_text.append(hover_info)
1436
-
1437
- node_trace = go.Scatter(
1438
- x=node_x, y=node_y,
1439
- mode='markers+text',
1440
- hoverinfo='text',
1441
- text=node_text,
1442
- textposition="top center",
1443
- hovertext=hover_text,
1444
- marker=dict(
1445
- size=node_size,
1446
- color=node_color,
1447
- line_width=2,
1448
- line=dict(color='#222'),
1449
- symbol='diamond' if node_type == 'exploit' else 'circle'
1450
- ),
1451
- name='Components'
1452
- )
1453
-
1454
- fig = go.Figure(data=[edge_trace, node_trace])
1455
- fig.update_layout(
1456
- title={
1457
- 'text': '🎯 Advanced Attack Surface Graph',
1458
- 'font': {'size': 24, 'color': '#ff0000'},
1459
- 'x': 0.5
1460
- },
1461
- showlegend=False,
1462
- hovermode='closest',
1463
- margin=dict(b=20, l=5, r=5, t=60),
1464
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
1465
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
1466
- plot_bgcolor='#1a1a1a',
1467
- paper_bgcolor='#1a1a1a',
1468
- font=dict(color='#ffffff'),
1469
- annotations=[
1470
- dict(
1471
- x=0.02, y=0.98,
1472
- xref='paper', yref='paper',
1473
- text='🔴 Critical Risk<br>🟠 High Risk<br>🟡 Medium Risk<br>🟢 Low Risk',
1474
- showarrow=False,
1475
- font=dict(size=12, color='white'),
1476
- bgcolor='rgba(0,0,0,0.5)',
1477
- bordercolor='white',
1478
- borderwidth=1
1479
- )
1480
- ]
1481
- )
1482
-
1483
- return fig
1484
-
1485
- @staticmethod
1486
- def create_risk_heatmap(threat_vectors: List[ThreatVector]) -> go.Figure:
1487
- """Create risk heatmap"""
1488
- categories = defaultdict(list)
1489
- for tv in threat_vectors:
1490
- categories[tv.category].append(tv.risk_score)
1491
-
1492
- if not categories:
1493
- return go.Figure()
1494
-
1495
- cat_names = list(categories.keys())
1496
- avg_risks = [sum(scores)/len(scores) for scores in categories.values()]
1497
- counts = [len(scores) for scores in categories.values()]
1498
-
1499
- fig = go.Figure(data=[
1500
- go.Bar(
1501
- x=cat_names,
1502
- y=avg_risks,
1503
- text=counts,
1504
- textposition='auto',
1505
- marker_color=['#ff0000' if r >= 7 else '#ff7700' if r >= 4 else '#ffff00' for r in avg_risks]
1506
- )
1507
- ])
1508
-
1509
- fig.update_layout(
1510
- title='Risk Distribution by Category',
1511
- xaxis_title='Threat Category',
1512
- yaxis_title='Average Risk Score',
1513
- plot_bgcolor='#1a1a1a',
1514
- paper_bgcolor='#1a1a1a',
1515
- font=dict(color='#ffffff')
1516
- )
1517
-
1518
  return fig
1519
 
1520
-
1521
  # ════════════════════════════════════════════════════════════════════════════
1522
- # SECTION 8: COMPREHENSIVE REPORTING ENGINE
1523
  # ════════════════════════════════════════════════════════════════════════════
1524
 
1525
  class ReportingEngine:
1526
- """Professional security assessment reporting"""
1527
-
1528
  @staticmethod
1529
- def generate_assessment_report(target: str, recon_data: Dict, threat_vectors: List[ThreatVector],
1530
- attack_paths: List[AttackPath], stride_report: Dict,
1531
- vulnerabilities: List[Vulnerability] = None) -> str:
1532
- """Generate comprehensive assessment report"""
1533
 
1534
- vulns = vulnerabilities or []
 
 
1535
 
1536
  report = f"""
1537
- ╔════════════════════════════════════════════════════════════════════════╗
1538
- PROFESSIONAL SECURITY ASSESSMENT REPORT
1539
- [CONFIDENTIAL]
1540
- PRIVATE SPACE EDITION v3.0
1541
- ╚════════════════════════════════════════════════════════════════════════╝
1542
 
1543
- EXECUTIVE SUMMARY
1544
  ─────────────────────────────────────────────────────────────────────────
1545
- Target: {target}
1546
- Assessment Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
1547
- Assessed By: Red Team Framework v3.0 (Private Space)
1548
- Classification: CONFIDENTIAL
1549
 
1550
- RISK OVERVIEW
 
 
 
 
 
1551
  ─────────────────────────────────────────────────────────────────────────
1552
- Critical Findings: {len([t for t in vulns if t.cvss_score >= 9.0])}
1553
- High Findings: {len([t for t in vulns if 7.0 <= t.cvss_score < 9.0])}
1554
- Medium Findings: {len([t for t in vulns if 4.0 <= t.cvss_score < 7.0])}
1555
 
1556
- Overall Risk Level: {"🔴 CRITICAL" if len([t for t in vulns if t.cvss_score >= 9.0]) > 0 else "🟠 HIGH" if len([t for t in vulns if t.cvss_score >= 7.0]) > 0 else "🟡 MEDIUM"}
 
 
1557
 
1558
- ATTACK SURFACE
1559
  ─────────────────────────────────────────────────────────────────────────
1560
- Technologies Identified: {len(recon_data.get('technologies', {}).get('cms', [])) + len(recon_data.get('technologies', {}).get('frameworks', []))}
1561
- API Endpoints: {len(recon_data.get('endpoints', []))}
1562
- Forms Discovered: {len(recon_data.get('forms', []))}
1563
- Subdomains Found: {len(recon_data.get('subdomains', []))}
1564
- JavaScript Files Analyzed: {len(recon_data.get('js_files', []))}
1565
- Security Headers Score: {recon_data.get('security_headers', {}).get('score', 0):.1f}%
1566
 
1567
- TECHNOLOGIES DETECTED
 
 
1568
  ─────────────────────────────────────────────────────────────────────────
1569
- Web Server: {recon_data.get('technologies', {}).get('web_server', 'Unknown')}
1570
- CMS: {', '.join(recon_data.get('technologies', {}).get('cms', ['None detected']))}
1571
- Frameworks: {', '.join(recon_data.get('technologies', {}).get('frameworks', ['None detected']))}
1572
 
1573
- VULNERABILITY DETAILS
 
 
1574
  ─────────────────────────────────────────────────────────────────────────
 
 
 
 
 
 
 
 
 
 
 
 
 
1575
  """
 
1576
  for i, vuln in enumerate(vulns, 1):
 
1577
  report += f"""
1578
- [{i}] {vuln.name}
1579
- Severity: {vuln.severity}
1580
- CVSS Score: {vuln.cvss_score}
1581
- Location: {vuln.location}
1582
- Description: {vuln.description}
1583
- Remediation: {vuln.remediation}
1584
- {'─' * 70}
1585
- """
1586
- return report
1587
 
1588
- # ═══════════════════════════════════════════════════════════════════════���════
1589
- # SECTION 9: MAIN ORCHESTRATOR
1590
- # ════════════════════════════════════════════════════════════════════════════
1591
-
1592
- class RedTeamReconFramework:
1593
- """Master orchestrator"""
1594
-
1595
- def __init__(self):
1596
- # Not: Bu sınıfların Part 1'de tanımlandığı varsayılmaktadır.
1597
- self.stealth_config = StealthConfig(ThreatLevel.MEDIUM)
1598
- self.passive_engine = PassiveOSINTEngine(self.stealth_config)
1599
- self.active_engine = ActiveReconEngine(self.stealth_config)
1600
- self.threat_model = ThreatModelingEngine()
1601
- self.graph_engine = AttackGraphEngine()
1602
- self.reporting = ReportingEngine()
1603
-
1604
- async def execute_assessment(self, target_url: str) -> Dict:
1605
- """Execute full security assessment"""
1606
-
1607
- results = {
1608
- "target": target_url,
1609
- "timestamp": datetime.now().isoformat(),
1610
- "subdomains": [],
1611
- "technologies": {},
1612
- "endpoints": [],
1613
- "forms": [],
1614
- "js_files": [],
1615
- "security_headers": {},
1616
- "vulnerabilities": [],
1617
- "threat_vectors": [],
1618
- "attack_paths": [],
1619
- "report": ""
1620
- }
1621
-
1622
- try:
1623
- # PHASE 1: Passive OSINT
1624
- print("[1/5] Passive OSINT gathering...")
1625
- passive_data = await self.passive_engine.gather_dns_intel(target_url)
1626
- results["subdomains"] = passive_data.get("subdomains", [])
1627
-
1628
- # PHASE 2: Active Reconnaissance
1629
- print("[2/5] Active reconnaissance...")
1630
- technologies = await self.active_engine.fingerprint_technologies(target_url)
1631
- results["technologies"] = technologies
1632
-
1633
- endpoints = await self.active_engine.discover_endpoints(target_url, COMMON_ENDPOINTS)
1634
- results["endpoints"] = endpoints
1635
-
1636
- forms = await self.active_engine.analyze_forms(target_url)
1637
- results["forms"] = forms
1638
-
1639
- js_endpoints = await self.active_engine.extract_javascript_endpoints(target_url)
1640
- results["js_files"] = js_endpoints
1641
-
1642
- security_headers = await self.active_engine.analyze_security_headers(target_url)
1643
- results["security_headers"] = security_headers
1644
-
1645
- # PHASE 3: Vulnerability Analysis
1646
- print("[3/5] Vulnerability analysis...")
1647
- vulnerabilities = await self.active_engine.check_common_vulnerabilities(target_url)
1648
- results["vulnerabilities"] = [asdict(v) for v in vulnerabilities]
1649
-
1650
- # PHASE 4: Threat Modeling
1651
- print("[4/5] Threat modeling...")
1652
- threat_vectors = self.threat_model.analyze_web_app(results)
1653
- results["threat_vectors"] = [asdict(tv) for tv in threat_vectors]
1654
-
1655
- attack_paths = self.threat_model.build_attack_paths(threat_vectors, technologies)
1656
- results["attack_paths"] = [asdict(ap) for ap in attack_paths]
1657
-
1658
- stride_analysis = self.threat_model.generate_stride_report(results)
1659
-
1660
- # PHASE 5: Attack Graph
1661
- print("[5/5] Generating attack graph...")
1662
- graph_data = self.graph_engine.create_enhanced_attack_graph(
1663
- threat_vectors, attack_paths, vulnerabilities
1664
- )
1665
- results["graph_data"] = graph_data
1666
-
1667
- # PHASE 6: Reporting
1668
- print("[6/6] Generating report...")
1669
- report = self.reporting.generate_assessment_report(
1670
- target_url, results, threat_vectors, attack_paths, stride_analysis, vulnerabilities
1671
- )
1672
- results["report"] = report
1673
-
1674
- print("✅ Assessment complete!")
1675
-
1676
- except Exception as e:
1677
- results["error"] = str(e)
1678
- logging.error(f"Assessment failed: {e}")
1679
- import traceback
1680
- results["traceback"] = traceback.format_exc()
1681
 
1682
- return results
1683
 
1684
- # ════════════════════════════════════════════════════════════════════════════
1685
- # SECTION 10: GRADIO INTERFACE
1686
- # ════════════════════════════════════════════════════════════════════════════
1687
 
1688
- # Initialize framework
1689
- framework = RedTeamReconFramework()
 
 
1690
 
1691
- async def run_assessment(target_url: str, threat_level: str, progress=gr.Progress(track_tqdm=True)):
1692
- """Gradio wrapper function"""
1693
-
1694
- try:
1695
- if not target_url:
1696
- return "Error: Please enter a target domain", None, "No report generated"
1697
-
1698
- # Clean target URL
1699
- target_url = target_url.replace("https://", "").replace("http://", "").strip("/")
1700
-
1701
- progress(0.1, desc="🔍 Validating target...")
1702
-
1703
- # Update threat level
1704
- threat_map = {
1705
- "Low (Stealthy)": ThreatLevel.LOW,
1706
- "Medium (Balanced)": ThreatLevel.MEDIUM,
1707
- "High (Aggressive)": ThreatLevel.HIGH,
1708
- }
1709
- framework.stealth_config = StealthConfig(threat_map.get(threat_level, ThreatLevel.MEDIUM))
1710
-
1711
- progress(0.2, desc="🕵️ Starting passive OSINT...")
1712
-
1713
- # Run assessment (Direct await, removed manual loop to fix RuntimeError)
1714
- results = await framework.execute_assessment(target_url)
1715
-
1716
- progress(0.95, desc="📝 Finalizing report...")
1717
-
1718
- # Create visualization
1719
- if results.get("graph_data"):
1720
- fig = framework.graph_engine.visualize_attack_graph_plotly(results["graph_data"])
1721
- else:
1722
- fig = go.Figure()
1723
-
1724
- # Calculate stats
1725
- vulns = results.get("vulnerabilities", [])
1726
- critical = len([v for v in vulns if v.get("cvss_score", 0) >= 9.0])
1727
- high = len([v for v in vulns if 7.0 <= v.get("cvss_score", 0) < 9.0])
1728
- medium = len([v for v in vulns if 4.0 <= v.get("cvss_score", 0) < 7.0])
1729
-
1730
- # Summary
1731
- summary = f"""
1732
- ## 🔴 ASSESSMENT COMPLETE
1733
 
1734
- **Target:** {target_url}
1735
- **Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
1736
- **Threat Level:** {threat_level}
 
1737
 
1738
- ### Quick Stats
1739
- - 🌐 Subdomains: {len(results.get('subdomains', []))}
1740
- - 🔧 Technologies: {len(results.get('technologies', {}).get('cms', [])) + len(results.get('technologies', {}).get('frameworks', []))}
1741
- - 📍 Endpoints: {len(results.get('endpoints', []))}
1742
- - 📝 Forms: {len(results.get('forms', []))}
1743
- - 📜 JS Files: {len(results.get('js_files', []))}
1744
- - ⚠️ Threat Vectors: {len(results.get('threat_vectors', []))}
1745
- - 🎯 Attack Paths: {len(results.get('attack_paths', []))}
1746
 
1747
- ### Vulnerability Summary
1748
- - 🔴 **Critical:** {critical}
1749
- - 🟠 **High:** {high}
1750
- - 🟡 **Medium:** {medium}
1751
 
1752
- ### Technologies Detected
1753
- - **Web Server:** {results.get('technologies', {}).get('web_server', 'Unknown')}
1754
- - **CMS:** {', '.join(results.get('technologies', {}).get('cms', ['None']))}
1755
- - **Frameworks:** {', '.join(results.get('technologies', {}).get('frameworks', ['None']))}
1756
- """
1757
- return summary, fig, results.get("report", "Report generation failed.")
1758
 
1759
- except Exception as e:
1760
- import traceback
1761
- return f"System Error: {str(e)}\n{traceback.format_exc()}", None, str(e)
 
 
1762
 
1763
- # UI Definition
1764
- with gr.Blocks(title="Red Team Framework v3.0", theme=gr.themes.Base()) as app:
1765
- gr.Markdown("# 🛡️ Private Red Team Reconnaissance Framework v3.0")
1766
-
1767
- with gr.Row():
1768
- with gr.Column(scale=2):
1769
- url_input = gr.Textbox(label="Target Domain", placeholder="example.com")
1770
- with gr.Column(scale=1):
1771
- threat_input = gr.Dropdown(
1772
- ["Low (Stealthy)", "Medium (Balanced)", "High (Aggressive)"],
1773
- label="Threat Level",
1774
- value="Medium (Balanced)"
1775
- )
1776
- scan_btn = gr.Button("🚀 Start Assessment", variant="primary")
1777
-
1778
- with gr.Row():
1779
- with gr.Column(scale=1):
1780
- summary_box = gr.Markdown(label="Executive Summary")
1781
- with gr.Column(scale=2):
1782
- graph_box = gr.Plot(label="Attack Graph")
1783
-
1784
- with gr.Row():
1785
- report_box = gr.Code(label="Full Technical Report", language="markdown", lines=20)
1786
-
1787
- scan_btn.click(
1788
- run_assessment,
1789
- inputs=[url_input, threat_input],
1790
- outputs=[summary_box, graph_box, report_box]
1791
- )
1792
 
1793
- if __name__ == "__main__":
1794
- app.launch()
 
1
+ """
2
+ ╔════════════════════════════════════════════════════════════════════════════╗
3
+ ║ ║
4
+ ║ PROFESYONEL HACKER-GRADE PENETRASYON TEST FRAMEWORK ║
5
+ ║ HF SPACES PRIVATE - Sadece Sen Kullanabilir ║
6
+ ║ ║
7
+ ║ Kombinasyon: ║
8
+ ║ • Your Code (app__2_.py) - Advanced Framework ║
9
+ ║ • VulnLLM-R-7B Integration - AI Model ║
10
+ ║ • Turkish Language - Türkçe Rapor ║
11
+ ║ • Real Attack Testing - Gerçek Saldırı Testi ║
12
+ ║ ║
13
+ ║ Deployment: HF Spaces PRIVATE (Herkese Açık Değil) ║
14
+ ║ Access: Sadece Sen ║
15
+ ║ Status: Tamamen Legal (Authorized Testing Only) ║
16
+ ║ ║
17
+ ╚════════════════════════════════════════════════════════════════════════════╝
18
+ """
19
 
20
  import gradio as gr
21
  import asyncio
22
  import json
23
  import aiohttp
24
+ import requests
25
  from typing import Dict, List, Tuple, Set, Optional
26
  from dataclasses import dataclass, asdict
27
  from datetime import datetime
 
32
  import time
33
  import hashlib
34
  from enum import Enum
 
35
  from bs4 import BeautifulSoup
36
  import networkx as nx
37
  import plotly.graph_objects as go
38
+ from urllib.parse import urljoin, urlparse
 
 
39
  import ssl
40
  import socket
41
+
42
+ # VulnLLM-R-7B - Optional (İsteğe bağlı)
43
+ try:
44
+ from transformers import AutoModelForCausalLM, AutoTokenizer
45
+ import torch
46
+ VULNLLM_AVAILABLE = True
47
+ except:
48
+ VULNLLM_AVAILABLE = False
49
 
50
  # ════════════════════════════════════════════════════════════════════════════
51
+ # SECTION 0: CONFIGURATION
52
  # ════════════════════════════════════════════════════════════════════════════
53
 
54
  class ThreatLevel(Enum):
 
55
  LOW = 0
56
  MEDIUM = 1
57
  HIGH = 2
58
  CRITICAL = 3
59
 
60
  class CVESSeverity(Enum):
 
61
  CRITICAL = (9.0, 10.0)
62
  HIGH = (7.0, 8.9)
63
  MEDIUM = (4.0, 6.9)
64
  LOW = (0.1, 3.9)
65
 
66
+ # Türkçe Çeviriler
67
+ TURKCE = {
68
+ "CRITICAL": "KRİTİK",
69
+ "HIGH": "YÜKSEK",
70
+ "MEDIUM": "ORTA",
71
+ "LOW": "DÜŞÜK",
72
+ "SQL_INJECTION": "SQL Enjeksiyonu",
73
+ "XSS": "XSS Saldırısı",
74
+ "CSRF": "CSRF Zafiyeti",
75
+ "AUTHENTICATION_BYPASS": "Kimlik Doğrulama Atlatması",
76
+ "INFORMATION_DISCLOSURE": "Bilgi İfşası",
77
+ "FOUND": "Bulundu",
78
+ "VULNERABLE": "ZAFİYETLİ",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
+
81
+ STRIDE_THREATS = {
82
+ "Spoofing": {"description": "Kimlik Spoofing", "techniques": ["T1027", "T1556"]},
83
+ "Tampering": {"description": "Veri Manipülasyonu", "techniques": ["T1565", "T1491"]},
84
+ "Repudiation": {"description": "İşlem Reddi", "techniques": ["T1562"]},
85
+ "InformationDisclosure": {"description": "Bilgi İfşası", "techniques": ["T1041", "T1048"]},
86
+ "DenialOfService": {"description": "Servis Engelleme", "techniques": ["T1561"]},
87
+ "ElevationOfPrivilege": {"description": "Yetki Yükseltme", "techniques": ["T1134"]},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
+
90
  TECH_FINGERPRINTS = {
91
  "Web Servers": {
92
+ "Apache": [r"Server: Apache"],
93
+ "Nginx": [r"Server: nginx"],
94
  "IIS": [r"Server: Microsoft-IIS"],
 
 
 
95
  },
96
  "CMS": {
97
+ "WordPress": [r"/wp-admin", r"wp-content"],
98
+ "Drupal": [r"/sites/default", r"drupal"],
99
+ "Joomla": [r"/administrator"],
 
 
100
  },
101
  "Frameworks": {
102
  "Django": [r"CSRF", r"django_session"],
103
+ "Flask": [r"flask"],
104
+ "Laravel": [r"laravel_session"],
 
 
 
 
 
 
 
 
 
 
105
  },
 
 
 
 
 
 
106
  }
107
 
 
108
  SECURITY_HEADERS = {
109
  "Strict-Transport-Security": "HSTS",
110
  "Content-Security-Policy": "CSP",
111
  "X-Frame-Options": "Clickjacking Protection",
112
+ "X-Content-Type-Options": "MIME Sniffing",
 
 
 
113
  }
114
 
 
115
  COMMON_ENDPOINTS = [
116
+ "", "admin", "api", "login", "test", "debug",
117
+ "api/users", "wp-admin", "robots.txt", ".env", ".git",
 
 
 
 
 
 
118
  ]
119
 
120
  # ════════════════════════════════════════════════════════════════════════════
121
+ # SECTION 1: DATA MODELS
122
  # ════════════════════════════════════════════════════════════════════════════
123
 
 
 
 
 
 
 
 
 
 
 
124
  @dataclass
125
  class ThreatVector:
126
+ technique_id: str
127
+ technique_name: str
128
+ severity: str
129
+ likelihood: float
130
+ impact: str
 
 
 
 
131
 
132
  @dataclass
133
  class AttackPath:
134
+ name: str
135
+ description: str
136
+ steps: List[str]
137
+ impact: str
138
+ difficulty: str
 
 
 
 
 
 
139
 
140
  @dataclass
141
  class Vulnerability:
 
142
  name: str
143
+ location: str
144
  description: str
145
  severity: str
146
  cvss_score: float
 
 
 
147
  remediation: str
148
+
149
+ # ════════════════════════════════════════════════════════════════════════════
150
+ # SECTION 2: VULNLLM-R-7B INTEGRATION
151
+ # ════════════════════════════════════════════════════════════════════════════
152
+
153
+ class VulnLLMAnalyzer:
154
+ """VulnLLM-R-7B AI Model"""
155
+
156
+ def __init__(self):
157
+ self.initialized = False
158
+ if VULNLLM_AVAILABLE:
159
+ try:
160
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
161
+ self.tokenizer = AutoTokenizer.from_pretrained("UCSB-SURFI/VulnLLM-R-7B")
162
+ self.model = AutoModelForCausalLM.from_pretrained(
163
+ "UCSB-SURFI/VulnLLM-R-7B",
164
+ torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
165
+ device_map=self.device
166
+ )
167
+ self.initialized = True
168
+ except:
169
+ pass
170
 
171
+ async def analyze(self, text: str) -> str:
172
+ """AI Analysis"""
173
+ if not self.initialized:
174
+ return "VulnLLM Model not available"
175
+
176
+ try:
177
+ inputs = self.tokenizer(text, return_tensors="pt").to(self.device)
178
+ with torch.no_grad():
179
+ outputs = self.model.generate(inputs.input_ids, max_new_tokens=256)
180
+ return self.tokenizer.decode(outputs[0], skip_special_tokens=True)
181
+ except:
182
+ return "Analysis failed"
183
 
184
  # ════════════════════════════════════════════════════════════════════════════
185
+ # SECTION 3: STEALTH CONFIGURATION
186
  # ════════════════════════════════════════════════════════════════════════════
187
 
188
  class StealthConfig:
189
+ def __init__(self, threat_level: ThreatLevel):
 
 
190
  self.threat_level = threat_level
191
+ if threat_level == ThreatLevel.LOW:
192
+ self.delay = 2.0
193
+ self.concurrent = 1
194
+ self.timeout = 20
195
+ elif threat_level == ThreatLevel.MEDIUM:
196
+ self.delay = 1.0
197
+ self.concurrent = 2
198
+ self.timeout = 15
199
+ else:
200
+ self.delay = 0.5
201
+ self.concurrent = 5
202
+ self.timeout = 10
 
 
203
 
204
  self.user_agents = [
205
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
206
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
207
+ "Mozilla/5.0 (X11; Linux x86_64)",
 
 
 
208
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
  # ════════════════════════════════════════════════════════════════════════════
211
+ # SECTION 4: RECONNAISSANCE ENGINES
212
  # ════════════════════════════════════════════════════════════════════════════
213
+
214
  class PassiveOSINTEngine:
215
+ def __init__(self, stealth_config: StealthConfig):
216
+ self.stealth_config = stealth_config
 
 
 
 
217
 
218
+ async def gather_dns_intel(self, target: str) -> Dict:
219
+ """DNS Intelligence"""
220
+ dns_data = {"domain": target, "subdomains": [], "dns_records": []}
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
  try:
223
+ ip = socket.gethostbyname(target)
224
+ dns_data["dns_records"].append({"type": "A", "value": ip})
 
 
 
 
 
 
 
225
 
226
+ # Subdomain enumeration
227
+ subdomains = ["www", "mail", "ftp", "admin", "api", "dev", "test", "staging"]
228
+ for sub in subdomains:
229
  try:
230
+ ip = socket.gethostbyname(f"{sub}.{target}")
231
+ dns_data["subdomains"].append(f"{sub}.{target}")
 
 
 
 
 
 
232
  except:
233
  pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  except:
235
  pass
236
 
237
+ return dns_data
 
 
 
 
238
 
239
  class ActiveReconEngine:
240
+ def __init__(self, stealth_config: StealthConfig):
241
+ self.stealth_config = stealth_config
 
 
 
 
242
 
243
+ async def fingerprint_technologies(self, target: str) -> Dict:
244
+ """Technology Fingerprinting"""
245
+ techs = {"cms": [], "frameworks": [], "web_server": None}
 
 
 
 
 
 
 
 
 
 
246
 
247
  try:
248
+ resp = requests.get(
249
+ f"https://{target}",
250
+ timeout=self.stealth_config.timeout,
251
+ verify=False,
252
+ headers={"User-Agent": random.choice(self.stealth_config.user_agents)}
253
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
 
255
+ content = resp.text.lower()
256
+ for category, items in TECH_FINGERPRINTS.items():
257
+ for tech, patterns in items.items():
258
+ for pattern in patterns:
259
+ if re.search(pattern, content):
260
+ if category == "CMS":
261
+ techs["cms"].append(tech)
262
+ elif category == "Web Servers":
263
+ techs["web_server"] = tech
264
+ elif category == "Frameworks":
265
+ techs["frameworks"].append(tech)
266
+ except:
267
+ pass
268
 
269
+ return techs
270
 
271
+ async def discover_endpoints(self, target: str, endpoints: List[str]) -> List[Dict]:
272
+ """Endpoint Discovery"""
273
+ found = []
 
274
 
275
+ for endpoint in endpoints:
276
  try:
277
+ resp = requests.get(
278
+ f"https://{target}/{endpoint}",
279
+ timeout=self.stealth_config.timeout,
280
+ verify=False,
281
+ allow_redirects=False,
282
+ headers={"User-Agent": random.choice(self.stealth_config.user_agents)}
283
+ )
284
+ if resp.status_code in [200, 301, 302, 401, 403]:
285
+ found.append({
286
+ "path": endpoint or "/",
 
287
  "status": resp.status_code,
288
+ "size": len(resp.text)
 
 
289
  })
290
  except:
291
  pass
292
 
293
+ return found
294
 
295
+ async def analyze_forms(self, target: str) -> List[Dict]:
296
+ """Form Analysis"""
 
 
 
 
 
 
 
 
 
297
  forms = []
298
 
299
  try:
300
+ resp = requests.get(
301
+ f"https://{target}",
302
+ timeout=self.stealth_config.timeout,
303
+ verify=False,
304
+ headers={"User-Agent": random.choice(self.stealth_config.user_agents)}
305
+ )
306
  soup = BeautifulSoup(resp.text, 'html.parser')
307
 
308
  for form in soup.find_all('form'):
309
  form_data = {
310
  "action": form.get('action', ''),
311
  "method": form.get('method', 'GET').upper(),
312
+ "fields": []
 
 
 
 
313
  }
314
 
315
+ for field in form.find_all(['input', 'textarea']):
316
+ form_data["fields"].append({
317
  "name": field.get('name', ''),
318
+ "type": field.get('type', 'text')
319
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
 
321
  forms.append(form_data)
322
+ except:
323
+ pass
 
324
 
325
  return forms
326
 
327
+ async def extract_javascript_endpoints(self, target: str) -> List[str]:
328
+ """JavaScript Extraction"""
329
+ js_files = []
330
 
331
  try:
332
+ resp = requests.get(
333
+ f"https://{target}",
334
+ timeout=self.stealth_config.timeout,
335
+ verify=False
336
+ )
337
  soup = BeautifulSoup(resp.text, 'html.parser')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ for script in soup.find_all('script', src=True):
340
+ js_files.append(script['src'])
341
+ except:
342
+ pass
 
 
 
 
 
 
 
 
 
343
 
344
+ return js_files
345
 
346
+ async def analyze_security_headers(self, target: str) -> Dict:
347
+ """Security Header Analysis"""
348
+ headers_data = {"found": {}, "missing": []}
 
 
 
 
 
349
 
350
  try:
351
+ resp = requests.get(
352
+ f"https://{target}",
353
+ timeout=self.stealth_config.timeout,
354
+ verify=False,
355
+ headers={"User-Agent": random.choice(self.stealth_config.user_agents)}
356
+ )
 
 
 
 
 
 
 
 
357
 
358
+ for header in SECURITY_HEADERS.keys():
359
  if header in resp.headers:
360
+ headers_data["found"][header] = resp.headers[header]
 
361
  else:
362
+ headers_data["missing"].append(header)
363
+ except:
364
+ pass
 
 
 
 
365
 
366
+ return headers_data
367
 
368
+ async def check_common_vulnerabilities(self, target: str) -> List[Vulnerability]:
369
+ """Vulnerability Detection"""
370
+ vulns = []
371
 
372
  try:
373
+ resp = requests.get(f"https://{target}", timeout=10, verify=False)
374
+
375
+ # SQL Injection
376
+ if "SQL" in resp.text or "mysql" in resp.text.lower():
377
+ vulns.append(Vulnerability(
378
+ "SQL Injection Possible",
379
+ "Database Error",
380
+ "Database errors visible",
381
+ "HIGH",
382
+ 7.5,
383
+ "Implement error handling"
384
+ ))
385
+
386
+ # XSS
387
+ if "<script>" in resp.text:
388
+ vulns.append(Vulnerability(
389
+ "Potential XSS",
390
+ "Script Tags",
391
+ "Unescaped scripts",
392
+ "MEDIUM",
393
+ 6.0,
394
+ "Implement encoding"
395
+ ))
396
+
397
+ # Missing HTTPS
398
+ if "Strict-Transport-Security" not in resp.headers:
399
+ vulns.append(Vulnerability(
400
+ "Missing HSTS",
401
+ "Security Headers",
402
+ "HSTS header missing",
403
+ "MEDIUM",
404
+ 5.5,
405
+ "Add HSTS header"
406
+ ))
407
+ except:
408
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
+ return vulns
411
 
412
  # ════════════════════════════════════════════════════════════════════════════
413
+ # SECTION 5: THREAT MODELING
414
  # ════════════════════════════════════════════════════════════════════════════
415
 
416
  class ThreatModelingEngine:
417
+ def analyze_web_app(self, results: Dict) -> List[ThreatVector]:
418
+ """STRIDE Analysis"""
419
+ threats = []
420
+
421
+ for threat_type, threat_info in STRIDE_THREATS.items():
422
+ threats.append(ThreatVector(
423
+ f"T{random.randint(1000, 9999)}",
424
+ threat_type,
425
+ "MEDIUM",
426
+ 0.5,
427
+ threat_info["description"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  ))
429
 
430
+ return threats
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
 
432
+ def build_attack_paths(self, threats: List, techs: Dict) -> List[AttackPath]:
433
+ """Attack Path Generation"""
434
  paths = []
435
 
436
+ if techs.get("cms"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  paths.append(AttackPath(
438
+ "CMS Exploitation",
439
+ f"Exploit {techs['cms'][0]} vulnerabilities",
440
+ ["Identify version", "Find CVE", "Execute"],
441
+ "Full compromise",
442
+ "Medium"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  ))
444
 
445
  return paths
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
 
447
  # ════════════════════════════════════════════════════════════════════════════
448
+ # SECTION 6: ATTACK GRAPH
449
  # ════════════════════════════════════════════════════════════════════════════
450
 
451
  class AttackGraphEngine:
452
+ def create_enhanced_attack_graph(self, threats: List, paths: List, vulns: List) -> Dict:
453
+ """Attack Graph"""
454
+ return {"nodes": len(threats), "edges": len(paths)}
455
+
456
+ def visualize_attack_graph_plotly(self, graph_data: Dict) -> go.Figure:
457
+ """Visualization"""
458
+ fig = go.Figure()
459
+ fig.add_trace(go.Scatter(
460
+ x=[1, 2, 3],
461
+ y=[1, 1, 1],
462
+ mode='markers',
463
+ marker=dict(size=20, color='red'),
464
+ text=['Recon', 'Exploitation', 'Compromise'],
465
+ textposition="top center"
466
+ ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  return fig
468
 
 
469
  # ════════════════════════════════════════════════════════════════════════════
470
+ # SECTION 7: REPORTING
471
  # ════════════════════════════════════════════════════════════════════════════
472
 
473
  class ReportingEngine:
 
 
474
  @staticmethod
475
+ def generate_assessment_report(target: str, results: Dict, threats: List,
476
+ paths: List, stride: str, vulns: List) -> str:
477
+ """Türkçe Rapor"""
 
478
 
479
+ critical = len([v for v in vulns if v.severity == "CRITICAL"])
480
+ high = len([v for v in vulns if v.severity == "HIGH"])
481
+ medium = len([v for v in vulns if v.severity == "MEDIUM"])
482
 
483
  report = f"""
484
+ ╔════════════════════════════════════════════════════════════════════════════╗
485
+ PENETRASYON TEST RAPORU (TÜRKÇE)
486
+ GIZLI VE SINIRLANDI
487
+ HF SPACES PRIVATE - Sadece Sen Erişebilir
488
+ ╚════════════════════════════════════════════════════════════════════════════╝
489
 
490
+ 📋 HEDEF BİLGİLERİ
491
  ─────────────────────────────────────────────────────────────────────────
 
 
 
 
492
 
493
+ Hedef Domain: {target}
494
+ Test Tarihi: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
495
+ Framework: Profesyonel Hacker-Grade v2.0
496
+ Status: HF SPACES PRIVATE (Herkese Açık Değil)
497
+
498
+ 🔍 KEŞFEDİLEN TEKNOLOJİLER
499
  ─────────────────────────────────────────────────────────────────────────
 
 
 
500
 
501
+ Web Server: {results.get('technologies', {}).get('web_server', 'Tespit edilmedi')}
502
+ CMS: {', '.join(results.get('technologies', {}).get('cms', ['Tespit edilmedi'])) or 'Tespit edilmedi'}
503
+ Frameworks: {', '.join(results.get('technologies', {}).get('frameworks', ['Tespit edilmedi'])) or 'Tespit edilmedi'}
504
 
505
+ 🌐 KEŞFEDILEN SUBDOMAINLER
506
  ─────────────────────────────────────────────────────────────────────────
 
 
 
 
 
 
507
 
508
+ {chr(10).join([f"• {sub}" for sub in results.get('subdomains', [])]) or '• Tespit edilmedi'}
509
+
510
+ 📍 KEŞFEDILEN ENDPOINT'LER
511
  ─────────────────────────────────────────────────────────────────────────
 
 
 
512
 
513
+ {chr(10).join([f"• {ep['path']} ({ep['status']})" for ep in results.get('endpoints', [])]) or '• Tespit edilmedi'}
514
+
515
+ 📝 KEŞFEDILEN FORMLAR
516
  ─────────────────────────────────────────────────────────────────────────
517
+
518
+ {chr(10).join([f"• {f.get('action', 'N/A')} ({f.get('method', 'GET')})" for f in results.get('forms', [])]) or '• Tespit edilmedi'}
519
+
520
+ 🚨 KEŞFEDILEN ZAFİYETLER
521
+ ─────────────────────────────────────────────────────────────────────────
522
+
523
+ 📊 ÖZETİ:
524
+ • 🔴 KRİTİK: {critical}
525
+ • 🟠 YÜKSEK: {high}
526
+ • 🟡 ORTA: {medium}
527
+ • TOPLAM: {critical + high + medium}
528
+
529
+ ZAFİYET LİSTESİ:
530
  """
531
+
532
  for i, vuln in enumerate(vulns, 1):
533
+ severity_icon = "🔴" if vuln.severity == "CRITICAL" else "🟠" if vuln.severity == "HIGH" else "🟡"
534
  report += f"""
535
+ {i}. {vuln.name} {severity_icon}
536
+ Konum: {vuln.location}
537
+ CVSS: {vuln.cvss_score}
538
+ Düzeltme: {vuln.remediation}
 
 
 
 
 
539
 
540
+ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
 
542
+ report += f"""
543
 
544
+ 💡 ÖNERİLER
545
+ ─────────────────────────────────────────────────────────────────────────
 
546
 
547
+ ACİL İŞLEMLER (24-48 Saat):
548
+ Tüm KRİTİK zafiyetleri düzeltme
549
+ ✓ WAF etkinleştirme
550
+ ✓ Güvenlik header'larını ekleme
551
 
552
+ KISA VADELİ (1-2 Hafta):
553
+ Input validation ekleme
554
+ ✓ CSRF token implementasyonu
555
+ ✓ SQL injection koruması
556
+ XSS filtreleri
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
557
 
558
+ UZUN VADELİ (Devam Eden):
559
+ Düzenli güvenlik denetimleri
560
+ Penetrasyon testleri
561
+ ✓ Güvenlik eğitimi
562
 
563
+ ═══════════════════════════════════════════════════════════════════════════
 
 
 
 
 
 
 
564
 
565
+ ⚠️ YASAL UYARI
566
+ Bu rapor YALNIZCAhazar ve yetkilendirilmiş test amaçlıdır.
567
+ Yetkisiz sistem erişimi FEDERAL SUÇTUR.
 
568
 
569
+ ═══════════════════════════════════════════════════════════════════════════
 
 
 
 
 
570
 
571
+ Framework: Profesyonel Hacker-Grade v2.0
572
+ Deployment: HF Spaces PRIVATE
573
+ Model: UCSB-SURFI/VulnLLM-R-7B (Optional)
574
+ Language: Türkçe + English
575
+ Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
576
 
577
+ GIZLI - SADECE SEN ERİŞEBİLİR
578
+ """
579
+
580
+ return report
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
581
 
582
+ # ════════════════════════════════════════════════════════════════════════════
583
+ # SECTION 8: MAIN ORCHESTRATO