Zum Inhalt springen

Remote Code Execution (RCE)

CWE-94CWE-77OWASP A03:2021Aktualisiert 29. August 20265 Min. Lesezeit

Remote Code Execution (RCE) ist eine Schwachstelle, bei der ein Angreifer aus der Ferne eigenen Code oder Systembefehle auf Ihrem Server ausführt, weil unsichere Eingaben in einen Befehl, eine Vorlage oder eine Deserialisierung gelangen. Es ist das schwerste Ergebnis, das eine Anwendung haben kann: Ab diesem Moment führt der Angreifer Code mit den Rechten Ihres Servers aus.

Remote Code Execution, kurz RCE, gilt als das schwerste Ergebnis, das eine Web-Schwachstelle haben kann. Der Angreifer sendet nicht bloß Daten an Ihre Anwendung, sondern eigenen Programmcode oder Systembefehle, und Ihr Server führt sie brav aus. Im Folgenden erfahren Sie, was RCE genau ist, wie ein solcher Angriff in der Praxis abläuft, was ein Angreifer damit erreicht und wie Sie Ihre Anwendung dagegen absichern.

Was ist Remote Code Execution?

Remote Code Execution (RCE) ist eine Schwachstelle, bei der ein Angreifer aus der Ferne eigenen Code oder Befehle auf Ihrem Server ausführen lässt. Das gelingt, sobald eine Eingabe von außen (ein Parameter, eine hochgeladene Datei, ein Header) an eine Stelle gelangt, an der die Anwendung diese Eingabe als auszuführende Anweisung behandelt statt als harmlose Daten.

Ein Vergleich aus dem Alltag: Stellen Sie sich ein Gebäude mit einem Briefschlitz vor, der nur dazu gedacht ist, eine Adresse anzugeben. Hinter dem Schlitz sitzt ein eifriger Assistent, der genau das tut, was auf dem Zettel steht. Normalerweise erhält er eine Adresse und schlägt die Route nach. Schreibt jemand jedoch “und öffnen Sie danach alle Türen” auf den Zettel, dann tut der allzu gehorsame Assistent auch das. Bei einer RCE ist Ihr Server dieser Assistent: Alles, was durch eine schlecht bewachte Öffnung hereinkommt, kann zu einem Befehl werden.

Die Schwachstelle steckt also nicht in einer einzelnen Technik, sondern in dem Muster, dass Eingaben und ausführbare Anweisungen ineinander übergehen. Das kann geschehen, wenn eine Eingabe in einen Systembefehl gelangt (Command Injection, CWE-77), wenn eine Anwendung eine Zeichenkette etwa mit eval als Programmcode auswertet (Code Injection, CWE-94) oder wenn eine verwundbare Bibliothek nicht vertrauenswürdige Daten deserialisiert. Der rote Faden ist immer derselbe: Die Grenze zwischen Daten und Code ist verschwunden.

Wie funktioniert ein RCE-Angriff?

Der klassische Weg ist Command Injection: Die Anwendung baut einen Systembefehl zusammen, indem sie Benutzereingaben an eine Zeichenkette anhängt, und übergibt ihn der Shell. Nehmen wir eine einfache Diagnosefunktion, die mit dem Befehl ping prüft, ob ein Host erreichbar ist.

Verwundbar:

const { exec } = require("child_process");

app.get("/ping", (req, res) => {
  const host = req.query.host;
  // Die Eingabe wird direkt in den Shell-Befehl eingefügt
  exec("ping -c 1 " + host, (err, stdout) => {
    res.send(stdout);
  });
});

Gibt ein normaler Benutzer einen Hostnamen ein, funktioniert das einwandfrei. Doch exec übergibt die gesamte Zeichenkette an eine Shell, und die Shell kennt Sonderzeichen. Ein Angreifer ruft nicht /ping?host=example.com auf, sondern /ping?host=example.com;cat /etc/passwd. Die Shell liest das Semikolon als Trennzeichen zwischen zwei Befehlen und führt den zweiten einfach aus. Mit Varianten wie host=example.com && rm -rf /data oder dem Herunterladen und Starten eines Skripts wird aus diesem harmlosen Diagnosefeld eine vollwertige Kommandozeile auf Ihrem Server.

Die Lösung besteht darin, Eingaben niemals von einer Shell interpretieren zu lassen. Rufen Sie das Programm direkt auf und übergeben Sie die Argumente als eigene Liste, damit Sonderzeichen ihre Bedeutung verlieren. Validieren Sie die Eingabe zusätzlich gegen ein striktes Muster.

Sicher:

const { execFile } = require("child_process");

app.get("/ping", (req, res) => {
  const host = req.query.host;
  // Nur Buchstaben, Ziffern, Punkte und Bindestriche zulassen
  if (!/^[a-zA-Z0-9.-]+$/.test(host)) {
    return res.status(400).send("Ungueltiger Host");
  }
  // Argumente werden als Liste uebergeben, ohne eine Shell dazwischen
  execFile("ping", ["-c", "1", host], (err, stdout) => {
    res.send(stdout);
  });
});

Jetzt wird example.com;cat /etc/passwd als ein einziger, ungültiger Hostname behandelt: Es gibt keine Shell mehr, die das Semikolon als “starte einen neuen Befehl” auffasst, und die Validierung weist die Eingabe ohnehin ab. Das Programm erhält genau die Argumente, die Sie beabsichtigt haben, und nichts weiter, genau die Trennung zwischen Befehl und Daten, die den Angriff unmöglich macht.

Verdächtige Zeichen selbst mit einer Sperrliste aus der Eingabe zu filtern, ist kein verlässlicher Schutz: Angreifer verfügen über unzählige Varianten mit anderen Kodierungen, Leerzeichen oder Anführungszeichen. Rufen Sie das zugrunde liegende Programm direkt mit einer Argumentliste auf und arbeiten Sie mit einer Positivliste erlaubter Werte.

Welche Auswirkungen hat Remote Code Execution?

Die Auswirkung einer RCE ist per Definition schwer, denn der Angreifer führt Code mit denselben Rechten wie Ihre Anwendung aus. Im mildesten Fall liest er Dateien aus, die nicht für ihn bestimmt sind: Konfigurationsdateien, geheime Schlüssel, den Quellcode. Doch dabei bleibt es selten. Mit der Möglichkeit, Befehle auszuführen, kann ein Angreifer eine dauerhafte Hintertür installieren, Daten zur Erpressung verschlüsseln oder den Server als Ausgangspunkt für weitere Angriffe nutzen.

Gerade Letzteres macht RCE so gefährlich. Ein übernommener Server steht fast immer innerhalb Ihres Netzwerks und hat Zugriff auf Dinge, die von außen unerreichbar sind: interne APIs, Datenbanken, andere Maschinen. Von dort bewegt sich ein Angreifer seitwärts durch die Infrastruktur, sammelt Zugangsdaten und arbeitet sich zu den Systemen vor, auf die es wirklich ankommt. Was als ein einziges verwundbares Eingabefeld begann, endet dann in einem vollständigen Einbruch.

Für die Organisation bedeutet das ein Datenleck, Ausfälle von Diensten, mögliche Erpressung und die entsprechenden rechtlichen und Reputationsfolgen. Weil der Schweregrad vom Auslesen einer einzelnen Datei bis zur vollständigen Übernahme von Server und Netzwerk reicht, bewegt sich die Bewertung von hoch bis kritisch, und in der Praxis liegt eine echte RCE fast immer am oberen Ende dieser Skala.

Wie erkennen Sie Remote Code Execution?

Ein Tester sucht nach jeder Stelle, an der eine Eingabe einen Befehl, einen Dateipfad, eine Vorlage oder eine Deserialisierung beeinflussen kann. Eine erste Prüfung besteht darin, Shell-Zeichen wie ;, | oder && gefolgt von einem harmlosen Befehl mitzusenden und zu beobachten, ob sich die Ausgabe ändert. Bringt das kein sichtbares Ergebnis (bei blinden Varianten gibt es keine direkte Reaktion), misst ein Pentester das Verhalten indirekt: ein Befehl, der die Antwort absichtlich verzögert, oder der eine ausgehende Netzwerkanfrage an einen eigenen Server auslöst und so die Ausführung verrät.

Automatisierte Scanner und Abhängigkeitsprüfungen finden viele bekannte Fälle, etwa eine verwundbare Bibliotheksversion, übersehen aber die RCEs, die tief in der eigenen Logik oder hinter der Authentifizierung verborgen liegen. Ein gründlicher Penetrationstest verbindet daher Automatisierung mit manueller Untersuchung. Genau diese Art von Schwäche spürt AssistSec bei einer Sicherheitsuntersuchung gezielt auf und reproduziert sie nachvollziehbar, damit Sie wissen, welche Eingabe tatsächlich zur Codeausführung führt.

Wie verhindern Sie Remote Code Execution?

  • Rufen Sie externe Programme ohne Shell auf. Verwenden Sie eine Variante, die das Programm und seine Argumente als eigene Liste übergibt (etwa execFile statt exec), sodass Sonderzeichen keine Bedeutung erhalten.
  • Werten Sie nicht vertrauenswürdige Eingaben niemals als Code aus. Vermeiden Sie eval und ähnliche Konstrukte auf Basis von Benutzereingaben und nutzen Sie sichere Template-Engines, die Daten und Code trennen.
  • Validieren Sie Eingaben mit einer Positivliste. Legen Sie pro Feld fest, welche Werte gültig sind, und weisen Sie den Rest ab, statt zu versuchen, “gefährliche” Zeichen herauszufiltern.
  • Verfolgen Sie Abhängigkeiten und patchen Sie schnell. Viele RCEs stammen aus Fremdkomponenten; verfolgen Sie Advisories und aktualisieren Sie verwundbare Versionen so schnell wie möglich.
  • Wenden Sie das Prinzip der geringsten Rechte an. Lassen Sie die Anwendung unter einem Konto mit minimalen Rechten und in einer isolierten Umgebung laufen, damit ein erfolgreicher Angriff so wenig wie möglich erreicht.
  • Seien Sie vorsichtig bei Deserialisierung und Datei-Uploads. Deserialisieren Sie keine nicht vertrauenswürdigen Daten und behandeln Sie eine hochgeladene Datei niemals als etwas, das ausgeführt werden darf.
  • Lassen Sie den Code regelmäßig testen. Ein gezielter Penetrationstest und ein Code-Review fangen die RCE-Pfade ab, die Scanner überspringen.

Quellen

Häufige Fragen

Was ist der Unterschied zwischen RCE und Command Injection?

Command Injection ist einer der häufigsten Wege zu Remote Code Execution: Unsichere Eingaben gelangen in einen Systembefehl. RCE ist das umfassendere Ergebnis (Code aus der Ferne auszuführen), das auch durch Code Injection, unsichere Deserialisierung oder eine verwundbare Bibliothek entstehen kann.

Warum ist RCE so viel schwerwiegender als andere Schwachstellen?

Bei den meisten Schwachstellen liest oder verändert ein Angreifer Daten. Bei RCE führt er eigenen Code auf Ihrem Server aus, mit denselben Rechten wie Ihre Anwendung. Damit ist praktisch alles auf dieser Maschine erreichbar und oft auch das dahinterliegende Netzwerk.

Kann eine RCE entstehen, ohne dass ich selbst unsicheren Code schreibe?

Ja. Viele RCEs stammen aus einer verwundbaren Fremdbibliothek oder Komponente. Log4Shell ist das bekannteste Beispiel. Zu wissen, welche Abhängigkeiten Sie einsetzen, und diese zeitnah zu patchen, ist daher genauso wichtig wie sicherer eigener Code.

Schützt eine Web Application Firewall vor RCE?

Eine WAF blockiert bekannte Angriffsmuster und ist eine nützliche zusätzliche Schicht, doch Angreifer umgehen Filter regelmäßig mit anderen Kodierungen oder unbekannten Payloads. Die eigentliche Lösung liegt in sicheren Aufrufen, Eingabevalidierung und zeitnahem Patchen.

Verwandte Artikel

Zum Suchen / drücken · Esc