Skip to main content
skill CX Codex

binary-hardening — Claude Code skill: what it does, how to install

Configures security flags for C and C++ builds, inspects binaries with checksec, and sets up seccomp-bpf syscall filtering.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add mohitmishra786/low-level-dev-skills --skill binary-hardening -a claude-code
Open on GitHub

What binary-hardening does

The skill guides an agent through hardened compilation and binary auditing for C and C++. It covers analyzing binaries with checksec to verify Full RELRO, stack canaries, NX stack, and PIE.

It provides concrete flag configurations for GCC and Clang, including -fstack-protector-strong, -D_FORTIFY_SOURCE=3, and Clang CFI. It also supplies a C template for seccomp-bpf syscall allowlisting and verification commands using readelf and objdump. Hardware shadow stack and CET options fail to protect execution if the CPU or the running Linux kernel lacks CET support.

What it helps with

  • Inspect compiled binaries with checksec for missing mitigations
  • Configure GCC or Clang builds with Full RELRO, PIE, and stack canaries
  • Restrict Linux syscalls using an allowlist in seccomp-bpf
  • Set up Clang Control Flow Integrity using LTO

Example prompts for the agent

  • Check ./build/app with checksec and explain which mitigations are missing
  • Add Full RELRO, PIE, and stack canary flags to my GCC build script
  • Write a seccomp-bpf allowlist filter for a C service

How to install binary-hardening

1Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill binary-hardening -a claude-code

2Manually: put the files in place

~/.claude/skills/binary-hardening/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/binary-hardening/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about binary-hardening

How do I install binary-hardening in Claude Code?

Run npx skills add mohitmishra786/low-level-dev-skills --skill binary-hardening -a claude-code.

What does the binary-hardening skill do?

It instructs coding agents on applying compiler hardening flags, configuring seccomp-bpf syscall filters, and auditing binaries with checksec.

What is required to enable Clang CFI?

Clang Control Flow Integrity requires Link Time Optimization via -flto and hidden symbol visibility via -fvisibility=hidden.

Source text

SKILL.md · MIT
---
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

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Similar skills

All skills for Security →

From the same set90

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor