Closed
Description
With musl we can generate static binaries just fine. But without much work we can even generate a static position independent executable, which would enable Address Space Layout Randomization for free.
For this to work, we need:
- rustc:
relocation-model=pic
- gcc:
-static-pie
- remove any
-no-pie
- ld.lld has
-pie
or--pic-executable
- replace musl
crt1.o
withrcrt1.o
❯ ldd target/x86_64-unknown-linux-musl/debug/payload
statically linked
❯ file target/x86_64-unknown-linux-musl/debug/payload
../target/x86_64-unknown-linux-musl/debug/payload: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=747e92db7323dd8d1d57474e2a79516727c1b919, with debug_info, not stripped
❯ readelf -l target/x86_64-unknown-linux-musl/debug/payload
Elf file type is DYN (Shared object file)
Entry point 0x3180
There are 10 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000002f30 0x0000000000002f30 R 0x1000
LOAD 0x0000000000003000 0x0000000000003000 0x0000000000003000
0x000000000002a68e 0x000000000002a68e R E 0x1000
LOAD 0x000000000002e000 0x000000000002e000 0x000000000002e000
0x000000000000d95c 0x000000000000d95c R 0x1000
LOAD 0x000000000003c620 0x000000000003d620 0x000000000003d620
0x0000000000001b34 0x0000000000003688 RW 0x1000
DYNAMIC 0x000000000003d990 0x000000000003e990 0x000000000003e990
0x0000000000000130 0x0000000000000130 RW 0x8
NOTE 0x0000000000000270 0x0000000000000270 0x0000000000000270
0x0000000000000024 0x0000000000000024 R 0x4
TLS 0x000000000003c620 0x000000000003d620 0x000000000003d620
0x0000000000000030 0x00000000000000c0 R 0x20
GNU_EH_FRAME 0x0000000000034c1c 0x0000000000034c1c 0x0000000000034c1c
0x0000000000000d54 0x0000000000000d54 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x000000000003c620 0x000000000003d620 0x000000000003d620
0x00000000000019e0 0x00000000000019e0 R 0x1
Section to Segment mapping:
Segment Sections...
00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .rela.dyn
01 .init .text .fini
02 .rodata .debug_gdb_scripts .eh_frame_hdr .eh_frame .gcc_except_table
03 .tdata .data.rel.ro .dynamic .got .data .bss
04 .dynamic
05 .note.gnu.build-id
06 .tdata .tbss
07 .eh_frame_hdr
08
09 .tdata .data.rel.ro .dynamic .got
❯ ../target/x86_64-unknown-linux-musl/debug/payload | grep Entry
aux: Entry(140177653338496)
❯ ../target/x86_64-unknown-linux-musl/debug/payload | grep Entry
aux: Entry(140526706565504)
❯ ../target/x86_64-unknown-linux-musl/debug/payload | grep Entry
aux: Entry(139632460222848)
payload
is a program printing all the AUX vectors, which also contains the entry address of the program. As you can see it changes with every start of the program.