memfd Shell Code Injection unter Linux

vorhergehende Artikel in: Linux Security Python
23.04.2023

Ich stieß neulich auf einen Python-OneLiner, der sich mit der Erstellung und Nutzung von memfd's befasste: Filedeskriptoren, die nur im RAM eines Rechners existieren, sich aber sonst wie normale Dateien verhalten. Wenn man ausführbaren Code in einem solchen File speichert, kann man dieses sogar ausführen. Es bleiben aber keine Spuren auf dem Rechner zurück, nachdem er ausgeschaltet wurde.

Den Toot selbst kann ich hier leider nicht verlinken: ich konnte ihn mir zwar auf Mastodon ansehen, aber nicht im Browser öffnen - da scheint irgendwas schiefgelaufen zu sein. Der Python-Code ließ sich aber kopieren - daher gebe ich wenigstens den hier wieder:

python3 -c "import os;os.fork()or(os.setsid(),print(f'/proc/{os.getpid()}/fd/{os.memfd_create(str())}'),os.kill(os.getpid(),19))"

Letztlich wird hier ein Prozess gestartet, der wiederum mittels der funktion memfd_create einen dieser besagten memfd's anlegt und - da diese mit dem Ende ihres Elternprozesses ebenfalls wieder verschwinden - mittels Signal 19 pausiert. Anschließend kann man mit der Datei unter /proc/{os.getpid()}/fd/{number} wie mit jeder anderen Datei arbeiten.

Nachdem ich das versucht und festgestellt hatte, dass das wirklich geht war mein erster Gedanke: "Das muss doch auch ohne Python in der Shell gehen!". Die gute Nachricht - wie sich hinterher herausstellte - war, dass dem nicht so ist: es existiert in der Standardinstallation kein vergleichbares Werkzeug, dass es in der Shell - wei z.B. mkfifo - gestatten würde, einen solchen memfd zu erzeugen.

Das ließ mich weiter in den Kaninchenbau abrutschen und ich erforschte zunächst viele der fast unzählbaren alternativen Wege, eine Ramdisk unter Linux zu erzeugen. Irgendwann stieß ich dann aber auf einen Blogbeitrag, der gefährlich so klang, wie das, was ich mir vorstellte: Dieser Beitrag erklärte aber nur, was geht und nicht wie man das macht. Ich konnte aber daraus entnehmen, dass der Vortrag auf einer Hackerkonferenz im Jahre 2018 gehalten worden war.

Ich sah mir also zunächst diese Präsentation an, die mir aber immer noch nicht genug Hintergründe offenbarte. Also suchte ich weiter und fand den zugehörigen Vortrag tatsächlich als Video. Nachdem ich mir dieses zu Gemüte geführt hatte, begann ich mit eigenen Experimenten, die dem dort vorgezeichneten Pfad folgten.

Besonders interessant fand ich eine für mich neue Information: dass man unter Linux als nicht-privilegierter Nutzer einfach so die Address Space Layout Randomization (ASLR) abschalten kann, überraschte mich dann doch.

Und dass es möglich ist, via /proc den Speicher einer Anwendung zu überschreiben - auch die Abschnitte, die Code enthalten! - überraschte mich ebenfalls. So kann man sich auf einfache Art und Weise das Angriffsziel zurechtlegen:

  • ASLR abschalten,
  • Snippet schreiben, das memfd erzeugt und Prozess pausiert (ähnlich dem schon gezeigten Python-Code)
  • Anwendung dd nutzen, um eigenen Speicher zu überschreiben (selbstmodifizierender Code!)
  • Eine geeignete Stelle suchen, um den eigenen Code zu platzieren (bei dd war das der Aufruf von fclose)
  • Mittels /proc die Position im Ram suchen, an die dd geladen wird (ASLR deaktivieren!)
  • Anwendung dd aufrufen und das Snippet an die Adresse des fclose-Aufrufs kopieren
Damit wird bei Beendigung von dd unser Code ausgeführt, der einen memfd erzeugt und anschließend den Prozess pausiert. In den so entstandenen File-Descriptor können wir nun beliebige ausführbare Inhalte kopieren und diese darüber auch ausführen.

Jemand, der einen solchen Angriff bemerken wollte, müsste schon sehr speziell Ausschau halten: Prozesse, die pausiert sind, wären ein guter Anfangsverdacht!

Der Mensch, der diesen Vortrag damals gehalten hat, hat eine eigene Firma, in deren Blog, man den Artikel dazu ebenfalls finden kann.

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Multi-User-WebDAV, Docker, GitHub

    17.11.2019

    Nachdem ich mich in letzter Zeit verstärkt mit Docker und dem zugehörigen Ökosystem beschäftige, habe ich begonnen, verschiedenste Dienste in Containern zu testen um zu sehen, ob in manchen Fällen LXC oder KVM nicht doch die bessere Wahl wäre...

    Weiterlesen...

Neueste Artikel

  • Migration der Webseite und aller OpenSource Projekte

    In eigener Sache...

    Weiterlesen...
  • AutoHideToolbar für Java Swing

    Ich habe eine neue Java Swing Komponente erstellt: Es handelt sich um einen Wrapper für von JToolBar abgeleitete Klassen, die die Werkzeugleiste minimieren und sie nur dann einblenden, wenn der Mauszeiger über ihnen schwebt.

    Weiterlesen...
  • Integration von EBMap4D in die sQLshell

    Ich habe bereits in einem früheren Artikel über meine ersten Erfolge berichtet, der sQLshell auf Basis des bestehenden Codes aus dem Projekt EBMap4D eine bessere Integration für Geo-Daten zu spendieren und entsprechende Abfragen, bzw. deren Ergebnisse auf einer Kartenansicht zu visualisieren.

    Weiterlesen...

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.