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 Github Repositories Gitlab Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Aviator + Websockets

    15.06.2019

    Nachdem ich in den letzten Wochen und Monaten meine Zeit und Energie in die sQLshell gesteckt habe - was sowohl Bugfixing als auch neue Features betraf - habe ich nun endlich die Zeit gefunden, ein bereits lange überfälliges Feature an dWb+ und speziell am aviator zu implementieren.

    Weiterlesen...

Neueste Artikel

  • Neue Version plantumlinterfaceproxy napkin look

    Es gibt eine neue Version des Projektes plantumlinterfaceproxy - Codename napkin look.

    Weiterlesen...
  • Apache HTTPCore5 funktioniert nicht mit Docker

    Ich habe neulich drei Stunden meines Lebens verschwendet weil ich unbedingt die neueste Version der HTTPCore5 Library von Apache einsetzen wollte.

    Weiterlesen...
  • Entwurfsmodus für beliebige SVG Graphiken

    Nachdem ich in der Vergangenheit immer wieder Weiterentwicklungen der Idee vorgestellt habe, Graphiken mit dem Computer so zu ezeugen dass sie eine gewisse "handgemachte" Anmutung haben, habe ich nunmehr die durchschlagende Idee gehabt:

    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, muß 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 GitHub-Repositories findet man hier - meine öffentlichen GitLab-Repositories finden sich dagegen hier.