
Caricatore di shellcode da libreria condivisa Linux
Donut per Linux, converte un oggetto condiviso ELF di Linux (.so) in un blob .bin position-independent che può essere eseguito direttamente dalla memoria (ad esempio, copiandolo in una regione mmap'd e saltando ad esso come puntatore a funzione).
Questo progetto evita intenzionalmente memfd (memfd_create, execveat su memfd, ecc.).
amd64arm64386Requisiti:
go generate e per i test)Compila la CLI:
make
Crea un .so hello-world, convertilo in un .bin, ed eseguilo con il runner incluso:
# Build payload .so
go build -buildmode=c-shared -o /tmp/hello.so ./testdata/hello
# Convert .so -> .bin (call the exported symbol "Hello")
./malasada --call-export Hello -o /tmp/hello.bin /tmp/hello.so
# Optional: compress the embedded payload (stage0 will depack before loading)
./malasada --compress --call-export Hello -o /tmp/hello.compressed.bin /tmp/hello.so
# Build the runner (PIC shellcode executor) with zig cc
zig cc -O2 -o /tmp/runner ./testdata/runner/runner.c
# Run it (stage0 hands off to ld-linux; runner will not return)
/tmp/runner /tmp/hello.bin
L'output atteso contiene:
hello from go
Il repository incorpora blob stage0 precompilati:
internal/stage0/stage0_linux_amd64.bininternal/stage0/stage0_linux_arm64.bininternal/stage0/stage0_linux_386.binSe modifichi internal/stage0/stage0.c o internal/stage0/linker.ld, rigenerali:
go generate ./...
La CLI utilizza sempre i blob stage0 incorporati (nessun Zig richiesto a runtime). Per cambiare stage0, modifica internal/stage0/stage0.c ed esegui di nuovo:
go generate ./...
testdata/Dockerfile compila la CLI, crea il .so hello, lo converte in un .bin, compila il runner con Zig ed esegue il test end-to-end in un container Linux.
Esempi:
docker buildx build --platform linux/amd64 -f testdata/Dockerfile .
docker buildx build --platform linux/arm64 -f testdata/Dockerfile .
docker buildx build --platform linux/386 -f testdata/Dockerfile .
# Or via Makefile:
make docker-test-386