
Carregador de Shellcode a partir de Biblioteca Compartilhada Linux
Donut para Linux, converte um objeto compartilhado ELF do Linux (.so) em um blob .bin independente de posição que pode ser executado diretamente da memória (por exemplo, copiando-o para uma região mmap'd e saltando para ele como um ponteiro de função).
Este projeto evita intencionalmente memfd (memfd_create, execveat em memfd, etc).
amd64arm64386Requisitos:
go generate e para testes)Compile a CLI:
make
Compile um .so hello-world, converta-o em um .bin e execute-o com o runner incluído:
# 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
A saída esperada contém:
hello from go
O repositório incorpora blobs stage0 pré-construídos:
internal/stage0/stage0_linux_amd64.bininternal/stage0/stage0_linux_arm64.bininternal/stage0/stage0_linux_386.binSe você editar internal/stage0/stage0.c ou internal/stage0/linker.ld, regenere-os:
go generate ./...
A CLI sempre usa os blobs stage0 incorporados (nenhum Zig necessário em tempo de execução). Para alterar o stage0, edite internal/stage0/stage0.c e execute novamente:
go generate ./...
testdata/Dockerfile compila a CLI, compila o .so hello, converte-o em um .bin, compila o runner com Zig e executa o teste de ponta a ponta em um contêiner Linux.
Exemplos:
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 .
# Ou via Makefile:
make docker-test-386