┌───────────────────────┐ ▄▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄▄ │ │ █ █ █ █ █ █ │ │ █ █ █ █ █▀▀▀▀ │ │ █ █ █ █ ▄ │ │ ▄▄▄▄▄ │ │ █ █ │ │ █ █ │ │ █▄▄▄█ │ │ ▄ ▄ │ │ █ █ │ │ █ █ │ │ █▄▄▄█ │ │ ▄▄▄▄▄ │ Einführung in SHELF Loading │ █ │ Der Nexus zwischen Static und Position Independent Code│ █ │ ~ @ulexec and @Anonymous_ └───────────────────█ ──┘ ~ Deutsche Übersetzung gamma@thc.org 1. Einführung In den letzten Jahren wurden Linux Angriffstools immer ausgereifter und komplexer. Anhand der höheren Anzahl an Publikationen über Linux Bedrohungen sieht man, dass Linux Malware immer populärer wurde. Diese beinhaltet Linux Malware Implante wie APT82's VPNFilter, Drovorub oder Winnti Linux Malware. Jedoch scheint dieser Anstieg der Popularität nicht viel Einfluß auf die Entwicklung zu haben.Es ist ein relativ junges Ecosystem in dem Cyberkriminelle noch keine aussichtsreichen Ziele zum Geldverdienen, abgesehen vom Crypto Mining, DDoS und Ransomware Operationen, gefunden haben. In der heutigen Linux Threat Landscape resultiert schon die kleinste Verbesserung oder Einführung weiterer Komplexität in AV Evasion. Hierdurch tendieren Linux Malware Entwickler nicht dazu unnötig viele Ressourcen in die Tarnung Ihrer Malware zu stecken. Es gibt eine Vielzahl an mehrdeutigen Gründen, warum dieses Phänomem auftritt. Das Linux Ekosystem ist, im Vergleich zu anderen beliebten Systemen wie Windows und MacOs, dynamischer und unterschiedlicher. Dies beginnt mit den verschiedenen Arten von ELF-Dateien für verschiedene Architecturen, die Tatsache, dass ELF Binaries valide in verschiedenen Formen sein kann, und dass die XXXX Sichtbark visibility of Linux threats is often quite poor. Wegen dieser Dinge begegnen AV Firmen komplett andere Herausforderungen um diese Bedrohungen zu entdecken. Oft wird aufgrund der schlechten Erkennungsrate von einfachen/simplen Bedrohungen implizit angenommen, dass Linux Malware von Natur aus nicht komplex ist. Diese Aussage könnte nicht weiter von Wahrheit entfernt sein. Und die, die mit dem ELF File Format vertraut sind wissen, dass es gerade bei ELF Dateien mehr Raum an Innovationen als wie bei anderen Datei Formaten aufgrund ihrer Flexibilität gibt, obwohl wir sie in den letzten Jahren für Missbräuche nicht gerade viel gesehen haben. In diesem Artikel werden wir eine Technik zeigen, die eine ungewöhnliche Funktionalität von Datei Formaten zeigt. Mit Hilfe dieser Technik werden komplette Exectuables in Shellcode umgewandelt. Dies zeigt wiederum einmal, dass ELF Datein derartig manipuliert werden können um neue Angriffstechniken, welche schwer mit anderen Datei Formaten zu realisieren wären, zu demonstrieren. 2. Eine Einführung in "ELF Reflective Loading" Um diese Technik zu verstehen müssen wir zunächst den kontextuellen Hintergund der bisherigen ELF Techniken erläutern, auf diese die vorgestellte Technik basiert. Ebenso wird die Technik mit den vorherigen Techniken mit ihren Vor- und Nachteilen verglichen. Die meisten ELF Packer, oder andere Applikationen die eine Form des ELF Binary Loadings implementieren, basieren grundlegend auf dem, was User-Land-Exec bezeichnet wird. User-Land-Exec ist eine Methode, die zuerst von @thegrugq veroeffentlicht wurde, in der ein ELF Binary ohne Verwendung der Execve-Familie von System Calls geladen werden kann und aufgrund dessen seinen Namen bekommen hat.. Zur Vereinfachung werden im folgenden Diagramm die Schritte zur Implementierung eines einfachen User-Land-Exec mit Hilfe von ET_EXEC und ET_DYN dargestellt und zeigen eine Implementierung eines UPX Packers für ELF Binaries:Wie man sehen kann besitzt diese Technik folgende Bedingungen (von @thegrugq): 1. Den Adress Bereich löschen 2. Wenn das Binary dynamisch gelinkt wird, lade den Dynamic Linker. 3. Lade das Binary. 4. Initialisiere den Stack 5. Bestimme den Entry Point (z.B. den Dynamic Linker oder das Main Executable). 6. Transferiere die Ausführung zum Entry Point. Auf einem technischen Level sind wir zu den folgenden Bedingungen gekommen: 1. Initialisiere den Stack der eingebettenen ausführbaren Datei mit dem zugehörigem Auxiliary Vector. 2. Analysiere die PHDRs und prüfe, ob ein PT_INTERP Segment existiert unter der Vorraussetzung, dass die Datei eine dynamisch gelinkte ausführbare Datei ist. 3. Lade den Interpreter wenn PT_INTERP vorhanden ist. 4. Lade das eingettete Exectuable. 5. Beginne Codeausführung mit dem gemapptem e_entry des Ziel Executables oder des Interpreters je nachdem ob das Ziel Excutable eine dynamisch gelinkte Datei ist. Wir empfehlen @thegrugq's ausführliches Paper [9]zu diesem Thema zu lesen, um eine ausführlichere Beschreibung zu erhalten. Einer der Fähigkeiten des gewöhnlichen User-Land-Execs ist wie gerade dargestellt wurde die Umgehung eines execves im Kontrast zu anderen gängigen Techniken wie memfd_create/execveat, die zum Laden und Ausführen einer Ziel ELF-Datei eingesetzt werden. Da der Loader das Ziel Executable mappt und lädt hat das eingebettete Exectuable die Möglichkeit eine unkonventionelle Struktur zu besitzen. Das hat den Seiteneffekt nützlich für Evasion und anti-forensische Zwecke zu sein. Auf der Seite kann es für Reverse-Engineerer leicht erkennbar sein, da eine Vielzahl kritischer Artifakte im Loading Process involviert sind. Außerdem kann es etwas fragil sein weil die Technik stark von diesen Komponenten abhängt. Aus diesem Grund war es gewisseweise mühsam User-land-Exec basierende Loader zu schreiben. Als mehr Features zum ELF-Dateiformat hinzugefügt wurden wurde diese Technik immer ausgereifter und gewann an Komplexität. Die neue Technik die wir in diesem Paper behandeln basiert auf der Implementierung eines generischen User-Land-Exec Loaders, der mit einer reduzierten Anzahl an Bedingungen hybride PIEs/statisch gelinkte ELF Datei unterstützt und bisher noch nie erwähnt wurde. Wir glauben das diese Technik eine drastische Verbesserung der bisherigen User-Land-Exec Loader darstellt, da aufgrund der nicht vorhandenen technischen Abhängigkeiten, der Natur der hybriden static/PIE ELF Variante, der Möglichkeiten die diese Technik bietet diese wesentlich invasiver als vorherige User-Land-Exec Varianten ist. 3. Interna der Erzeugung von statischen PIE Executables 3.1 Hintergrund Im Juli des Jahres 2017 patchte H. J. Lu einen Bug-Eintrag im GCC Bugzilla namens ‘Support creating static PIE'. Dieser Patch erwähnt die Implementierung von statischen PIE in dem GLibC Branch hjl-pie-static, in dem Lu zeigt, dass durch das Angeben und Anfügen von -static und -pie zu den PIE-Versionen von crt*.o statische PIE ELF Executables erzeugt werden können. Es ist wichtig zu erwähnen, dass zu der Zeit in der Patch publiziert wurde, die Erzeugung von komplett statisch gelinkten PIE Binärdateien nicht möglich war [1]. Im August übermittelte LU einen zweiten Patch[2] an den GCC um das -static Flagi, das er im vorherigen Patch gezeigt hatte, zur Unterstützung von statischen PIE Dateien hinzuzufügen. Der Patch wurde im trunk [3] akzeptiert und dieses Feature wurde im GCC v8 veröffentlicht. Weiterhin gab es im December 2017 einen commit in der glibc[4], der die Option –enable-static-pie hinzufügte. Dieser Patch machte es möglich die von der ld.so benötigten Teile einzubetten um eigentständige statische PIE Executables zu erzeugen. Die große Änderung in der Glibc um statische PIEs zu erlauben war die neue Funktion _dl_relocate_static_pie die von der __libc_start_main aufgerufen wird. Diese Funktion wird dazu benutzt um die Run-Time Load Address zu lokalisieren, das dynamische Segment auszulesen und dynamische Relokationen vor der Initialisierung durchzuführen um dann den Ausführungsfluss auf die Ziel Applikationen umzuleiten. Um herauszufinden in welcher Reihenfolge Flags und Compilierung/Linking Stages benötigt sind um statische PIE Exectuables zu erzeugen wurded den die Flags –static-pie –v beim Aufruf von GCC benutzt. Wir fanden jedoch bald heraus das hierbei eine Fülle von Flags und Aufrufe des internen Wrappers durch den Linker erzeugt wurde. Zum beispiel wird die Linking Phase durch das Tool /usr/lib/gcc/x86_64-linux-gnu/9/collect2 behandelt und GCC selbst wird durch /usr/lib/gcc/x86_64-linux-gnu/9/cc1 gewrappt. Trotz allerdem haben wir es geschafftrr die irrelevanten Flags zu entfernen und kamen am Schluss zu folgenden Schritten:
Diese Schritte sind tatsächlich die selben die Lu vorgestellt hat und zwar dem Linker die Input Files zu geben, die mit den folgenden Flags kompiliert wurden: –fpie, and –static, -pie, -z text, --no-dynamic-linker. Das rcrt1.o Object beinhaltet den _start Code, der den Programmcode beinhaltet um die Applikation zu laden bevor sein Entry Point den entsprechenden libc Startup Code aufruft, der sich in der __libc_start_main befindet:
Wie eben erwähnt ruft die __libc_start_main die neu hinzugefügte Funktion _dl_relocate_static_pie (die in elf/dl-reloc-static-pie.c der GlibC definiert ist) auf. Die primären Schritte die diese Funktion ausführt sind im folgenden Code kommentiert:
Mit der Hilfe dieser Features ist es GCC möglich statisch gelinkte Executables yu erzeugen, die an jeder beliebigen Adresse geladen werden können. Man kann beobachten, dass _dl_relocate_static_pie fuer die benötigten dynamischen Relokalisierungen verantwortlich ist. Ein erwähnenswerter Unterschied zwischen rcrt1.o und der gewöhnlichen crt1.o Datei ist, dass der ganze Code Position Independant ist. Inspeziert man die erzeugten Binaries sieht man das folgende:
Auf den ersten Blick scheinen sie gewöhnliche dynamisch gelinkte PIE Executables zu sein, die auf auf den ET_DYN executable type aus dem ELF Header basieren. Wenn man jedoch genauer hinschaut erkennt man, dass das PT_INTERP Segment nicht existiert welches normalerweise den Pfad zum Interpreter in dynamisch gelinkten Executables angibt und das Vorhandensein des PT_TLS Segmentes, dass normalerweise nur in statisch gelinkten Executables vorkommt.
Üperprüft man wie der dynamischer Linker das Executable erkennt sieht man das dieser den File Typ korrekt erkennt:
Im dieses File zu laden müssen wir alle PT_LOAD Segmente zu Speicher mappen, den Stack des Prozesses mit den entsprechenden Auxiliarty Vector Entries initialisieren und dann auf den gemappted Entry Point des Excetuables die Programmausführung zu lenken. Das Mapping des RTLD braucht nicht beachtet werden, da es keine externen Abhängigkeiten oder Adress Restriktionen zur Link-Zeit gibt. Wie können beobachten, das es 4 ladbare Segmente gibt, die gewöhnlich in SCOP ELF Dateien auftauchen. Zum einfacheren Einsatz ist es unabdingbar, dass alle vier Segmente in ein einziges zusammenführbar ist wie es gewöhnlich bei der ELF Disk Injection in ein fremdes Executable gemacht wird. Dies kann man durch die Verwendung des -N Linker Flags realisieren. 3.2. Non-compatibility of GCC's -N and static-pie flags Wenn man GCC die –static-pie und -N Flags übergibt kann man beobachten, dass folgendes Executable erzeugt wird:
Das Erste was am Typ des generierten ELFs auffällt ist, das wenn nur –static-pie benutzt wurde es den Typ ET_DYN hatte und jetzt nachdem es mit -N erzeugt wurde es im Typ ET_EXEC resultierte. Betrachtet man die virtuellen Adressen der Segmente genauer, erkennt man, dass das erzeugte Binarz kein Position Independent Exceutable ist. Der Grund dafür ist, dass die virtuellen Adressen absoluten Adressen zu sein schein und nicht relative. Um zu verstehen warum unser Programm nicht wie erwartet gelinkt wurde schauen wir und das Linker Script an und was zum linken benutzt wurde. Da wir den LD Linker von BinUtils benutzen schauen wir uns an wie LD das Linker Skript ausgewählt hat, welches in der Zeile 345 ld/ldmain.c implementiert wird:
Das ldfile_open_default_command_file ist in Wahrheit ein indirekter Aufruf einer zur Compile-Zeit erzeugten Archtitektur unabhängigen Funktion die eine Menge an internen Linker Skripten abhängig von den übergebenen Linker Flags enthält. Da wir die x86_64 Architektur benutzer wird der generierte Source Code ld/elf_x86_64 sein und die Funktion um das Skript auszuwählen ist gldelf_x86_64_get_script, das eine Aneinanderreihung von if-else-if Statements ist um das interne Linker Skript auszuwählen. Die Option -N setzt config.text_read_only auf False wodurch eine Funktion ausgewählt wird, die ein internes Linker Skript auswählt welches kein PIC wie folgt dargestellt wird erzeugt:
Diese Art der Auswahl des standardmäßigen Skripts macht die Flags –static-pie und -N zueinander inkompatibel da die Skript-Auswahl basierend auf -N vor –static-pie durchgeführt wird. 3.3. Überlistung durch eigenes Linker Script Die Inkompabilität zwichen den -N, -statisc und -pie Flags führte uns in ein totes Ende und wir wurden gezwungen andere Ansätze uns zu überlegen um diese Bariere zu überwinden. Was wir versuchten war dem Liner ein eigenes Skript zu übergeben. Da wir das Verhalten von zwei seperaten Linker Skripte zu vereinen war unser Ansatz der, das wir ein Skript auswählten und es derartig anpassten, so das es auch die Ausgabe des 2. Skriptes erzeugt. Wär wählten das Skript mit -static-pie vor dem mit -N da in unserem Fall es einfacher als das -N derartig anzupassen das es auch die PIE Erzeugung unterstützt. Um dieses Ziel zu erreichen müssten wir die Definition der Segmente ändern, die vom PHDRS [5] Feld im Linkr Skript kontrolliert werden. Wenn das Kommando nicht benutzt wird erzeugt der Linker standardmäßig die Program Headers. Wird jedoch das Kommando im Linker Skript vergessen dann erzeugt der Linker keine zusätzlichen Program Headers und es wird einfach die Anweisung und Guidelines des Linker Skripts befolgen. Unter der Berücksichtigung dieser Punkte fügten wir ein PHDRS Kommando dem standard Linker Skript hinzu, das mit dem originalen Segmenten beginnt die mit generell erzeigt werden wenn -static-pie verwendet wird:
Jetzt müssen wir herausbekommen wie jede Section zu jedem Segment gemappt wird. Hierzu können wir readelf wie folgt benutzen:
Mit der Kenntnis der Mappings müssen wir nur noch die Section Output Definition des Linker Scripts ändern. Diese Definition fügt den entsprechende Segment Namen am Ende jeder Funktionsdefinition hinzu wie man im folgenden Beispiel erkennen kann:
Man sieht, dass die .tdata und .tbbs Sections dem Segmenten hinzugefügt werden, die in in der Reihenfolge gemappt werden wie sie in der Ausgabe des "readelf -l" Kommandos gesehen haben. Hierdurch kamen wir zu einem funktionieren Skript, das präzise alle gemappte Sections änderte, die im Data zum Text Segment gemappt wurden:
Wenn man folgendes Test File mit diesem Linker Script kompililiert bekommt man folgendes erzeugte Executable:
Wir haben nun ein static-pie mit nur einem ladbarem Segment. Der selbe Ansatzt kann dafür verwendet werden um andre irrelevante Segmenten zu entfernen um nur die notwendigen kritischen Segementen die zur Ausführung des Binaries zu entfernen. Im folgenden wird beispielsweise ein static-pie Executable gezeigt, das nur die minimal notwendigen Header besitzt, die zur Auführung notwendig sind:
Im folgenden Schaubild wird die finale Ausgabe unserer gewünschten ELF Struktur gezeigt, die nur ein PT_LOAD Segment besitzt und durch ein Linker Skript mit dem PHDRS Kommando erzeugt wurde wie es im folgenden Screenshot gezeigt wird:
4. SHELF Loading Diese erzeugte ELF Variante gibt einem interesante Möglichkeiten die andere ELF Varianten nicht erlauben. Zur Einfachheit haben wir diese Art von ELF Binaries SHELF genannt und diese Variante im folgenden weiterhin so bennenen. Das folgende Schaubild zeigt ein aktualisiertes Diagramm der Loading Stages, die für das SHELF loading benötigt werden:
Wie man im obigen Diagramm erkennen kann ist der Vorgang des Loadings von SHELF files stark in seiner Komplexität im Vergleich zum konventionellen ELF Loadings reduziert. Um die Reduziertheit der Bedingungen des Ladens dieser Typen von Dateien zu zeigen wird im folgenden ein Ausschnit des minimalistischen SHELF User-Land-Exec Ansatzes gezeigt:
Durch die Anwendung dieses Ansatzes sieht ein SHELF File wie folgt im Speicher und auf Disk aus:
Man kann beobachten, dass der ELF und die Program Headers im Process Image fehlen. Dies ist ein Feature on ELF was im nächsten Abschnitt beschrieben wird. 4.1 Anti-Forensische Attribute Dieser neue Ansatz hat auch zwei optionale Stages, die für anti-forensische Zwecke sinvoll sind. Die dl_relocate_static_pie Funktion gibt alle benötigten Felder from Auxiliary Vector zur Relokation zurück. Dies gibt Raum zur Gestaltung des Ziel-SHELF Files in bezug darauf, wie es im Speicher und auf Disk aussehen kann. Die Entfernung des ELF-Headers beinflusst direkt die Rekontruktions-Fähigkeiten, da die meisten Linux basierenden Scanner den Process Speicher auf ELF Header hin untersuchen. Der ELF Header wird analysiert und beinhaltet weitere Informationen darüber wo sich die Programm Header Table befindet und folglich auch der Rest der gemappten Artifakten des Files. Die Entfernung des ELF Headers ist trivial, da dieses Artifakt nicht wirklich vom Loader benötigt wird, denn wie bereits erwähnt wurde werden alle benötigten Informationen aus dem Auxilary Vector gewonnen. Ein zusätzliches Artifakt was verstekt werden kann ist die Programm Header Teable, die ein klein wenig anders zu behandln ist wieder der ELF Header. Der Auxilarz Vector muss die Program Header Table lokalisieren damit der RTLD erfolgreich die Datei durch Runtime Relokationen laden kann. Es gibt verschiedene Ansätze um die PHT zu obfuskieren. Der einfachste Ansatz ist das Entfernen der Program Header Table an der urpsrünglichen Position und sie dann an eine Stelle in der Datei zu setzen, die auch dem Auxilary Vector bekannt ist.
Wir können jede Lokation der Auxilary Vector Einträge vorberechnen und jeden Eintrag als Macro in der Include-Datei deartig setzen dass unserer Loader jedes SHELF File zur Compile-Zeit kennt. Das folgende Schaubild zeigt beispielhaft wie diese Makros erzeugt werden können:
Wie man sieht haben wir das SHELF File auf seine e_entry und e_phnum Felder hin untersucht und entsprechende Makros erzeugt um diese Werte zu sichern. Wir haben auch ein zufälliges Basis Image aufgewählt um das File zu laden. Abschließend lokaliseren wir die PHT und konvertieren es in ein Array und entfernen es an der ursprünglichen Lokation. Wendet man diese Modifikationen an, kann man den ELF Header komplett entfernen und die standardmäßige Adresse des SHELF File PHT sowohl auf Disk als auch im Speicher(!) ändern. Ohne erfolgreiche Wiederherstellung der Program Header Table sind die Rekontruktionsmöglichkeiten stark limitiert und weitere Heuristiken müssen angewendet werden um das Prozess Image wieder herstellen zu können. Ein weiterer Ansatz um die Wiederherstellung der Program Header Table zu erschweren ist die Art wie die GLibC die Auflösund des Auxilary Vector Felder zu intrumentisieren. 4.2 Verschleierungsfähigkeiten von SHELF durch PT_TLS Patching Selbst nachdem man die standarmäßige Position der Program Header Table modifiziert indem man eine beliebige Position bei der Erzeugung des Auxilary Vectors wählt ist die Program Header Table immer noch im Speicher und kann mit etwas Aufwand gefunden werden. Um uns selbst mehr zu Verstecken zeigten wir wie der Startup Code die Auxilary Vector Felder ausliest. Der Programmcode der dies macht befindet sind in elf/dl_support.c in der Funktion _dl_aux_init. Kurzgefasst iteriert dieser Code über alle auxv_t Einträge, die interne Variable von der GlibC initalisieren.
Die internen _dl_* Variablen zu initialiseren ist der einzige Grund wofür der Auxiliary Vector benötigt wird. Mit dieser Kenntnis kann man die Erzeugung des Auxiliary Vectors komplett umgehen und den gleichen Job machen, den _dl_aux_init machen würde bevor die Programmausführung an das Ziel SHELF File übergeben wird. Die einzigen kritischen Einträge sind AT_PHDR, AT_PHNUM, und AT_RANDOM. Daher müssen nur die entsprechenden _dl_* Variablen gepatcht werden die von diesen Feldern abhängen. Den folgenden Einzeiler kann man beispielsweise dafür verwenden um ein Include File mit vorberechneten Macros, die den Offset zu jeder dl_* Variable enthalten, zu erzeugen.
Hat man den Offset zu diesen Variablen lokalisiert muss man diese im orginalen Startup Code so patchen wie man das bei der Verwendung des Auxiliary Vectors machen müsste. Der folgende Code illustriert diese Technik und initialisiert die Adressen des Program Headers mit new_address und korrigiert die Anzahl der Program Headers mit der richtigen Anzahl:
Zu diesem Zeitpunkt haben wir ein funktionierendes Programm ohne den Auxilary Vector mit anzugeben. Da das Ziel Binary statisch gelinkt ist und der Code, der das SHELF File lädt unserer Loader ist können wir alle anderen Segmente im Auxilary Vector's AT_PHDR und AT_PHNUM bzw. dl_phdr und dl_phnum vernachlässigen. Das PT_TLS Segment ist eine Ausnahme, die das Interface ist in welchem der Thread Local Storage im ELF File Format gespeichert wird. Der folgende Code aus der Datei csu/libc-tls.c in der Funktion __libc_setup_tls zeigt den Typ der Information, die aus dem PT_TLS Segment gelesen wird:
In dem obigem Code Stück kann man sehen, dass die TLS Initialisierung von dem Voorhandsein des PT_TLS Segmentes abhängt. Es gibt verschiedene Ansätze die das Artifakt obfuskieren können wie derartige Patchen der __libc_setup_tls Funktion so dass diese einfach abbricht und dann den TLS mit unserem eigenen Code initialisiert. Anstelle eines POCs werden wir einen einfachen Patch implementieren. Um die Notwendigkeit des PT_TLS Program Header zu vermeiden haben wir eine globale Variable hinzugefügt, wie Wir haben eine globale Variable hinzugefügt um die Verwendung des PT_TLS Program Headers zu umgehen. Diese Variable speichert die Werte from PT_TLS und setzt dee Werte in __libc_setup_tls anstelle der SHELF File Program Header Table:
Benutzt man das folgende Skript um _phdr.h zu erzeugen:
Wir können unsere Patche in folgender Art nach dem includen von _phdr.h anwenden:
Wendet man die oben gezeigt Methologie an so gewinnt man ein hohes Level an Evasivität durch das Laden und Ausführen von SHELF Files ohne ELF-Header, Program Header und Auxilialarz Vector - genauso wie Shellcode geladen wird. Das folgende Diagramm zeigt wie einfach der Loading Prozess von SHELF Files ist:
5. Conclusion Wir haben die Interna des Reflective Loadings von ELF Files betrachtet und verschiedene Implementationen von User-Land-Exec mit ihren Vor- und Nachteilen erläutert. Danach haben wir die letzten Patche in der GCC Code Base dargestellt, die Unterstützung für Static-Pie Binaries implementieren und die Ansätze diskutiert um static-pie ELF Files mit einem einzigen PT_LOAD Segment zu erzeugen. Abschließend zeigten wir die anti-forensischen Fähigkeiten, die SHELF Files bieten können von denen wir der Meinung sind, dass diese eine betrachtenswerte Verbesserung darstellen wenn man sie mit vorangegangenden Version des ELF Reflective Loadings vergleicht. Wir sind der Meinung, dass dies die nächste Generation des ELF Reflective Loadings darstellt und den Lesern näherbringt welche Angriffsmöglichkeiten das ELF Datei Format bieten. Der Source Code kann durch kontakieren von @sblip or @ulexec eangefragt werden. 6. Quellenangaben [1] (Unterstützung von static pie) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81498 [2] (Erster gcc Patch) https://gcc.gnu.org/ml/gcc-patches/2017-08/msg00638.html [3] (gcc patch) https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=252034 [4] (glibc --enable-static-pie) https://sourceware.org/git/?p=glibc.git;a=commit; \ h=9d7a3741c9e59eba87fb3ca6b9f979befce07826 [5] (ldscript doc) https://sourceware.org/binutils/docs/ld/PHDRS.html#PHDRS [6] https://sourceware.org/binutils/docs/ld/ Output-Section-Phdr.html#Output-Section-Phdr [7] https://www.akkadia.org/drepper/tls.pdf [8] (warum ld kein -static -pie -N erlaubt) https://sourceware.org/git \ /gitweb.cgi?p=binutils-gdb.git;a=blob;f=ld/ldmain.c; \ h=c4af10f4e9121949b1b66df6428e95e66ce3eed4;hb=HEAD#l345 [9] (grugqs ul_exec Paper) https://grugq.github.io/docs/ul_exec.txt [10] (ELF UPX Interna) https://ulexec.github.io/ulexec.github.io/article \ /2017/11/17/UnPacking_a_Linux_Tsunami_Sample.html