
लिनक्स शेयर्ड लाइब्रेरी से शेलकोड लोडर
Donut Linux के लिए, एक Linux ELF शेयर्ड ऑब्जेक्ट (.so) को एक पोज़ीशन-इंडिपेंडेंट .bin ब्लॉब में रूपांतरित करता है जिसे सीधे मेमोरी से निष्पादित किया जा सकता है (उदाहरण के लिए, इसे mmap'd क्षेत्र में कॉपी करके और एक फंक्शन पॉइंटर के रूप में उस पर जंप करके)।
यह परियोजना जानबूझकर memfd (memfd_create, memfd पर execveat, आदि) से बचती है।
amd64arm64386आवश्यकताएँ:
go generate और परीक्षणों के लिए आवश्यक)CLI बनाएँ:
make
एक hello-world .so बनाएँ, इसे .bin में बदलें, और इसे शामिल रनर के साथ चलाएँ:
# 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
अपेक्षित आउटपुट में शामिल है:
hello from go
रिपॉजिटरी में पूर्व-निर्मित stage0 ब्लॉब्स एम्बेड हैं:
internal/stage0/stage0_linux_amd64.bininternal/stage0/stage0_linux_arm64.bininternal/stage0/stage0_linux_386.binयदि आप internal/stage0/stage0.c या internal/stage0/linker.ld को संपादित करते हैं, तो उन्हें पुनः उत्पन्न करें:
go generate ./...
CLI हमेशा एम्बेडेड stage0 ब्लॉब्स का उपयोग करता है (रनटाइम पर Zig की आवश्यकता नहीं)। stage0 बदलने के लिए, internal/stage0/stage0.c संपादित करें और पुनः चलाएँ:
go generate ./...
testdata/Dockerfile CLI बनाता है, hello .so बनाता है, इसे .bin में बदलता है, Zig के साथ रनर बनाता है, और Linux कंटेनर में एंड-टू-एंड परीक्षण चलाता है।
उदाहरण:
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