Skip to content
Back to skills

Binary Hardening

ASecurity

Binary hardening skill for security-hardened C/C++ builds. Use when enabling RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI sanitizers, shadow stack, or seccomp-bpf syscall filtering. Covers checksec analysis, compiler and linker flags for hardened builds, and NSA/CISA-recommended mitigations. Activates on queries about binary hardening, checksec, RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI, shadow stack, or seccomp.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 17, 2026
securityrustgoc++bashsecurity

Works with

  • mcp

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 17, 2026

npx -y skills add NetVar1337/agent-skill-canon --skill binary-hardening --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Binary Hardening?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Binary Hardening
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/netvar1337-binary-hardening/badge)](https://www.skillsdirectory.com/skills/netvar1337-binary-hardening)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: binary-hardening
description: Binary hardening skill for security-hardened C/C++ builds. Use when enabling RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI sanitizers, shadow stack, or seccomp-bpf syscall filtering. Covers checksec analysis, compiler and linker flags for hardened builds, and NSA/CISA-recommended mitigations. Activates on queries about binary hardening, checksec, RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI, shadow stack, or seccomp.
---

# Binary Hardening

## Purpose

Guide agents through enabling and verifying binary security mitigations: checksec analysis, compiler and linker hardening flags (RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI), hardware shadow stack, and seccomp-bpf syscall filtering for defense-in-depth.

## Triggers

- "How do I harden my binary against exploits?"
- "How do I check what security mitigations my binary has?"
- "What does checksec output mean?"
- "How do I enable RELRO, PIE, and stack canaries?"
- "How do I use seccomp to restrict syscalls?"
- "How do I enable CFI (control flow integrity)?"

## Workflow

### 1. Analyze existing binary with checksec

```bash
# Install checksec
pip install checksec.py   # or: apt install checksec

# Check a binary
checksec --file=./mybinary
checksec --file=/usr/bin/ssh

# Output example
# RELRO          STACK CANARY   NX    PIE    RPATH  RUNPATH  Symbols  FORTIFY  Fortified  Fortifiable  FILE
# Full RELRO     Canary found   NX    PIE    No RPATH  No RUNPATH  No Symbols  Yes   6   10   ./mybinary

# Check all binaries in a directory
checksec --dir=/usr/bin
```

| Protection | Good value | Concern |
|-----------|-----------|---------|
| RELRO | Full RELRO | Partial / No RELRO |
| Stack Canary | Canary found | No canary |
| NX | NX enabled | NX disabled |
| PIE | PIE enabled | No PIE |
| FORTIFY | Yes | No |

### 2. Hardening compiler and linker flags

```bash
# Full hardened build (GCC or Clang)
CFLAGS="-O2 -pipe \
  -fstack-protector-strong \
  -fstack-clash-protection \
  -fcf-protection \
  -D_FORTIFY_SOURCE=3 \
  -D_GLIBCXX_ASSERTIONS \
  -fPIE \
  -Wformat -Wformat-security -Werror=format-security"

LDFLAGS="-pie \
  -Wl,-z,relro \
  -Wl,-z,now \
  -Wl,-z,noexecstack \
  -Wl,-z,separate-code"

gcc ${CFLAGS} -o prog main.c ${LDFLAGS}
```

Flag reference:

| Flag | Protection | Notes |
|------|-----------|-------|
| `-fstack-protector-strong` | Stack canary | Stronger than `-fstack-protector` |
| `-fstack-clash-protection` | Stack clash | Prevents huge stack allocations |
| `-fcf-protection` | Intel CET (IBT+SHSTK) | x86 hardware CFI (kernel+CPU required) |
| `-D_FORTIFY_SOURCE=2` | Buffer overflow checks | Adds bounds checks to string/mem functions |
| `-D_FORTIFY_SOURCE=3` | Enhanced FORTIFY | GCC ≥12, Clang ≥12 |
| `-fPIE` + `-pie` | PIE/ASLR | Position independent executable |
| `-Wl,-z,relro` | Partial RELRO | Makes GOT read-only before `main` |
| `-Wl,-z,now` | Full RELRO | Resolves all PLT at startup → GOT fully RO |
| `-Wl,-z,noexecstack` | NX stack | Marks stack non-executable |

### 3. Control Flow Integrity (CFI)

Clang's CFI prevents calling virtual functions through wrong types (vtable CFI) and indirect calls to mismatched functions:

```bash
# Clang CFI — requires LTO and visibility
clang -fsanitize=cfi -fvisibility=hidden -flto \
      -O2 -fPIE -pie main.cpp -o prog

# Specific CFI checks
clang -fsanitize=cfi-vcall          # virtual call type check
clang -fsanitize=cfi-icall          # indirect call type check
clang -fsanitize=cfi-derived-cast   # derived-to-base cast
clang -fsanitize=cfi-unrelated-cast # unrelated type cast

# Cross-DSO CFI (across shared libraries — more complex)
clang -fsanitize=cfi -fsanitize-cfi-cross-dso -flto -fPIC -shared
```

```bash
# Microsoft CFG (Windows equivalent)
cl /guard:cf prog.c
link /guard:cf prog.obj
```

### 4. Stack canaries in depth

```bash
# GCC canary options
-fno-stack-protector       # disabled
-fstack-protector          # protect functions with alloca or buffers > 8 bytes
-fstack-protector-strong   # protect functions with local arrays/addresses taken
-fstack-protector-all      # protect all functions (slowest, most complete)

# Verify canary presence
objdump -d prog | grep -A5 "__stack_chk"
readelf -s prog | grep "stack_chk"
```

### 5. FORTIFY_SOURCE

FORTIFY_SOURCE wraps unsafe libc functions (memcpy, strcpy, sprintf) with bounds-checked versions when the buffer size can be determined at compile time:

```bash
# Level 2 (GCC/Clang default for hardened builds)
-D_FORTIFY_SOURCE=2
# Runtime check: abort() on overflow

# Level 3 (GCC ≥12, catches more cases)
-D_FORTIFY_SOURCE=3
# Adds dynamic buffer size tracking for more coverage

# Check FORTIFY coverage
objdump -d prog | grep "__.*_chk"     # fortified variants
checksec --file=prog | grep FORTIFY
```

### 6. seccomp-bpf syscall filtering

```c
#include <seccomp.h>

void apply_seccomp_filter(void) {
    scmp_filter_ctx ctx;

    // Default: kill process on any non-allowlisted syscall
    ctx = seccomp_init(SCMP_ACT_KILL_PROCESS);

    // Allowlist needed syscalls
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0);

    // Apply filter (irreversible after this point)
    seccomp_load(ctx);
    seccomp_release(ctx);
}

// Call early in main(), after all setup
int main(void) {
    // ... initialization ...
    apply_seccomp_filter();
    // ... restricted operation ...
}
```

```bash
# Test seccomp filter with strace
strace -e trace=all ./prog 2>&1 | grep "killed by SIGSYS"

# Profile syscalls to build allowlist
strace -c ./prog    # count all syscalls used
```

### 7. Intel CET (Shadow Stack + IBT)

```bash
# Full CET: SHSTK (shadow stack) + IBT (indirect branch tracking)
gcc -fcf-protection=full -O2 -o prog main.c

# Verify in binary
readelf -n prog | grep -E 'SHSTK|IBT'
readelf --notes prog | grep GNU_PROPERTY

# IBT landing pads in disassembly
objdump -d prog | grep endbr64

# CPU and kernel support
grep -m1 shstk /proc/cpuinfo
```

Requires hardware CET support (Intel Tiger Lake+ for SHSTK/IBT; AMD Zen 3+ for shadow stack on supported SKUs) and a kernel built with CET enabled.

### 8. ARM BTI and PAC (AArch64)

```bash
# Branch Target Identification + Pointer Authentication
gcc -mbranch-protection=standard -O2 -o prog main.c
# Or: -mbranch-protection=bti+pauth

readelf -n prog | grep -E 'BTI|PAC'
llvm-objdump -d prog | grep bti
```

| Feature | Protects |
|---------|----------|
| BTI | Indirect branch to non-marked targets |
| PAC | Signed return addresses and pointers (ARMv8.3+) |

### 9. ARM Memory Tagging (MTE)

```bash
# Userspace MTE tagging (experimental, arm64 hardware)
clang -fsanitize=memtag -g -o prog main.c

# Check MTE CPU support
grep -m1 mte /proc/cpuinfo
```

MTE assigns 4-bit tags to 16-byte granules — hardware detects tag mismatch on access.

### 10. glibc shadow stack (2.39+)

```bash
# Recent glibc may enable shadow stack for CET when hardware supports SHSTK
ldd --version   # feature availability varies by distro glibc build

# Explicit link with shadow stack support (toolchain dependent)
gcc -fcf-protection=full -Wl,-z,shstk -o prog main.c

# Verify GNU_PROPERTY_SHSTK in output
readelf -n prog | grep SHSTK
```

Shadow stack maintains a hardware-protected copy of return addresses separate from the data stack.

For the full hardening flags reference, see [references/hardening-flags.md](references/hardening-flags.md).

## Related skills

- Use `skills/runtimes/sanitizers` for ASan/UBSan during development
- Use `skills/observability/ebpf` for seccomp-bpf program writing with libbpf
- Use `skills/rust/rust-security` for Rust's memory-safety hardening approach
- Use `skills/binaries/elf-inspection` to verify mitigations in ELF binaries

Files in this skill

  • SKILL.md7.8 KB
  • references/hardening-flags.md2.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.