C binaries: ELF, linking and hardening
You examine the ELF structure, linking and in-memory layout of a compiled C program and ship releases hardened with protections such as ASLR, NX, RELRO and seccomp.
Level 501 · 19 lessons · 18 practice labs
Lessons
ELF and linking
- Anatomy of an ELF file: readelf and objdump
- Sections and segments: .text, .data, .bss
- Symbols and relocations
- Dynamic linking: PLT, GOT and ld.so
- Wrapping functions with LD_PRELOAD, and its risks
- Short task: write the profile of a binary
Runtime memory
- The process memory map: /proc/self/maps
- Stack frames and calling conventions (x86-64)
- Inside malloc: chunks, bins and tcache
- Writing your own allocator: arenas and pools
- Short task: verify your allocator with sanitizers and tests
Hardening
- ASLR and PIE: making addresses unpredictable
- Stack canaries and non-executable memory (NX)
- RELRO and BIND_NOW
- Control-flow integrity and shadow stacks (CET)
- Auditing binaries with checksec
- A system-call filter with seccomp
- Short task: build one program with different protections and compare
Capstone
- Capstone: ship a hardened, audited release
Practice labs
- Extracting section sizes with readelf: Find a binary's .text, .data and .bss sizes with readelf and explain which section a global array lands in.
- Reading an ELF header in C: Write a tool with elf.h that prints a file's class, machine type and entry point and rejects corrupt files.
- Reducing exported symbols: Hide a shared library's unnecessary exported symbols with visibility settings and verify with nm.
- Interpreting relocation records: List the relocation records in an object file and report which calls the linker will resolve.
- Tracing PLT and GOT entries: Show step by step with gdb how a program's puts call is resolved through the PLT and GOT and take notes.
- Faking the clock for tests with LD_PRELOAD: Write an LD_PRELOAD library that returns a fixed time for tests and explain the risk of this technique in privileged programs.
- Making a plugin loader safe: Harden a plugin loader that dlopens from a relative path with absolute paths and ownership and permission checks.
- Writing a simple arena allocator: Write an arena allocator that keeps alignment and frees everything at once, testing that returned addresses are aligned.
- A fixed-size pool allocator: Write a fixed-size pool allocator with a free list that detects and reports a double free.
- Making your allocator visible to ASan: Add ASan poisoning macros to the pool allocator and show that touching a freed block gets caught.
- Comparing PIE and non-PIE binaries: Build the same program with and without PIE and record how /proc/self/maps addresses change between runs.
- Building with full RELRO: Update a Makefile so a service binary is built with full RELRO and BIND_NOW and prove it with checksec.
- Auditing release binaries: Scan five binaries with checksec, find missing protections, fix the build settings and produce a before-and-after table.
- A simple seccomp allow-list: Set up a seccomp filter that allows only read, write and exit and show the process stops on a forbidden call.
- Sandboxing a parser with seccomp: Apply a seccomp filter after the file is opened so the parsing stage cannot open new files, and test it.
- Finding a missing syscall with strace: Use strace to find which call a service needs after it started crashing under seccomp and update the list with least privilege.
- Listing undefined and exported symbols: Complete a small tool that processes nm output and gives a shared library's exported and expected-from-outside symbols as two lists.
- Fixing the public interface with a version script: Write a linker version script that exports only the library's documented functions and verify the previously built program still runs.
About this course
You examine the ELF structure, linking and in-memory layout of a compiled C program and ship releases hardened with protections such as ASLR, NX, RELRO and seccomp.
What you will learn
- ELF and linking
- Runtime memory
- Hardening
- Capstone
Prerequisites
You should be experienced in the topics of the same path up to level 401.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 501; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.