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

AuswirkungDetails
ZugriffskontrolleBereich: 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

  1. MITRE Corporation. "CWE-290: Authentication Bypass by Spoofing." Common Weakness Enumeration. https://cwe.mitre.org/data/definitions/290.html

  2. OWASP Foundation. "Authentication Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

  3. NIST. "Guidelines for Securing IP Networks." https://csrc.nist.gov/