ziffir commited on
Commit
acd3686
·
verified ·
1 Parent(s): 92330ce

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +559 -572
app.py CHANGED
@@ -1,9 +1,13 @@
1
- """
 
 
 
 
2
  ═══════════════════════════════════════════════════════════════════════════════
3
- PROFESSIONAL RED TEAM WEB RECONNAISSANCE FRAMEWORK v2.0
4
  ─────────────────────────────────────────────────────────────────────────
5
- Advanced Web Application Security Assessment Tool
6
- Features: OSINT, Active Recon, Threat Modeling, STRIDE, MITRE ATT&CK
7
  ═══════════════════════════════════════════════════════════════════════════════
8
  """
9
 
@@ -28,6 +32,10 @@ import plotly.graph_objects as go
28
  import plotly.express as px
29
  from io import BytesIO
30
  import base64
 
 
 
 
31
 
32
  # ════════════════════════════════════════════════════════════════════════════
33
  # SECTION 1: CONFIGURATION & CONSTANTS
@@ -81,41 +89,131 @@ STRIDE_THREATS = {
81
  }
82
  }
83
 
84
- # Technology fingerprints
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  TECH_FINGERPRINTS = {
86
  "Web Servers": {
87
  "Apache": [r"Server: Apache", r"X-Powered-By: Apache"],
88
  "Nginx": [r"Server: nginx", r"X-Nginx"],
89
  "IIS": [r"Server: Microsoft-IIS"],
90
- "Cloudflare": [r"CF-RAY", r"Cloudflare"]
 
 
91
  },
92
  "CMS": {
93
  "WordPress": [r"/wp-admin", r"wp-content", r"wp_.*"],
94
- "Drupal": [r"/sites/default", r"drupal\.css"],
95
- "Joomla": [r"/administrator", r"com_content"]
 
 
96
  },
97
  "Frameworks": {
98
  "Django": [r"CSRF", r"django_session"],
99
  "Flask": [r"werkzeug", r"Flask"],
100
  "Laravel": [r"XSRF-TOKEN", r"laravel_session"],
101
- "Spring": [r"JSESSIONID", r"spring"]
 
 
102
  },
103
  "JavaScript": {
104
- "React": [r"__REACT", r"react\.js"],
105
- "Vue": [r"__VUE", r"vue\.js"],
106
- "Angular": [r"ng-app", r"angular\.js"]
 
 
 
 
 
 
 
 
107
  }
108
  }
109
 
110
- # Vulnerability database (simplified)
111
- VULNERABILITY_DATABASE = {
112
- "wordpress_plugins": {"severity": "HIGH", "avg_cvss": 7.5},
113
- "outdated_framework": {"severity": "HIGH", "avg_cvss": 7.8},
114
- "exposed_api": {"severity": "CRITICAL", "avg_cvss": 9.2},
115
- "sql_injection": {"severity": "CRITICAL", "avg_cvss": 9.9},
116
- "xss": {"severity": "HIGH", "avg_cvss": 6.1},
 
 
117
  }
118
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  # ════════════════════════════════════════════════════════════════════════════
120
  # SECTION 2: DATA MODELS
121
  # ════════════════════════════════════════════════════════════════════════════
@@ -123,9 +221,9 @@ VULNERABILITY_DATABASE = {
123
  @dataclass
124
  class IntelligenceIndicator:
125
  """IOC - Indicator of Compromise"""
126
- type: str # domain, subdomain, ip, email, tech, endpoint
127
  value: str
128
- confidence: float # 0.0-1.0
129
  source: str
130
  timestamp: str
131
  metadata: Optional[Dict] = None
@@ -139,6 +237,8 @@ class ThreatVector:
139
  techniques: List[str]
140
  description: str
141
  cvss_score: Optional[float] = None
 
 
142
 
143
  @dataclass
144
  class AttackPath:
@@ -147,7 +247,31 @@ class AttackPath:
147
  intermediate_steps: List[str]
148
  objective: str
149
  risk_level: str
150
- complexity: float # 0.0 to 1.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
  # ════════════════════════════════════════════════════════════════════════════
153
  # SECTION 3: STEALTH & OPSEC ENGINE
@@ -174,12 +298,16 @@ class StealthConfig:
174
  }
175
 
176
  self.user_agents = [
177
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
178
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
179
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
180
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
181
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15"
 
182
  ]
 
 
 
183
 
184
  def get_delay(self) -> float:
185
  """Random delay to avoid pattern detection"""
@@ -188,16 +316,29 @@ class StealthConfig:
188
 
189
  def get_headers(self) -> Dict[str, str]:
190
  """Anti-fingerprinting headers"""
191
- return {
192
  "User-Agent": random.choice(self.user_agents),
193
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
194
  "Accept-Encoding": random.choice(["gzip, deflate", "gzip, deflate, br"]),
195
- "Accept-Language": random.choice(["en-US,en;q=0.9", "en-US,en;q=0.9,pt;q=0.8"]),
196
  "Cache-Control": "no-cache",
197
  "DNT": "1",
198
  "Connection": "keep-alive",
199
- "Upgrade-Insecure-Requests": "1"
 
 
 
 
200
  }
 
 
 
 
 
 
 
 
 
201
 
202
  # ════════════════════════════════════════════════════════════════════════════
203
  # SECTION 4: PASSIVE OSINT ENGINE
@@ -212,7 +353,7 @@ class PassiveOSINTEngine:
212
  self.logger = self._setup_logging()
213
 
214
  def _setup_logging(self):
215
- logging.basicConfig(level=logging.INFO)
216
  return logging.getLogger("PassiveOSINT")
217
 
218
  async def gather_dns_intel(self, domain: str) -> Dict:
@@ -221,7 +362,10 @@ class PassiveOSINTEngine:
221
  "subdomains": [],
222
  "mx_records": [],
223
  "ns_records": [],
224
- "txt_records": []
 
 
 
225
  }
226
 
227
  try:
@@ -230,7 +374,9 @@ class PassiveOSINTEngine:
230
  # Try common subdomains
231
  common_subs = [
232
  "www", "mail", "ftp", "admin", "api", "dev", "staging",
233
- "cdn", "test", "blog", "shop", "support", "docs", "app"
 
 
234
  ]
235
 
236
  for sub in common_subs:
@@ -240,7 +386,20 @@ class PassiveOSINTEngine:
240
  for rdata in result:
241
  intel["subdomains"].append({
242
  "subdomain": full_domain,
243
- "ip": str(rdata)
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  })
245
  except:
246
  pass
@@ -248,7 +407,14 @@ class PassiveOSINTEngine:
248
  # MX records
249
  try:
250
  mx = dns.resolver.resolve(domain, 'MX')
251
- intel["mx_records"] = [str(r) for r in mx]
 
 
 
 
 
 
 
252
  except:
253
  pass
254
 
@@ -266,15 +432,17 @@ class PassiveOSINTEngine:
266
 
267
  async def gather_ssl_cert_intel(self, domain: str) -> Dict:
268
  """SSL certificate analysis for subdomains"""
269
- import ssl
270
- import socket
271
-
272
  cert_intel = {
273
  "subject": None,
274
  "issuer": None,
275
  "valid_from": None,
276
  "valid_to": None,
277
- "subjectAltNames": []
 
 
 
 
 
278
  }
279
 
280
  try:
@@ -282,11 +450,23 @@ class PassiveOSINTEngine:
282
  with socket.create_connection((domain, 443), timeout=5) as sock:
283
  with context.wrap_socket(sock, server_hostname=domain) as ssock:
284
  cert = ssock.getpeercert()
 
 
285
 
286
  cert_intel["subject"] = dict(x[0] for x in cert['subject'])
287
  cert_intel["issuer"] = dict(x[0] for x in cert['issuer'])
288
  cert_intel["valid_from"] = cert['notBefore']
289
  cert_intel["valid_to"] = cert['notAfter']
 
 
 
 
 
 
 
 
 
 
290
 
291
  # Extract SANs
292
  for alt_name in cert.get('subjectAltName', []):
@@ -297,15 +477,38 @@ class PassiveOSINTEngine:
297
 
298
  return cert_intel
299
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  async def github_reconnaissance(self, org_name: str) -> Dict:
301
  """Search GitHub for organization info"""
302
  github_intel = {
303
  "repositories": [],
304
  "leaked_patterns": [],
305
- "technology_hints": []
 
 
306
  }
307
 
308
  try:
 
309
  endpoint = f"https://api.github.com/users/{org_name}/repos"
310
  headers = self.config.get_headers()
311
 
@@ -313,403 +516,50 @@ class PassiveOSINTEngine:
313
  async with session.get(endpoint, headers=headers, timeout=10) as resp:
314
  if resp.status == 200:
315
  repos = await resp.json()
316
- for repo in repos[:10]: # Limit to 10
317
  github_intel["repositories"].append({
318
  "name": repo.get("name"),
319
  "url": repo.get("html_url"),
320
  "description": repo.get("description"),
321
- "language": repo.get("language")
 
 
 
322
  })
323
 
324
  if repo.get("language"):
325
  github_intel["technology_hints"].append(repo.get("language"))
326
- except Exception as e:
327
- self.logger.error(f"GitHub recon failed: {e}")
328
-
329
- return github_intel
330
-
331
- async def exposed_data_check(self, domain: str) -> List[Dict]:
332
- """Check if domain in breach databases"""
333
- breaches = []
334
-
335
- try:
336
- # HIBP-like check (public API)
337
- endpoint = f"https://haveibeenpwned.com/api/v3/breachedaccount/{domain}"
338
- headers = {"User-Agent": "RedTeamFramework/2.0"}
339
-
340
- resp = requests.get(endpoint, headers=headers, timeout=5)
341
- if resp.status_code == 200:
342
- breaches = resp.json()
343
- except:
344
- pass
345
-
346
- return breaches
347
-
348
- # ════════════════════════════════════════════════════════════════════════════
349
- # SECTION 5: ACTIVE RECONNAISSANCE ENGINE
350
- # ════════════════════════════��═══════════════════════════════════════════════
351
-
352
- class ActiveReconEngine:
353
- """Active scanning with OPSEC measures"""
354
-
355
- def __init__(self, config: StealthConfig):
356
- self.config = config
357
- self.findings = []
358
- self.logger = logging.getLogger("ActiveRecon")
359
-
360
- async def fingerprint_technologies(self, url: str) -> List[str]:
361
- """Identify technologies from headers, HTML, JS"""
362
- technologies = []
363
-
364
- try:
365
- headers = self.config.get_headers()
366
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False)
367
-
368
- # Server header analysis
369
- if "Server" in resp.headers:
370
- server = resp.headers["Server"]
371
- if "Apache" in server:
372
- technologies.append("Apache")
373
- if "nginx" in server:
374
- technologies.append("Nginx")
375
- if "IIS" in server:
376
- technologies.append("IIS")
377
-
378
- # X-Powered-By
379
- if "X-Powered-By" in resp.headers:
380
- technologies.append(resp.headers["X-Powered-By"])
381
-
382
- content = resp.text
383
-
384
- # CMS/Framework detection
385
- patterns = {
386
- "WordPress": r"wp-content|wp-includes|/wp-admin",
387
- "Drupal": r"sites/default/files|drupal\.css",
388
- "Joomla": r"Joomla|com_content",
389
- "Django": r"Django|csrf",
390
- "Flask": r"Flask|werkzeug",
391
- "React": r"__REACT_DEVTOOLS__|react\.js",
392
- "Vue": r"__VUE__|vue\.js",
393
- "Angular": r"ng-app|angular\.js"
394
- }
395
-
396
- for tech, pattern in patterns.items():
397
- if re.search(pattern, content, re.IGNORECASE):
398
- technologies.append(tech)
399
-
400
- except Exception as e:
401
- self.logger.error(f"Fingerprinting failed: {e}")
402
-
403
- return list(set(technologies))
404
-
405
- async def discover_endpoints(self, url: str, wordlist: List[str]) -> List[Dict]:
406
- """Endpoint discovery with smart filtering"""
407
- discovered = []
408
-
409
- for path in wordlist[:50]: # Limit wordlist
410
- try:
411
- full_url = f"https://{url.rstrip('/')}/{path.lstrip('/')}"
412
- headers = self.config.get_headers()
413
-
414
- await asyncio.sleep(self.config.get_delay())
415
-
416
- resp = requests.get(full_url, headers=headers, timeout=5, verify=False, allow_redirects=False)
417
-
418
- if resp.status_code in [200, 301, 302, 401, 403]:
419
- discovered.append({
420
- "path": path,
421
- "status": resp.status_code,
422
- "size": len(resp.text)
423
- })
424
- except:
425
- pass
426
-
427
- return discovered
428
-
429
- async def analyze_forms(self, url: str) -> List[Dict]:
430
- """Form detection and analysis"""
431
- forms = []
432
-
433
- try:
434
- headers = self.config.get_headers()
435
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False)
436
- soup = BeautifulSoup(resp.text, 'html.parser')
437
-
438
- for form in soup.find_all('form'):
439
- form_data = {
440
- "action": form.get('action', ''),
441
- "method": form.get('method', 'GET').upper(),
442
- "fields": []
443
- }
444
-
445
- for field in form.find_all(['input', 'textarea', 'select']):
446
- form_data["fields"].append({
447
- "name": field.get('name', ''),
448
- "type": field.get('type', 'text')
449
- })
450
-
451
- forms.append(form_data)
452
-
453
- except Exception as e:
454
- self.logger.error(f"Form analysis failed: {e}")
455
-
456
- return forms
457
-
458
- async def extract_javascript_endpoints(self, url: str) -> List[str]:
459
- """Extract API endpoints from JavaScript"""
460
- endpoints = []
461
-
462
- try:
463
- headers = self.config.get_headers()
464
- resp = requests.get(f"https://{url}", headers=headers, timeout=10, verify=False)
465
-
466
- # Find all script tags
467
- soup = BeautifulSoup(resp.text, 'html.parser')
468
-
469
- for script in soup.find_all('script'):
470
- if script.string:
471
- # Find API-like patterns
472
- api_pattern = r'["\']/(api|v[0-9]|rest)/[^"\'\s]+["\']'
473
- matches = re.findall(api_pattern, script.string)
474
- endpoints.extend(matches)
475
-
476
- content = resp.text
477
- api_urls = re.findall(r'(https?://[^\s"\']+/api/[^\s"\']+)', content)
478
- endpoints.extend(api_urls)
479
-
480
- except Exception as e:
481
- self.logger.error(f"JS extraction failed: {e}")
482
-
483
- return list(set(endpoints))
484
-
485
- # ════════════════════════════════════════════════════════════════════════════
486
- # SECTION 6: THREAT MODELING ENGINE (STRIDE + MITRE ATT&CK)
487
- # ════════════════════════════════════════════════════════════════════════════
488
-
489
- class ThreatModelingEngine:
490
- """Advanced threat modeling"""
491
-
492
- def __init__(self):
493
- self.threats: List[Dict] = []
494
- self.attack_paths: List[AttackPath] = []
495
-
496
- def analyze_web_app(self, recon_data: Dict) -> List[ThreatVector]:
497
- """Map reconnaissance to threats"""
498
- threat_vectors = []
499
-
500
- # Forms = injection vectors
501
- for form in recon_data.get("forms", []):
502
- threat_vectors.append(ThreatVector(
503
- category="web_form",
504
- location=form.get("action", ""),
505
- risk_score=7.5,
506
- techniques=["T1565.001", "T1598.003"],
507
- description=f"Form {form.get('action')}: SQL Injection, XSS potential",
508
- cvss_score=7.5
509
- ))
510
-
511
- # JavaScript = gadget chains
512
- for js_file in recon_data.get("js_files", []):
513
- threat_vectors.append(ThreatVector(
514
- category="js_gadget",
515
- location=js_file,
516
- risk_score=5.0,
517
- techniques=["T1195.001"],
518
- description=f"JavaScript gadget chain: {js_file}",
519
- cvss_score=5.0
520
- ))
521
-
522
- # API endpoints = information disclosure
523
- for endpoint in recon_data.get("endpoints", []):
524
- threat_vectors.append(ThreatVector(
525
- category="api_endpoint",
526
- location=endpoint,
527
- risk_score=6.5,
528
- techniques=["T1526"],
529
- description=f"API endpoint: {endpoint}",
530
- cvss_score=6.5
531
- ))
532
-
533
- return threat_vectors
534
-
535
- def build_attack_paths(self, threat_vectors: List[ThreatVector], technologies: List[str]) -> List[AttackPath]:
536
- """Generate attack chains"""
537
- paths = []
538
-
539
- # Generic attack path
540
- paths.append(AttackPath(
541
- entry_point="Public web form or API endpoint",
542
- intermediate_steps=[
543
- "Reconnaissance (technology fingerprinting)",
544
- "Vulnerability identification (SQLi, XSS, CSRF)",
545
- "Exploitation",
546
- "Data exfiltration or lateral movement"
547
- ],
548
- objective="Unauthorized access / Data breach",
549
- risk_level="CRITICAL",
550
- complexity=0.6
551
- ))
552
-
553
- # WordPress-specific
554
- if "WordPress" in technologies:
555
- paths.append(AttackPath(
556
- entry_point="WordPress admin panel",
557
- intermediate_steps=[
558
- "Plugin enumeration",
559
- "Known CVE exploitation",
560
- "Plugin upload for RCE",
561
- "Server compromise"
562
- ],
563
- objective="Remote Code Execution",
564
- risk_level="CRITICAL",
565
- complexity=0.4
566
- ))
567
-
568
- return paths
569
-
570
- def generate_stride_report(self, recon_data: Dict) -> Dict:
571
- """Generate STRIDE threat model"""
572
- stride_report = {}
573
-
574
- for threat_category, threat_info in STRIDE_THREATS.items():
575
- stride_report[threat_category] = {
576
- "description": threat_info["description"],
577
- "potential_impacts": [],
578
- "mitigations": threat_info["mitigations"]
579
- }
580
-
581
- # Match with found vulnerabilities
582
- if "forms" in recon_data and len(recon_data["forms"]) > 0:
583
- if threat_category == "Tampering":
584
- stride_report[threat_category]["potential_impacts"].append(
585
- "SQL Injection in form fields"
586
- )
587
 
588
- if "endpoints" in recon_data and len(recon_data["endpoints"]) > 0:
589
- if threat_category == "InformationDisclosure":
590
- stride_report[threat_category]["potential_impacts"].append(
591
- "Sensitive data exposed via API endpoints"
592
- )
593
-
594
- return stride_report
 
 
 
 
595
 
596
- # ════════════════════════════════════════════════════════════════════════════
597
- # SECTION 7: ATTACK GRAPH VISUALIZATION (ENHANCED)
598
- # ════════════════════════════════════════════════════════════════════════════
 
 
 
 
599
 
600
- class AttackGraphEngine:
601
- """Advanced attack surface visualization"""
602
-
603
- @staticmethod
604
- def create_enhanced_attack_graph(threat_vectors: List[ThreatVector],
605
- attack_paths: List[AttackPath]) -> Dict:
606
- """Build graph with threat vectors and attack paths"""
607
-
608
- nodes = ["Attacker", "Internet", "Target Domain"]
609
- edges = [("Attacker", "Internet"), ("Internet", "Target Domain")]
610
- node_info = {
611
- "Attacker": {"type": "attacker", "risk": 10},
612
- "Internet": {"type": "network", "risk": 5},
613
- "Target Domain": {"type": "asset", "risk": 7}
614
- }
615
-
616
- # Add threat vectors as nodes
617
- for i, vector in enumerate(threat_vectors[:10]):
618
- node_name = f"{vector.category.replace('_', ' ')}_{i}"
619
- nodes.append(node_name)
620
- edges.append(("Target Domain", node_name))
621
- node_info[node_name] = {
622
- "type": "vulnerability",
623
- "risk": vector.risk_score,
624
- "cvss": vector.cvss_score
625
- }
626
-
627
- return {
628
- "nodes": nodes,
629
- "edges": edges,
630
- "node_info": node_info,
631
- "threat_vectors": [asdict(v) for v in threat_vectors],
632
- "attack_paths": [asdict(ap) for ap in attack_paths]
633
- }
634
-
635
- @staticmethod
636
- def visualize_attack_graph_plotly(graph_data: Dict) -> go.Figure:
637
- """Create interactive Plotly visualization"""
638
-
639
- G = nx.DiGraph()
640
- G.add_edges_from(graph_data["edges"])
641
- pos = nx.spring_layout(G, k=2, iterations=50, seed=42)
642
-
643
- # Edge traces
644
- edge_x, edge_y = [], []
645
- for edge in G.edges():
646
- x0, y0 = pos[edge[0]]
647
- x1, y1 = pos[edge[1]]
648
- edge_x.extend([x0, x1, None])
649
- edge_y.extend([y0, y1, None])
650
-
651
- edge_trace = go.Scatter(
652
- x=edge_x, y=edge_y,
653
- line=dict(width=2, color='#888'),
654
- hoverinfo='none',
655
- mode='lines',
656
- name='Relationships'
657
- )
658
-
659
- # Node traces with risk coloring
660
- node_x, node_y, node_text, node_color, node_size = [], [], [], [], []
661
-
662
- for node in G.nodes():
663
- x, y = pos[node]
664
- node_x.append(x)
665
- node_y.append(y)
666
- node_text.append(node)
667
-
668
- node_info = graph_data["node_info"].get(node, {})
669
- risk = node_info.get("risk", 5)
670
-
671
- # Color by risk
672
- if risk >= 8:
673
- node_color.append('#ff0000') # Red - Critical
674
- elif risk >= 6:
675
- node_color.append('#ff7700') # Orange - High
676
- elif risk >= 4:
677
- node_color.append('#ffff00') # Yellow - Medium
678
- else:
679
- node_color.append('#00ff00') # Green - Low
680
-
681
- node_size.append(30 + (risk * 2))
682
-
683
- node_trace = go.Scatter(
684
- x=node_x, y=node_y,
685
- mode='markers+text',
686
- hoverinfo='text',
687
- text=node_text,
688
- textposition="top center",
689
- marker=dict(
690
- size=node_size,
691
- color=node_color,
692
- line_width=2,
693
- line=dict(color='#222')
694
- ),
695
- name='Assets/Threats'
696
- )
697
-
698
- fig = go.Figure(data=[edge_trace, node_trace])
699
- fig.update_layout(
700
- title='🎯 Advanced Attack Surface Graph',
701
- titlefont=dict(size=20, color='#ff0000'),
702
- showlegend=True,
703
- hovermode='closest',
704
- margin=dict(b=20, l=5, r=5, t=40),
705
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
706
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
707
- plot_bgcolor='#1a1a1a',
708
- paper_bgcolor='#1a1a1a',
709
- font=dict(color='#ffffff')
710
- )
711
-
712
- return fig
713
 
714
  # ════════════════════════════════════════════════════════════════════════════
715
  # SECTION 8: COMPREHENSIVE REPORTING ENGINE
@@ -720,42 +570,82 @@ class ReportingEngine:
720
 
721
  @staticmethod
722
  def generate_assessment_report(target: str, recon_data: Dict, threat_vectors: List[ThreatVector],
723
- attack_paths: List[AttackPath], stride_report: Dict) -> str:
 
724
  """Generate comprehensive assessment report"""
725
 
 
 
726
  report = f"""
727
  ╔════════════════════════════════════════════════════════════════════════╗
728
  ║ PROFESSIONAL SECURITY ASSESSMENT REPORT ║
729
  ║ [CONFIDENTIAL] ║
 
730
  ╚════════════════════════════════════════════════════════════════════════╝
731
 
732
  EXECUTIVE SUMMARY
733
  ─────────────────────────────────────────────────────────────────────────
734
  Target: {target}
735
  Assessment Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
736
- Assessed By: Red Team Framework v2.0
737
  Classification: CONFIDENTIAL
 
738
 
739
  RISK OVERVIEW
740
  ─────────────────────────────────────────────────────────────────────────
741
- Critical Findings: {len([t for t in threat_vectors if t.cvss_score and t.cvss_score >= 9.0])}
742
- High Findings: {len([t for t in threat_vectors if t.cvss_score and 7.0 <= t.cvss_score < 9.0])}
743
- Medium Findings: {len([t for t in threat_vectors if t.cvss_score and 4.0 <= t.cvss_score < 7.0])}
744
- Low Findings: {len([t for t in threat_vectors if t.cvss_score and t.cvss_score < 4.0])}
745
 
746
- Overall Risk Level: {"🔴 CRITICAL" if len([t for t in threat_vectors if t.cvss_score and t.cvss_score >= 9.0]) > 0 else "🟠 HIGH" if len([t for t in threat_vectors if t.cvss_score and t.cvss_score >= 7.0]) > 0 else "🟡 MEDIUM"}
747
 
748
  ATTACK SURFACE
749
  ─────────────────────────────────────────────────────────────────────────
750
- Technologies Identified: {len(recon_data.get('technologies', []))}
751
  API Endpoints: {len(recon_data.get('endpoints', []))}
752
  Forms Discovered: {len(recon_data.get('forms', []))}
753
  Subdomains Found: {len(recon_data.get('subdomains', []))}
754
- Exposed Services: {len(recon_data.get('exposed_services', []))}
 
755
 
756
  TECHNOLOGIES DETECTED
757
  ─────────────────────────────────────────────────────────────────────────
758
- {', '.join(recon_data.get('technologies', ['None detected']))}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
 
760
  THREAT VECTORS
761
  ─────────────────────────────────────────────────────────────────────────
@@ -767,8 +657,10 @@ THREAT VECTORS
767
  Location: {vector.location}
768
  Risk Score: {vector.risk_score}/10
769
  CVSS Score: {vector.cvss_score if vector.cvss_score else 'N/A'}
 
770
  MITRE ATT&CK: {', '.join(vector.techniques)}
771
  Description: {vector.description}
 
772
  """
773
 
774
  report += f"""
@@ -780,9 +672,18 @@ STRIDE THREAT MODEL
780
  for threat_type, threat_data in stride_report.items():
781
  report += f"""
782
  {threat_type}:
 
783
  Description: {threat_data['description']}
784
- Mitigations: {', '.join(threat_data['mitigations'])}
785
  """
 
 
 
 
 
 
 
 
786
 
787
  report += f"""
788
 
@@ -796,46 +697,191 @@ Attack Path {i}: {path.objective}
796
  Entry Point: {path.entry_point}
797
  Complexity: {path.complexity}/1.0
798
  Risk Level: {path.risk_level}
 
799
  Steps:
800
  """
801
  for step in path.intermediate_steps:
802
- report += f" → {step}\n"
803
 
804
  report += """
805
 
806
  RECOMMENDATIONS
807
  ─────────────────────────────────────────────────────────────────────────
808
- 1. IMMEDIATE (Critical):
809
- - Patch all critical CVEs
810
- - Enable WAF rules
811
- - Implement rate limiting
812
- - Enable security headers (CSP, X-Frame-Options, etc.)
 
813
 
814
- 2. SHORT-TERM (High):
815
- - Update outdated technologies
816
- - Implement input validation
817
- - Enable HTTPS enforcement
818
- - Setup security monitoring
 
819
 
820
- 3. LONG-TERM (Medium):
821
- - Implement secure SDLC
822
- - Regular security training
823
- - Penetration testing program
824
- - Bug bounty program
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
825
 
826
  METHODOLOGY
827
  ─────────────────────────────────────────────────────────────────────────
828
- 1. Passive OSINT: DNS records, SSL certificates, public databases
829
- 2. Active Reconnaissance: Technology fingerprinting, endpoint discovery
830
- 3. Threat Modeling: STRIDE analysis, attack path mapping
831
- 4. Risk Assessment: CVSS scoring, impact analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
832
 
833
  ═══════════════════════════════════════════════════════════════════════════
834
  Report Generated: {datetime.now().isoformat()}
835
  Classification: CONFIDENTIAL - DO NOT DISTRIBUTE
 
836
  ═══════════════════��═══════════════════════════════════════════════════════
837
  """
838
  return report
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
839
 
840
  # ════════════════════════════════════════════════════════════════════════════
841
  # SECTION 9: MAIN ORCHESTRATOR
@@ -859,10 +905,12 @@ class RedTeamReconFramework:
859
  "target": target_url,
860
  "timestamp": datetime.now().isoformat(),
861
  "subdomains": [],
862
- "technologies": [],
863
  "endpoints": [],
864
  "forms": [],
865
  "js_files": [],
 
 
866
  "threat_vectors": [],
867
  "attack_paths": [],
868
  "stride_analysis": {},
@@ -872,6 +920,7 @@ class RedTeamReconFramework:
872
 
873
  try:
874
  # PHASE 1: Passive OSINT
 
875
  passive_data = await self.passive_engine.gather_dns_intel(target_url)
876
  results["subdomains"] = passive_data.get("subdomains", [])
877
 
@@ -882,18 +931,27 @@ class RedTeamReconFramework:
882
  for san in ssl_data["subjectAltNames"]
883
  ])
884
 
 
 
 
 
 
 
 
885
  github_data = await self.passive_engine.github_reconnaissance(target_url.replace(".com", ""))
886
  results["github_intel"] = github_data
887
 
 
 
 
 
888
  # PHASE 2: Active Reconnaissance
 
889
  technologies = await self.active_engine.fingerprint_technologies(target_url)
890
  results["technologies"] = technologies
891
 
892
- endpoints = await self.active_engine.discover_endpoints(target_url, [
893
- "", "admin", "api", "login", "test", "debug", "config",
894
- "api/users", "api/admin", "api/auth", "api/data"
895
- ])
896
- results["endpoints"] = [e["path"] for e in endpoints]
897
 
898
  forms = await self.active_engine.analyze_forms(target_url)
899
  results["forms"] = forms
@@ -901,7 +959,16 @@ class RedTeamReconFramework:
901
  js_endpoints = await self.active_engine.extract_javascript_endpoints(target_url)
902
  results["js_files"] = js_endpoints
903
 
904
- # PHASE 3: Threat Modeling
 
 
 
 
 
 
 
 
 
905
  threat_vectors = self.threat_model.analyze_web_app(results)
906
  results["threat_vectors"] = [asdict(tv) for tv in threat_vectors]
907
 
@@ -911,19 +978,27 @@ class RedTeamReconFramework:
911
  stride_analysis = self.threat_model.generate_stride_report(results)
912
  results["stride_analysis"] = stride_analysis
913
 
914
- # PHASE 4: Attack Graph
915
- graph_data = self.graph_engine.create_enhanced_attack_graph(threat_vectors, attack_paths)
 
 
 
916
  results["graph_data"] = graph_data
917
 
918
- # PHASE 5: Reporting
 
919
  report = self.reporting.generate_assessment_report(
920
- target_url, results, threat_vectors, attack_paths, stride_analysis
921
  )
922
  results["report"] = report
923
 
 
 
924
  except Exception as e:
925
  results["error"] = str(e)
926
  logging.error(f"Assessment failed: {e}")
 
 
927
 
928
  return results
929
 
@@ -938,6 +1013,12 @@ def run_assessment(target_url: str, threat_level: str, progress=gr.Progress(trac
938
  """Gradio wrapper function"""
939
 
940
  try:
 
 
 
 
 
 
941
  progress(0.1, desc="🔍 Validating target...")
942
 
943
  # Update threat level
@@ -967,115 +1048,21 @@ def run_assessment(target_url: str, threat_level: str, progress=gr.Progress(trac
967
  else:
968
  fig = go.Figure()
969
 
 
 
 
 
 
 
970
  # Summary
971
  summary = f"""
972
  ## 🔴 ASSESSMENT COMPLETE
973
 
974
  **Target:** {target_url}
975
- **Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
 
976
 
977
  ### Quick Stats
978
  - 🌐 Subdomains: {len(results.get('subdomains', []))}
979
- - 🔧 Technologies: {len(results.get('technologies', []))}
980
- - 📍 Endpoints: {len(results.get('endpoints', []))}
981
- - 📝 Forms: {len(results.get('forms', []))}
982
- - ⚠️ Threat Vectors: {len(results.get('threat_vectors', []))}
983
- - 🎯 Attack Paths: {len(results.get('attack_paths', []))}
984
-
985
- ### Risk Assessment
986
- - **Critical:** {len([t for t in results.get('threat_vectors', []) if t.get('cvss_score', 0) >= 9.0])}
987
- - **High:** {len([t for t in results.get('threat_vectors', []) if 7.0 <= t.get('cvss_score', 0) < 9.0])}
988
- - **Medium:** {len([t for t in results.get('threat_vectors', []) if 4.0 <= t.get('cvss_score', 0) < 7.0])}
989
-
990
- ### Technologies Detected
991
- {', '.join(results.get('technologies', ['None']))}
992
- """
993
-
994
- return (
995
- summary,
996
- json.dumps(results, indent=2, default=str),
997
- fig,
998
- results.get("report", "No report generated")
999
- )
1000
-
1001
- except Exception as e:
1002
- error_msg = f"Error: {str(e)}"
1003
- return error_msg, "{}", go.Figure(), error_msg
1004
-
1005
- # ════════════════════════════════════════════════════════════════════════════
1006
- # GRADIO UI DEFINITION
1007
- # ══════════════��═════════════════════════════════════════════════════════════
1008
-
1009
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="red"), title="Red Team Recon Framework") as demo:
1010
- gr.Markdown("""
1011
- # 🛡️ RED TEAM ADVANCED WEB RECONNAISSANCE FRAMEWORK v2.0
1012
- ### Professional Security Assessment Tool
1013
-
1014
- **Features:**
1015
- - 🕵️ Passive OSINT (DNS, SSL, GitHub, Breach databases)
1016
- - 📡 Active Reconnaissance (Fingerprinting, endpoint discovery)
1017
- - 🎯 Threat Modeling (STRIDE + MITRE ATT&CK)
1018
- - 📊 Advanced Attack Surface Visualization
1019
- - 📝 Professional Reporting (CVSS, ATT&CK TID)
1020
-
1021
- ⚠️ **DISCLAIMER:** Authorized testing only. Unauthorized access is illegal.
1022
- """)
1023
-
1024
- with gr.Row():
1025
- with gr.Column(scale=1):
1026
- target_input = gr.Textbox(
1027
- label="Target Domain",
1028
- placeholder="example.com",
1029
- info="Enter target domain (without https://)"
1030
- )
1031
-
1032
- threat_level = gr.Radio(
1033
- choices=["Low (Stealthy)", "Medium (Balanced)", "High (Aggressive)"],
1034
- value="Medium (Balanced)",
1035
- label="Threat Level / Scan Intensity"
1036
- )
1037
-
1038
- scan_button = gr.Button("🚀 START ASSESSMENT", variant="primary", size="lg")
1039
-
1040
- with gr.Column(scale=1):
1041
- gr.Markdown("""
1042
- ### How It Works
1043
-
1044
- 1. **Passive OSINT**: DNS records, SSL certs, public data
1045
- 2. **Active Recon**: Technology fingerprinting
1046
- 3. **Threat Modeling**: STRIDE + MITRE ATT&CK
1047
- 4. **Risk Analysis**: CVSS scoring
1048
- 5. **Reporting**: Executive + technical reports
1049
- """)
1050
-
1051
- with gr.Tabs():
1052
- with gr.Tab("📊 Summary"):
1053
- summary_output = gr.Markdown(label="Assessment Summary")
1054
-
1055
- with gr.Tab("📈 Attack Graph"):
1056
- graph_output = gr.Plot(label="Attack Surface Visualization")
1057
-
1058
- with gr.Tab("🔍 Raw Data"):
1059
- json_output = gr.Code(language="json", label="Detailed Findings (JSON)")
1060
-
1061
- with gr.Tab("📋 Full Report"):
1062
- report_output = gr.Textbox(
1063
- label="Security Assessment Report",
1064
- lines=30,
1065
- max_lines=100,
1066
- interactive=False
1067
- )
1068
-
1069
- # Button click handler
1070
- scan_button.click(
1071
- fn=run_assessment,
1072
- inputs=[target_input, threat_level],
1073
- outputs=[summary_output, json_output, graph_output, report_output]
1074
- )
1075
-
1076
- # ════════════════════════════════════════════════════════════════════════════
1077
- # LAUNCH
1078
- # ════════════════════════════════════════════════════════════════════════════
1079
-
1080
- if __name__ == "__main__":
1081
- demo.launch(share=True, server_name="0.0.0.0", server_port=7860)
 
1
+
2
+ # BÖLÜM 1: KODUN 1-7. BÖLÜMLERİ
3
+ # Bu dosyayı app_part1.py olarak kaydedin
4
+
5
+ part1_code = '''"""
6
  ═══════════════════════════════════════════════════════════════════════════════
7
+ PRIVATE RED TEAM WEB RECONNAISSANCE FRAMEWORK v3.0 - PART 1
8
  ─────────────────────────────────────────────────────────────────────────
9
+ Bölümler: 1-7 (Configuration, Data Models, Stealth, OSINT, Active Recon,
10
+ Threat Modeling, Attack Graph)
11
  ═══════════════════════════════════════════════════════════════════════════════
12
  """
13
 
 
32
  import plotly.express as px
33
  from io import BytesIO
34
  import base64
35
+ import ssl
36
+ import socket
37
+ import subprocess
38
+ from urllib.parse import urljoin, urlparse
39
 
40
  # ════════════════════════════════════════════════════════════════════════════
41
  # SECTION 1: CONFIGURATION & CONSTANTS
 
89
  }
90
  }
91
 
92
+ # Extended MITRE ATT&CK Matrix
93
+ MITRE_TECHNIQUES = {
94
+ "Reconnaissance": {
95
+ "T1592": "Gather Victim Host Information",
96
+ "T1593": "Search Open Websites/Domains",
97
+ "T1594": "Search Victim-Owned Websites",
98
+ "T1595": "Active Scanning",
99
+ "T1596": "Search Open Technical Databases",
100
+ "T1597": "Search Closed Sources",
101
+ "T1598": "Phishing for Information"
102
+ },
103
+ "Initial Access": {
104
+ "T1190": "Exploit Public-Facing Application",
105
+ "T1199": "Trusted Relationship",
106
+ "T1566": "Phishing"
107
+ },
108
+ "Execution": {
109
+ "T1059": "Command and Scripting Interpreter",
110
+ "T1203": "Exploitation for Client Execution"
111
+ },
112
+ "Persistence": {
113
+ "T1078": "Valid Accounts",
114
+ "T1547": "Boot or Logon Autostart Execution"
115
+ },
116
+ "Privilege Escalation": {
117
+ "T1134": "Access Token Manipulation",
118
+ "T1548": "Abuse Elevation Control Mechanism"
119
+ },
120
+ "Defense Evasion": {
121
+ "T1562": "Impair Defenses",
122
+ "T1036": "Masquerading"
123
+ },
124
+ "Credential Access": {
125
+ "T1110": "Brute Force",
126
+ "T1187": "Forced Authentication"
127
+ },
128
+ "Discovery": {
129
+ "T1526": "Enumerate External Remote Systems",
130
+ "T1087": "Account Discovery"
131
+ },
132
+ "Lateral Movement": {
133
+ "T1021": "Remote Services",
134
+ "T1570": "Lateral Tool Transfer"
135
+ },
136
+ "Collection": {
137
+ "T1113": "Screen Capture",
138
+ "T1115": "Clipboard Data"
139
+ },
140
+ "Command and Control": {
141
+ "T1071": "Application Layer Protocol",
142
+ "T1572": "Protocol Tunneling"
143
+ },
144
+ "Exfiltration": {
145
+ "T1041": "Exfiltration Over C2 Channel",
146
+ "T1048": "Exfiltration Over Alternative Protocol"
147
+ },
148
+ "Impact": {
149
+ "T1531": "Account Access Removal",
150
+ "T1561": "Disk Wipe"
151
+ }
152
+ }
153
+
154
+ # Technology fingerprints - Extended
155
  TECH_FINGERPRINTS = {
156
  "Web Servers": {
157
  "Apache": [r"Server: Apache", r"X-Powered-By: Apache"],
158
  "Nginx": [r"Server: nginx", r"X-Nginx"],
159
  "IIS": [r"Server: Microsoft-IIS"],
160
+ "Cloudflare": [r"CF-RAY", r"Cloudflare"],
161
+ "AWS": [r"X-Amz", r"AmazonS3"],
162
+ "Azure": [r"Azure", r"Microsoft-IIS"]
163
  },
164
  "CMS": {
165
  "WordPress": [r"/wp-admin", r"wp-content", r"wp_.*"],
166
+ "Drupal": [r"/sites/default", r"drupal\\.css"],
167
+ "Joomla": [r"/administrator", r"com_content"],
168
+ "Magento": [r"/skin/frontend", r"Mage.Cookies"],
169
+ "Shopify": [r"cdn.shopify.com", r"Shopify.theme"]
170
  },
171
  "Frameworks": {
172
  "Django": [r"CSRF", r"django_session"],
173
  "Flask": [r"werkzeug", r"Flask"],
174
  "Laravel": [r"XSRF-TOKEN", r"laravel_session"],
175
+ "Spring": [r"JSESSIONID", r"spring"],
176
+ "Ruby on Rails": [r"_rails", r"authenticity_token"],
177
+ "ASP.NET": [r"ASP.NET_SessionId", r"__VIEWSTATE"]
178
  },
179
  "JavaScript": {
180
+ "React": [r"__REACT", r"react\\.js"],
181
+ "Vue": [r"__VUE", r"vue\\.js"],
182
+ "Angular": [r"ng-app", r"angular\\.js"],
183
+ "jQuery": [r"jquery", r"jQuery"],
184
+ "Bootstrap": [r"bootstrap", r"data-toggle"]
185
+ },
186
+ "Databases": {
187
+ "MySQL": [r"MySQL", r"sqlstate"],
188
+ "PostgreSQL": [r"PostgreSQL", r"pg_query"],
189
+ "MongoDB": [r"MongoDB", r"mongod"],
190
+ "Redis": [r"Redis", r"redis-cli"]
191
  }
192
  }
193
 
194
+ # Security Headers to check
195
+ SECURITY_HEADERS = {
196
+ "Strict-Transport-Security": "HSTS",
197
+ "Content-Security-Policy": "CSP",
198
+ "X-Frame-Options": "Clickjacking Protection",
199
+ "X-Content-Type-Options": "MIME Sniffing Protection",
200
+ "X-XSS-Protection": "XSS Filter",
201
+ "Referrer-Policy": "Referrer Control",
202
+ "Permissions-Policy": "Feature Policy"
203
  }
204
 
205
+ # Common endpoints for discovery
206
+ COMMON_ENDPOINTS = [
207
+ "", "admin", "api", "login", "test", "debug", "config",
208
+ "api/users", "api/admin", "api/auth", "api/data", "api/v1",
209
+ "wp-admin", "wp-login", "administrator", "phpmyadmin",
210
+ "robots.txt", "sitemap.xml", ".env", ".git", ".htaccess",
211
+ "backup", "db", "database", "dump", "sql", "old",
212
+ "dev", "staging", "beta", "uat", "demo",
213
+ "swagger", "api-docs", "graphql", "graphiql",
214
+ "actuator", "health", "metrics", "prometheus"
215
+ ]
216
+
217
  # ════════════════════════════════════════════════════════════════════════════
218
  # SECTION 2: DATA MODELS
219
  # ════════════════════════════════════════════════════════════════════════════
 
221
  @dataclass
222
  class IntelligenceIndicator:
223
  """IOC - Indicator of Compromise"""
224
+ type: str
225
  value: str
226
+ confidence: float
227
  source: str
228
  timestamp: str
229
  metadata: Optional[Dict] = None
 
237
  techniques: List[str]
238
  description: str
239
  cvss_score: Optional[float] = None
240
+ cwe_id: Optional[str] = None
241
+ evidence: Optional[str] = None
242
 
243
  @dataclass
244
  class AttackPath:
 
247
  intermediate_steps: List[str]
248
  objective: str
249
  risk_level: str
250
+ complexity: float
251
+ mitre_techniques: List[str] = None
252
+
253
+ def __post_init__(self):
254
+ if self.mitre_techniques is None:
255
+ self.mitre_techniques = []
256
+
257
+ @dataclass
258
+ class Vulnerability:
259
+ """Vulnerability finding"""
260
+ name: str
261
+ description: str
262
+ severity: str
263
+ cvss_score: float
264
+ cvss_vector: str
265
+ location: str
266
+ evidence: str
267
+ remediation: str
268
+ cwe_id: Optional[str] = None
269
+ owasp_category: Optional[str] = None
270
+ mitre_techniques: List[str] = None
271
+
272
+ def __post_init__(self):
273
+ if self.mitre_techniques is None:
274
+ self.mitre_techniques = []
275
 
276
  # ════════════════════════════════════════════════════════════════════════════
277
  # SECTION 3: STEALTH & OPSEC ENGINE
 
298
  }
299
 
300
  self.user_agents = [
301
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
302
+ "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",
303
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
304
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
305
+ "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",
306
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edge/120.0.0.0"
307
  ]
308
+
309
+ self.proxies = []
310
+ self.current_proxy = 0
311
 
312
  def get_delay(self) -> float:
313
  """Random delay to avoid pattern detection"""
 
316
 
317
  def get_headers(self) -> Dict[str, str]:
318
  """Anti-fingerprinting headers"""
319
+ headers = {
320
  "User-Agent": random.choice(self.user_agents),
321
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
322
  "Accept-Encoding": random.choice(["gzip, deflate", "gzip, deflate, br"]),
323
+ "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"]),
324
  "Cache-Control": "no-cache",
325
  "DNT": "1",
326
  "Connection": "keep-alive",
327
+ "Upgrade-Insecure-Requests": "1",
328
+ "Sec-Fetch-Dest": "document",
329
+ "Sec-Fetch-Mode": "navigate",
330
+ "Sec-Fetch-Site": "none",
331
+ "Sec-Fetch-User": "?1"
332
  }
333
+ return headers
334
+
335
+ def get_proxy(self) -> Optional[Dict]:
336
+ """Rotate proxies if available"""
337
+ if not self.proxies:
338
+ return None
339
+ proxy = self.proxies[self.current_proxy % len(self.proxies)]
340
+ self.current_proxy += 1
341
+ return proxy
342
 
343
  # ════════════════════════════════════════════════════════════════════════════
344
  # SECTION 4: PASSIVE OSINT ENGINE
 
353
  self.logger = self._setup_logging()
354
 
355
  def _setup_logging(self):
356
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
357
  return logging.getLogger("PassiveOSINT")
358
 
359
  async def gather_dns_intel(self, domain: str) -> Dict:
 
362
  "subdomains": [],
363
  "mx_records": [],
364
  "ns_records": [],
365
+ "txt_records": [],
366
+ "a_records": [],
367
+ "aaaa_records": [],
368
+ "cname_records": []
369
  }
370
 
371
  try:
 
374
  # Try common subdomains
375
  common_subs = [
376
  "www", "mail", "ftp", "admin", "api", "dev", "staging",
377
+ "cdn", "test", "blog", "shop", "support", "docs", "app",
378
+ "portal", "secure", "vpn", "remote", "webmail", "mx",
379
+ "ns1", "ns2", "dns", "autodiscover", "autoconfig"
380
  ]
381
 
382
  for sub in common_subs:
 
386
  for rdata in result:
387
  intel["subdomains"].append({
388
  "subdomain": full_domain,
389
+ "ip": str(rdata),
390
+ "type": "A"
391
+ })
392
+ except:
393
+ pass
394
+
395
+ # Try AAAA records
396
+ try:
397
+ full_domain = f"{sub}.{domain}"
398
+ result = dns.resolver.resolve(full_domain, 'AAAA')
399
+ for rdata in result:
400
+ intel["aaaa_records"].append({
401
+ "subdomain": full_domain,
402
+ "ipv6": str(rdata)
403
  })
404
  except:
405
  pass
 
407
  # MX records
408
  try:
409
  mx = dns.resolver.resolve(domain, 'MX')
410
+ intel["mx_records"] = [{"preference": r.preference, "exchange": str(r.exchange)} for r in mx]
411
+ except:
412
+ pass
413
+
414
+ # NS records
415
+ try:
416
+ ns = dns.resolver.resolve(domain, 'NS')
417
+ intel["ns_records"] = [str(r) for r in ns]
418
  except:
419
  pass
420
 
 
432
 
433
  async def gather_ssl_cert_intel(self, domain: str) -> Dict:
434
  """SSL certificate analysis for subdomains"""
 
 
 
435
  cert_intel = {
436
  "subject": None,
437
  "issuer": None,
438
  "valid_from": None,
439
  "valid_to": None,
440
+ "subjectAltNames": [],
441
+ "serial_number": None,
442
+ "signature_algorithm": None,
443
+ "version": None,
444
+ "expired": False,
445
+ "valid": False
446
  }
447
 
448
  try:
 
450
  with socket.create_connection((domain, 443), timeout=5) as sock:
451
  with context.wrap_socket(sock, server_hostname=domain) as ssock:
452
  cert = ssock.getpeercert()
453
+ cipher = ssock.cipher()
454
+ version = ssock.version()
455
 
456
  cert_intel["subject"] = dict(x[0] for x in cert['subject'])
457
  cert_intel["issuer"] = dict(x[0] for x in cert['issuer'])
458
  cert_intel["valid_from"] = cert['notBefore']
459
  cert_intel["valid_to"] = cert['notAfter']
460
+ cert_intel["serial_number"] = cert.get('serialNumber')
461
+ cert_intel["signature_algorithm"] = cert.get('signatureAlgorithm')
462
+ cert_intel["version"] = version
463
+ cert_intel["cipher"] = cipher
464
+
465
+ # Check expiration
466
+ from datetime import datetime
467
+ expiry = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
468
+ cert_intel["expired"] = expiry < datetime.now()
469
+ cert_intel["valid"] = True
470
 
471
  # Extract SANs
472
  for alt_name in cert.get('subjectAltName', []):
 
477
 
478
  return cert_intel
479
 
480
+ async def crt_sh_lookup(self, domain: str) -> List[str]:
481
+ """Query Certificate Transparency logs via crt.sh"""
482
+ subdomains = set()
483
+ try:
484
+ url = f"https://crt.sh/?q=%.{domain}&output=json"
485
+ headers = self.config.get_headers()
486
+
487
+ async with aiohttp.ClientSession() as session:
488
+ async with session.get(url, headers=headers, timeout=10) as resp:
489
+ if resp.status == 200:
490
+ data = await resp.json()
491
+ for entry in data:
492
+ name = entry.get('name_value', '')
493
+ if name and '*' not in name:
494
+ subdomains.add(name)
495
+ except Exception as e:
496
+ self.logger.error(f"crt.sh lookup failed: {e}")
497
+
498
+ return list(subdomains)
499
+
500
  async def github_reconnaissance(self, org_name: str) -> Dict:
501
  """Search GitHub for organization info"""
502
  github_intel = {
503
  "repositories": [],
504
  "leaked_patterns": [],
505
+ "technology_hints": [],
506
+ "members": [],
507
+ "gists": []
508
  }
509
 
510
  try:
511
+ # Search repos
512
  endpoint = f"https://api.github.com/users/{org_name}/repos"
513
  headers = self.config.get_headers()
514
 
 
516
  async with session.get(endpoint, headers=headers, timeout=10) as resp:
517
  if resp.status == 200:
518
  repos = await resp.json()
519
+ for repo in repos[:20]: # Limit to 20
520
  github_intel["repositories"].append({
521
  "name": repo.get("name"),
522
  "url": repo.get("html_url"),
523
  "description": repo.get("description"),
524
+ "language": repo.get("language"),
525
+ "stars": repo.get("stargazers_count"),
526
+ "forks": repo.get("forks_count"),
527
+ "updated": repo.get("updated_at")
528
  })
529
 
530
  if repo.get("language"):
531
  github_intel["technology_hints"].append(repo.get("language"))
532
+
533
+ # Check for common leaked patterns in repo names/descriptions
534
+ desc = (repo.get("description") or "").lower()
535
+ if any(x in desc for x in ['password', 'secret', 'key', 'token', 'credential']):
536
+ github_intel["leaked_patterns"].append({
537
+ "repo": repo.get("name"),
538
+ "pattern": "Potential secret in description"
539
+ })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
 
541
+ # Search for gists
542
+ gist_endpoint = f"https://api.github.com/users/{org_name}/gists"
543
+ async with aiohttp.ClientSession() as session:
544
+ async with session.get(gist_endpoint, headers=headers, timeout=10) as resp:
545
+ if resp.status == 200:
546
+ gists = await resp.json()
547
+ for gist in gists[:10]:
548
+ github_intel["gists"].append({
549
+ "id": gist.get("id"),
550
+ # BÖLÜM 2: KODUN 8-10. BÖLÜMLERİ
551
+ # Bu dosyayı app_part2.py olarak kaydedin
552
 
553
+ part2_code = '''"""
554
+ ═══════════════════════════════════════════════════════════════════════════════
555
+ PRIVATE RED TEAM WEB RECONNAISSANCE FRAMEWORK v3.0 - PART 2
556
+ ─────────────────────────────────────────────────────────────────────────
557
+ Bölümler: 8-10 (Reporting Engine, Main Orchestrator, Gradio Interface)
558
+ ═══════════════════════════════════════════════════════════════════════════════
559
+ """
560
 
561
+ # Part 1'deki importları ve sınıfları tekrar etmek için:
562
+ # Bu dosyayı çalıştırmadan önce Part 1'i import edin veya birleştirin
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
563
 
564
  # ════════════════════════════════════════════════════════════════════════════
565
  # SECTION 8: COMPREHENSIVE REPORTING ENGINE
 
570
 
571
  @staticmethod
572
  def generate_assessment_report(target: str, recon_data: Dict, threat_vectors: List[ThreatVector],
573
+ attack_paths: List[AttackPath], stride_report: Dict,
574
+ vulnerabilities: List[Vulnerability] = None) -> str:
575
  """Generate comprehensive assessment report"""
576
 
577
+ vulns = vulnerabilities or []
578
+
579
  report = f"""
580
  ╔════════════════════════════════════════════════════════════════════════╗
581
  ║ PROFESSIONAL SECURITY ASSESSMENT REPORT ║
582
  ║ [CONFIDENTIAL] ║
583
+ ║ PRIVATE SPACE EDITION v3.0 ║
584
  ╚════════════════════════════════════════════════════════════════════════╝
585
 
586
  EXECUTIVE SUMMARY
587
  ─────────────────────────────────────────────────────────────────────────
588
  Target: {target}
589
  Assessment Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
590
+ Assessed By: Red Team Framework v3.0 (Private Space)
591
  Classification: CONFIDENTIAL
592
+ Assessment Type: Comprehensive Web Application Security Assessment
593
 
594
  RISK OVERVIEW
595
  ─────────────────────────────────────────────────────────────────────────
596
+ Critical Findings: {len([t for t in vulns if t.cvss_score >= 9.0])}
597
+ High Findings: {len([t for t in vulns if 7.0 <= t.cvss_score < 9.0])}
598
+ Medium Findings: {len([t for t in vulns if 4.0 <= t.cvss_score < 7.0])}
599
+ Low Findings: {len([t for t in vulns if t.cvss_score < 4.0])}
600
 
601
+ 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"}
602
 
603
  ATTACK SURFACE
604
  ─────────────────────────────────────────────────────────────────────────
605
+ Technologies Identified: {len(recon_data.get('technologies', {}).get('cms', [])) + len(recon_data.get('technologies', {}).get('frameworks', []))}
606
  API Endpoints: {len(recon_data.get('endpoints', []))}
607
  Forms Discovered: {len(recon_data.get('forms', []))}
608
  Subdomains Found: {len(recon_data.get('subdomains', []))}
609
+ JavaScript Files Analyzed: {len(recon_data.get('js_files', []))}
610
+ Security Headers Score: {recon_data.get('security_headers', {}).get('score', 0):.1f}%
611
 
612
  TECHNOLOGIES DETECTED
613
  ─────────────────────────────────────────────────────────────────────────
614
+ Web Server: {recon_data.get('technologies', {}).get('web_server', 'Unknown')}
615
+ CMS: {', '.join(recon_data.get('technologies', {}).get('cms', ['None detected']))}
616
+ Frameworks: {', '.join(recon_data.get('technologies', {}).get('frameworks', ['None detected']))}
617
+ JavaScript Libraries: {', '.join(recon_data.get('technologies', {}).get('javascript', ['None detected']))}
618
+ CDN: {', '.join(recon_data.get('technologies', {}).get('cdn', ['None detected']))}
619
+
620
+ VULNERABILITY DETAILS
621
+ ─────────────────────────────────────────────────────────────────────────
622
+ """
623
+
624
+ for i, vuln in enumerate(vulns, 1):
625
+ report += f"""
626
+ [{i}] {vuln.name}
627
+ Severity: {vuln.severity}
628
+ CVSS Score: {vuln.cvss_score}
629
+ CVSS Vector: {vuln.cvss_vector}
630
+ CWE ID: {vuln.cwe_id or 'N/A'}
631
+ OWASP Category: {vuln.owasp_category or 'N/A'}
632
+ Location: {vuln.location}
633
+
634
+ Description:
635
+ {vuln.description}
636
+
637
+ Evidence:
638
+ {vuln.evidence}
639
+
640
+ Remediation:
641
+ {vuln.remediation}
642
+
643
+ MITRE ATT&CK Techniques: {', '.join(vuln.mitre_techniques)}
644
+
645
+ {'─' * 70}
646
+ """
647
+
648
+ report += f"""
649
 
650
  THREAT VECTORS
651
  ─────────────────────────────────────────────────────────────────────────
 
657
  Location: {vector.location}
658
  Risk Score: {vector.risk_score}/10
659
  CVSS Score: {vector.cvss_score if vector.cvss_score else 'N/A'}
660
+ CWE ID: {vector.cwe_id or 'N/A'}
661
  MITRE ATT&CK: {', '.join(vector.techniques)}
662
  Description: {vector.description}
663
+ Evidence: {vector.evidence or 'N/A'}
664
  """
665
 
666
  report += f"""
 
672
  for threat_type, threat_data in stride_report.items():
673
  report += f"""
674
  {threat_type}:
675
+ Risk Level: {threat_data.get('risk_level', 'LOW')}
676
  Description: {threat_data['description']}
677
+ Potential Impacts:
678
  """
679
+ for impact in threat_data.get('potential_impacts', []):
680
+ report += f" • {impact}\\n"
681
+
682
+ report += f" Affected Components:\\n"
683
+ for component in threat_data.get('affected_components', []):
684
+ report += f" • {component}\\n"
685
+
686
+ report += f" Mitigations: {', '.join(threat_data['mitigations'])}\\n"
687
 
688
  report += f"""
689
 
 
697
  Entry Point: {path.entry_point}
698
  Complexity: {path.complexity}/1.0
699
  Risk Level: {path.risk_level}
700
+ MITRE ATT&CK Techniques: {', '.join(path.mitre_techniques)}
701
  Steps:
702
  """
703
  for step in path.intermediate_steps:
704
+ report += f" → {step}\\n"
705
 
706
  report += """
707
 
708
  RECOMMENDATIONS
709
  ─────────────────────────────────────────────────────────────────────────
710
+ 1. IMMEDIATE (Critical - Fix within 24 hours):
711
+ Patch all critical CVEs (CVSS 9.0+)
712
+ Disable exposed sensitive files (.env, .git)
713
+ Enable WAF rules for SQL injection protection
714
+ Implement rate limiting on authentication endpoints
715
+ • Enable security headers (CSP, HSTS, X-Frame-Options)
716
 
717
+ 2. SHORT-TERM (High - Fix within 1 week):
718
+ Update outdated technologies and frameworks
719
+ Implement input validation on all forms
720
+ Enable HTTPS enforcement (HSTS)
721
+ Setup security monitoring and alerting
722
+ • Conduct code review for injection vulnerabilities
723
 
724
+ 3. MEDIUM-TERM (Medium - Fix within 1 month):
725
+ Implement Web Application Firewall (WAF)
726
+ Conduct penetration testing
727
+ Implement secure session management
728
+ Setup vulnerability disclosure program
729
+ • Regular security training for developers
730
+
731
+ 4. LONG-TERM (Ongoing):
732
+ • Implement Secure SDLC
733
+ • Regular automated security scanning
734
+ • Bug bounty program
735
+ • Incident response planning
736
+ • Compliance auditing (OWASP ASVS)
737
+
738
+ COMPLIANCE MAPPING
739
+ ─────────────────────────────────────────────────────────────────────────
740
+ OWASP Top 10 2021:
741
+ """
742
+
743
+ owasp_categories = defaultdict(list)
744
+ for vuln in vulns:
745
+ if vuln.owasp_category:
746
+ owasp_categories[vuln.owasp_category].append(vuln.name)
747
+
748
+ for category, vuln_list in owasp_categories.items():
749
+ report += f" {category}: {len(vuln_list)} findings\\n"
750
+ for v in vuln_list[:3]: # Limit to 3 per category
751
+ report += f" • {v}\\n"
752
+
753
+ report += f"""
754
+
755
+ MITRE ATT&CK MAPPING
756
+ ─────────────────────────────────────────────────────────────────────────
757
+ """
758
+
759
+ mitre_techniques = set()
760
+ for vuln in vulns:
761
+ mitre_techniques.update(vuln.mitre_techniques)
762
+ for path in attack_paths:
763
+ mitre_techniques.update(path.mitre_techniques)
764
+
765
+ for tech in sorted(mitre_techniques):
766
+ report += f" • {tech}"
767
+ # Add technique name if available
768
+ for category, techniques in MITRE_TECHNIQUES.items():
769
+ if tech in techniques:
770
+ report += f" - {techniques[tech]}"
771
+ break
772
+ report += "\\n"
773
+
774
+ report += f"""
775
 
776
  METHODOLOGY
777
  ─────────────────────────────────────────────────────────────────────────
778
+ 1. Passive OSINT (Non-intrusive):
779
+ DNS record enumeration (A, AAAA, MX, NS, TXT)
780
+ SSL/TLS certificate analysis
781
+ Certificate Transparency log queries (crt.sh)
782
+ • GitHub reconnaissance
783
+ • Wayback Machine historical data
784
+ • Shodan/Censys intelligence (if API available)
785
+
786
+ 2. Active Reconnaissance (Low impact):
787
+ • HTTP header analysis
788
+ • Technology fingerprinting
789
+ • Endpoint discovery
790
+ • Form analysis
791
+ • JavaScript endpoint extraction
792
+ • Security headers assessment
793
+
794
+ 3. Vulnerability Analysis:
795
+ • Pattern-based detection
796
+ • Configuration weakness identification
797
+ • Information disclosure checks
798
+ • Injection vulnerability probes (safe)
799
+
800
+ 4. Threat Modeling:
801
+ • STRIDE analysis
802
+ • Attack path generation
803
+ • MITRE ATT&CK mapping
804
+ • Risk scoring (CVSS v3.1)
805
+
806
+ 5. Reporting:
807
+ • Executive summary
808
+ • Technical findings
809
+ • Remediation guidance
810
+ • Compliance mapping
811
+
812
+ TOOLS & TECHNIQUES
813
+ ─────────────────────────────────────────────────────────────────────────
814
+ • Framework: Red Team Recon Framework v3.0
815
+ • Standards: OWASP Testing Guide, PTES, CVSS v3.1
816
+ • Threat Model: STRIDE, MITRE ATT&CK v12
817
+ • Visualization: NetworkX, Plotly
818
+ • OSINT: DNS, SSL, crt.sh, GitHub, Wayback
819
+
820
+ LIMITATIONS
821
+ ─────────────────────────────────────────────────────────────────────────
822
+ • Assessment limited to authorized scope
823
+ • No active exploitation performed
824
+ • Rate limiting may affect scan completeness
825
+ • Some checks require manual verification
826
+ • API keys needed for full OSINT features
827
 
828
  ═══════════════════════════════════════════════════════════════════════════
829
  Report Generated: {datetime.now().isoformat()}
830
  Classification: CONFIDENTIAL - DO NOT DISTRIBUTE
831
+ Private Space Assessment - Authorized Testing Only
832
  ═══════════════════��═══════════════════════════════════════════════════════
833
  """
834
  return report
835
+
836
+ @staticmethod
837
+ def generate_executive_summary(target: str, recon_data: Dict, vulnerabilities: List[Vulnerability]) -> str:
838
+ """Generate executive summary for C-level"""
839
+
840
+ critical = len([v for v in vulnerabilities if v.cvss_score >= 9.0])
841
+ high = len([v for v in vulnerabilities if 7.0 <= v.cvss_score < 9.0])
842
+ medium = len([v for v in vulnerabilities if 4.0 <= v.cvss_score < 7.0])
843
+
844
+ summary = f"""
845
+ EXECUTIVE SUMMARY
846
+ ═══════════════════════════════════════════════════════════════════════════
847
+
848
+ Target Organization: {target}
849
+ Assessment Period: {datetime.now().strftime('%Y-%m-%d')}
850
+ Overall Risk Rating: {"CRITICAL" if critical > 0 else "HIGH" if high > 0 else "MEDIUM"}
851
+
852
+ KEY FINDINGS:
853
+ • {critical} Critical vulnerabilities requiring immediate attention
854
+ • {high} High-risk vulnerabilities to address within 1 week
855
+ • {medium} Medium-risk vulnerabilities for next sprint
856
+
857
+ BUSINESS IMPACT:
858
+ """
859
+
860
+ if critical > 0:
861
+ summary += "• CRITICAL: Immediate risk of data breach or system compromise\\n"
862
+ if high > 0:
863
+ summary += "• HIGH: Significant risk to business operations and data integrity\\n"
864
+
865
+ summary += f"""
866
+ IMMEDIATE ACTIONS REQUIRED:
867
+ 1. Convene security incident response team
868
+ 2. Prioritize critical vulnerability remediation
869
+ 3. Review and enhance monitoring capabilities
870
+ 4. Consider temporary WAF rules for protection
871
+
872
+ ESTIMATED REMEDIATION EFFORT:
873
+ • Critical issues: 1-3 days
874
+ • High issues: 1-2 weeks
875
+ • Full remediation: 1-3 months
876
+
877
+ RECOMMENDED INVESTMENT:
878
+ • Immediate security patches: $5K-$15K
879
+ • Security infrastructure improvements: $25K-$75K
880
+ • Ongoing security program: $100K-$300K annually
881
+
882
+ ═══════════════════════════════════════════════════════════════════════════
883
+ """
884
+ return summary
885
 
886
  # ════════════════════════════════════════════════════════════════════════════
887
  # SECTION 9: MAIN ORCHESTRATOR
 
905
  "target": target_url,
906
  "timestamp": datetime.now().isoformat(),
907
  "subdomains": [],
908
+ "technologies": {},
909
  "endpoints": [],
910
  "forms": [],
911
  "js_files": [],
912
+ "security_headers": {},
913
+ "vulnerabilities": [],
914
  "threat_vectors": [],
915
  "attack_paths": [],
916
  "stride_analysis": {},
 
920
 
921
  try:
922
  # PHASE 1: Passive OSINT
923
+ print("[1/5] Passive OSINT gathering...")
924
  passive_data = await self.passive_engine.gather_dns_intel(target_url)
925
  results["subdomains"] = passive_data.get("subdomains", [])
926
 
 
931
  for san in ssl_data["subjectAltNames"]
932
  ])
933
 
934
+ # Certificate Transparency logs
935
+ ct_subdomains = await self.passive_engine.crt_sh_lookup(target_url)
936
+ for sub in ct_subdomains:
937
+ if sub not in [s.get("subdomain") for s in results["subdomains"]]:
938
+ results["subdomains"].append({"subdomain": sub, "ip": "from_ct"})
939
+
940
+ # GitHub recon
941
  github_data = await self.passive_engine.github_reconnaissance(target_url.replace(".com", ""))
942
  results["github_intel"] = github_data
943
 
944
+ # Wayback Machine
945
+ wayback_urls = await self.passive_engine.wayback_machine_lookup(target_url)
946
+ results["historical_urls"] = wayback_urls
947
+
948
  # PHASE 2: Active Reconnaissance
949
+ print("[2/5] Active reconnaissance...")
950
  technologies = await self.active_engine.fingerprint_technologies(target_url)
951
  results["technologies"] = technologies
952
 
953
+ endpoints = await self.active_engine.discover_endpoints(target_url, COMMON_ENDPOINTS)
954
+ results["endpoints"] = endpoints
 
 
 
955
 
956
  forms = await self.active_engine.analyze_forms(target_url)
957
  results["forms"] = forms
 
959
  js_endpoints = await self.active_engine.extract_javascript_endpoints(target_url)
960
  results["js_files"] = js_endpoints
961
 
962
+ security_headers = await self.active_engine.analyze_security_headers(target_url)
963
+ results["security_headers"] = security_headers
964
+
965
+ # PHASE 3: Vulnerability Analysis
966
+ print("[3/5] Vulnerability analysis...")
967
+ vulnerabilities = await self.active_engine.check_common_vulnerabilities(target_url)
968
+ results["vulnerabilities"] = [asdict(v) for v in vulnerabilities]
969
+
970
+ # PHASE 4: Threat Modeling
971
+ print("[4/5] Threat modeling...")
972
  threat_vectors = self.threat_model.analyze_web_app(results)
973
  results["threat_vectors"] = [asdict(tv) for tv in threat_vectors]
974
 
 
978
  stride_analysis = self.threat_model.generate_stride_report(results)
979
  results["stride_analysis"] = stride_analysis
980
 
981
+ # PHASE 5: Attack Graph
982
+ print("[5/5] Generating attack graph...")
983
+ graph_data = self.graph_engine.create_enhanced_attack_graph(
984
+ threat_vectors, attack_paths, vulnerabilities
985
+ )
986
  results["graph_data"] = graph_data
987
 
988
+ # PHASE 6: Reporting
989
+ print("[6/6] Generating report...")
990
  report = self.reporting.generate_assessment_report(
991
+ target_url, results, threat_vectors, attack_paths, stride_analysis, vulnerabilities
992
  )
993
  results["report"] = report
994
 
995
+ print("✅ Assessment complete!")
996
+
997
  except Exception as e:
998
  results["error"] = str(e)
999
  logging.error(f"Assessment failed: {e}")
1000
+ import traceback
1001
+ results["traceback"] = traceback.format_exc()
1002
 
1003
  return results
1004
 
 
1013
  """Gradio wrapper function"""
1014
 
1015
  try:
1016
+ if not target_url:
1017
+ return "Error: Please enter a target domain", "{}", go.Figure(), "No report generated"
1018
+
1019
+ # Clean target URL
1020
+ target_url = target_url.replace("https://", "").replace("http://", "").strip("/")
1021
+
1022
  progress(0.1, desc="🔍 Validating target...")
1023
 
1024
  # Update threat level
 
1048
  else:
1049
  fig = go.Figure()
1050
 
1051
+ # Calculate stats
1052
+ vulns = results.get("vulnerabilities", [])
1053
+ critical = len([v for v in vulns if v.get("cvss_score", 0) >= 9.0])
1054
+ high = len([v for v in vulns if 7.0 <= v.get("cvss_score", 0) < 9.0])
1055
+ medium = len([v for v in vulns if 4.0 <= v.get("cvss_score", 0) < 7.0])
1056
+
1057
  # Summary
1058
  summary = f"""
1059
  ## 🔴 ASSESSMENT COMPLETE
1060
 
1061
  **Target:** {target_url}
1062
+ **Date:** {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
1063
+ **Threat Level:** {threat_level}
1064
 
1065
  ### Quick Stats
1066
  - 🌐 Subdomains: {len(results.get('subdomains', []))}
1067
+ - 🔧 Technologies: {len(results.get('technologies', {}).get('cms', [])) + len(results.get('technologies', {}).get('frameworks', []))}
1068
+ - 📍 Endpoints: