Authentifizierungsumgehung durch Spoofing
Beschreibung
Authentifizierungsumgehung durch Spoofing ist eine Schwachstelle, die durch fehlerhaft implementierte Authentifizierungsschemata verursacht wird, die Spoofing-Angriffen ausgesetzt sind. Diese Schwäche tritt auf, wenn Systeme Authentifizierungsentscheidungen basierend auf Attributen treffen, die von Angreifern gefälscht oder manipuliert werden können, wie Quell-IP-Adressen, DNS-Lookups, HTTP-Header oder andere extern kontrollierbare Werte. Anstatt Anmeldedaten direkt zu verifizieren, vertrauen anfällige Systeme Identitätsbehauptungen, die Angreifer fälschen können, was unbefugten Zugang ohne ordnungsgemäße Authentifizierung ermöglicht.
Risiko
Spoofing-basierte Authentifizierungsumgehung erzeugt schwerwiegende Sicherheitsrisiken, da der Authentifizierungsmechanismus selbst grundlegend fehlerhaft ist. IP-Adressbasierte Authentifizierung kann durch IP-Spoofing besiegt werden, bei dem Angreifer Quelladressen fälschen, was besonders effektiv in Netzwerken ohne Egress-Filterung ist. DNS-basierte Vertrauensentscheidungen sind anfällig für DNS-Cache-Poisoning und DNS-Hijacking-Angriffe, die von Angreifern kontrollierte Hostnamen für IP-Lookups zurückgeben. HTTP-Header-Authentifizierung (X-Forwarded-For, Referer, Host) ermöglicht Angreifern, einfach Header zu setzen, die jede Identität beanspruchen. Das Risiko wird verstärkt, da diese Schwächen während des normalen Betriebs möglicherweise nicht offensichtlich sind, aber trivial von Angreifern mit Netzwerkzugang ausnutzbar sind. Systeme, die sich für sicherheitskritische Entscheidungen auf spoofbare Attribute verlassen, haben überhaupt keine bedeutungsvolle Authentifizierung.
Lösung
Verlassen Sie sich nie ausschließlich auf spoofbare Attribute für Authentifizierungsentscheidungen. Anstelle von IP-Adressbasierter Authentifizierung verwenden Sie ordnungsgemäße anmeldedatenbasierte Authentifizierung (Passwörter, Zertifikate, Token). Ersetzen Sie DNS-Lookups für Sicherheitsentscheidungen durch zertifikatsbasierte Host-Verifikation (TLS). Ignorieren Sie HTTP-Header wie X-Forwarded-For für Authentifizierung, es sei denn, sie kommen von vertrauenswürdigen Proxies und werden mit anderen Authentifizierungsfaktoren kombiniert. Implementieren Sie ordnungsgemäße Authentifizierungsprotokolle, die kryptografischen Identitätsnachweis verwenden. Wenn IP-basierte Beschränkungen für Defense-in-Depth benötigt werden, kombinieren Sie sie mit ordnungsgemäßer Authentifizierung anstatt sie allein zu verwenden. Für Vertrauen auf Netzwerkebene verwenden Sie gegenseitiges TLS oder VPNs mit zertifikatsbasierter Authentifizierung. Prüfen Sie regelmäßig Authentifizierungsmechanismen, um Abhängigkeit von spoofbaren Attributen zu identifizieren.
Häufige Auswirkungen
| Auswirkung | Details |
|---|---|
| Zugriffskontrolle | Bereich: Zugriffskontrolle Angreifer können auf Ressourcen zugreifen, die ansonsten ohne ordnungsgemäße Authentifizierung nicht zugänglich wären, indem sie Identitätsattribute spoofen. Dies ermöglicht vollständige Umgehung der Authentifizierung, was Angreifern erlaubt, falsche Identitäten anzunehmen und unbefugten Zugang zu geschützten Systemen und Daten zu erlangen. |
Beispielcode
Anfälliger Code (Java)
Die folgenden Beispiele demonstrieren Authentifizierungsumgehung durch Spoofing:
// Anfällig: IP-Adressbasierte Authentifizierung
public class VulnerableIPAuth {
private static final String APPROVED_IP = "192.168.1.100";
public boolean authenticate(HttpServletRequest request) {
// Anfällig: Vertraut Quell-IP-Adresse
String sourceIP = request.getRemoteAddr();
if (sourceIP != null && sourceIP.equals(APPROVED_IP)) {
return true; // Basierend auf spoofbarer IP authentifiziert
}
return false;
// Angreifer spooft Quell-IP um Authentifizierung zu umgehen
}
public boolean authenticateByHeader(HttpServletRequest request) {
// Anfällig: Vertraut X-Forwarded-For-Header
String clientIP = request.getHeader("X-Forwarded-For");
if (clientIP != null && clientIP.equals(APPROVED_IP)) {
return true; // Angreifer setzt Header: X-Forwarded-For: 192.168.1.100
}
return false;
}
}
// Anfällig: DNS-basierte Authentifizierung
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
int vulnerable_dns_auth(struct sockaddr_in *client_addr, const char *trusted_host) {
struct hostent *hp;
// Anfällig: Reverse-DNS-Lookup für Authentifizierung
hp = gethostbyaddr((char *)&client_addr->sin_addr,
sizeof(struct in_addr), AF_INET);
if (hp && !strncmp(hp->h_name, trusted_host, strlen(trusted_host))) {
return 1; // Vertraut basierend auf DNS
// Angreifer vergiftet DNS-Cache um vertrauenswürdigen Hostnamen zurückzugeben
}
return 0;
}
int vulnerable_forward_dns(const char *hostname, const char *trusted_domain) {
// Anfällig: Forward-Lookup verifiziert Reverse nicht
struct hostent *hp = gethostbyname(hostname);
if (hp != NULL) {
// Verbinde mit aufgelöster IP
// Angreifer kontrolliert DNS für seine Domain
return 1;
}
return 0;
}
# Anfällig: Header-basierte Authentifizierung
from flask import Flask, request
app = Flask(__name__)
@app.route('/admin')
def vulnerable_admin():
# Anfällig: Vertraut Referer-Header
referer = request.headers.get('Referer', '')
if 'internal.company.com' in referer:
return render_admin_panel()
# Angreifer setzt Referer: https://internal.company.com/
# Anfällig: Vertraut Host-Header
host = request.headers.get('Host', '')
if host == 'admin.internal.com':
return render_admin_panel()
# Angreifer setzt Host: admin.internal.com
return "Zugriff verweigert", 403
@app.route('/api/data')
def vulnerable_api():
# Anfällig: IP-Allowlist aus Header
client_ip = request.headers.get('X-Real-IP', request.remote_addr)
if client_ip in ALLOWED_IPS:
return get_sensitive_data()
# Angreifer setzt X-Real-IP: 10.0.0.1
return "Zugriff verweigert", 403
Korrigierter Code (Java)
// Korrigiert: Ordnungsgemäße anmeldedatenbasierte Authentifizierung
public class SecureAuth {
private final TokenValidator tokenValidator;
private final PasswordEncoder passwordEncoder;
// Korrigiert: Anmeldedatenbasierte Authentifizierung, nicht IP-basiert
public AuthResult authenticate(HttpServletRequest request) {
// Anmeldedaten extrahieren
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
return AuthResult.failure("Autorisierung fehlt");
}
String token = authHeader.substring(7);
// Korrigiert: Kryptografisches Token verifizieren
if (!tokenValidator.isValid(token)) {
return AuthResult.failure("Ungültiges Token");
}
// IP kann für zusätzliche Sicherheitsschicht verwendet werden, nicht primäre Auth
String sourceIP = request.getRemoteAddr();
if (!isIPInAllowedRange(sourceIP)) {
logger.warn("Zugriff von ungewöhnlicher IP: " + sourceIP);
// Könnte zusätzliche Verifikation erfordern, aber Token ist primäre Auth
}
return AuthResult.success(tokenValidator.getUserFromToken(token));
}
// Korrigiert: X-Forwarded-For nur von bekannten Proxies vertrauen
public String getClientIP(HttpServletRequest request) {
String remoteAddr = request.getRemoteAddr();
// Header nur vertrauen wenn Anfrage von bekanntem Proxy kommt
if (TRUSTED_PROXY_IPS.contains(remoteAddr)) {
String forwarded = request.getHeader("X-Forwarded-For");
if (forwarded != null) {
// Erste IP (Client) aus Kette nehmen
return forwarded.split(",")[0].trim();
}
}
return remoteAddr;
}
}
// Korrigiert: Zertifikatsbasierte Host-Verifikation
#include <openssl/ssl.h>
#include <openssl/x509.h>
int secure_host_verification(SSL *ssl, const char *expected_hostname) {
X509 *cert = SSL_get_peer_certificate(ssl);
if (cert == NULL) {
return 0; // Kein Zertifikat präsentiert
}
// Korrigiert: Zertifikatskette verifizieren
if (SSL_get_verify_result(ssl) != X509_V_OK) {
X509_free(cert);
return 0; // Zertifikat nicht vertrauenswürdig
}
// Korrigiert: Hostname stimmt mit Zertifikat überein
if (X509_check_host(cert, expected_hostname,
strlen(expected_hostname), 0, NULL) != 1) {
X509_free(cert);
return 0; // Hostname stimmt nicht überein
}
X509_free(cert);
return 1; // Host über Zertifikat verifiziert
}
// Korrigiert: Nicht allein auf DNS für Sicherheit verlassen
int secure_connect(const char *hostname, int port) {
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
// Zertifikatsverifikation aktivieren
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_default_verify_paths(ctx);
// Mit TLS verbinden
SSL *ssl = connect_with_tls(hostname, port, ctx);
// Host über Zertifikat verifizieren, nicht DNS allein
if (!secure_host_verification(ssl, hostname)) {
SSL_shutdown(ssl);
return -1;
}
return 0;
}
# Korrigiert: Ordnungsgemäße Authentifizierung ohne spoofbare Attribute
from flask import Flask, request, abort
from functools import wraps
import jwt
app = Flask(__name__)
def require_auth(f):
"""Korrigiert: Token-basierte Authentifizierung"""
@wraps(f)
def decorated(*args, **kwargs):
auth_header = request.headers.get('Authorization')
if not auth_header or not auth_header.startswith('Bearer '):
abort(401)
token = auth_header.split(' ')[1]
try:
# Korrigiert: Kryptografisches Token verifizieren
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
request.user = payload
except jwt.InvalidTokenError:
abort(401)
return f(*args, **kwargs)
return decorated
def get_client_ip(request):
"""Korrigiert: Forwarded-Header nur von bekannten Proxies vertrauen"""
remote_addr = request.remote_addr
# X-Forwarded-For nur verarbeiten wenn von vertrauenswürdigem Proxy
if remote_addr in TRUSTED_PROXY_IPS:
forwarded = request.headers.get('X-Forwarded-For')
if forwarded:
# Erste (originale Client-)IP zurückgeben
return forwarded.split(',')[0].strip()
return remote_addr
@app.route('/admin')
@require_auth
def secure_admin():
# Korrigiert: Verwendet Token-Authentifizierung, nicht Header
if not request.user.get('is_admin'):
abort(403)
return render_admin_panel()
@app.route('/api/data')
@require_auth
def secure_api():
# Korrigiert: Authentifizierung via Token, IP nur für Logging/Auditing
client_ip = get_client_ip(request)
logger.info(f"API-Zugriff durch {request.user['id']} von {client_ip}")
return get_sensitive_data()
Die Korrektur ersetzt spoofbare Attribute durch ordnungsgemäße kryptografische Authentifizierungsmechanismen wie Token, Zertifikate und verifizierte Anmeldedaten.
Ausgenutzt in der Praxis
Hausautomations-IP-Allowlist-Umgehung (IoT-Geräte, 2022)
CVE-2022-30319 dokumentierte ein Hausautomationsprodukt, das IP-Allowlist für Authentifizierung verwendete, die durch IP-Spoofing umgangen werden könnte, was unbefugte Kontrolle über Hausautomationsgeräte ermöglichte.
VOIP-Header-Spoofing (VOIP-Systeme, 2009)
CVE-2009-1048 dokumentierte VOIP-Authentifizierungsumgehung via gespooftem Host-Header, was Angreifern ermöglichte, ohne ordnungsgemäße Anmeldedaten auf die Systemadministration zuzugreifen.
DNS-Cache-Poisoning-Angriffe (Verschiedene Systeme, Fortlaufend)
Systeme, die DNS-Reverse-Lookups für Authentifizierung vertrauen, wurden durch DNS-Cache-Poisoning kompromittiert, was Angreifern ermöglichte, vertrauenswürdige Hosts zu imitieren.
Tools zum Testen/Ausnutzen
-
hping3 — Paketerstellungstool für IP-Spoofing-Tests.
-
Burp Suite — Web-Sicherheitstool für Header-Manipulation und Spoofing-Tests.
-
dnschef — DNS-Proxy zum Testen von DNS-basierter Authentifizierung.
CVE-Beispiele
-
CVE-2022-30319 — Hausautomationsprodukt mit IP-Allowlist-Umgehung.
-
CVE-2009-1048 — VOIP-Authentifizierungsumgehung via gespooftem Host-Header.
Referenzen
-
MITRE Corporation. "CWE-290: Authentication Bypass by Spoofing." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/290.html
-
OWASP Foundation. "Authentication Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
-
NIST. "Guidelines for Securing IP Networks." https://csrc.nist.gov/