In modern Linux system administration, DevSecOps pipelines, and binary reverse engineering, verifying that compiled executables have incorporated essential compiler hardening mitigations is vital for system defence. Without security flags like Position Independent Executables (PIE), Stack Canaries, and Relocation Read-Only (RELRO), software remains vulnerable to buffer overflows, return-oriented programming (ROP) exploits, and memory corruption attacks. checksec is a battle-tested command-line utility that inspects ELF (Executable and Linkable Format) binaries to provide an instant audit of their active compiler mitigations.
Core Binary Hardening Protections Explained
When checksec analyses an application, it evaluates five critical binary security properties:
| Security Flag | Compiler Mechanism | Security Purpose |
|---|---|---|
| RELRO (Relocation Read-Only) | -Wl,-z,relro -Wl,-z,now |
Makes the Global Offset Table (GOT) read-only after dynamic loading to prevent GOT overwrite attacks |
| Stack Canary | -fstack-protector-strong |
Inserts a pseudo-random integer guard token before the return address to detect stack buffer overflows |
| NX (No-Execute) | -Wl,-z,noexecstack |
Marks the application stack and heap memory pages as non-executable, stopping raw shellcode execution |
| PIE (Position Independent Executable) | -fPIE -pie |
Loads the binary at randomised virtual memory addresses on each launch alongside kernel ASLR |
| FORTIFY_SOURCE | -D_FORTIFY_SOURCE=2 |
Replaces unsafe C standard library calls (like strcpy or sprintf) with bounds-checked variants |
Installing checksec on Major Linux Distributions
checksec is maintained both as a lightweight POSIX shell script and as a modern Python package. You can install it quickly using standard package managers:
| Distribution / Platform | Installation Command |
|---|---|
| Ubuntu / Debian | sudo apt update && sudo apt install checksec |
| Arch Linux / Manjaro | sudo pacman -S checksec |
| Fedora / RHEL (EPEL) | sudo dnf install checksec |
| Universal Python (Pipx) | pipx install checksec-py |
Auditing an Individual Binary Executable
To inspect an individual program file, invoke checksec with the --file flag:
checksec --file=/bin/ls
checksec parses the ELF headers and outputs a clean, colour-coded terminal summary:
RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH /bin/ls
In this output, green highlights indicate robust hardening. If a flag displays red (such as No RELRO or No Canary found), the binary was compiled without essential protective boundaries.
Auditing Running Processes in Memory
You can also audit active processes running on your Linux host. This is especially useful for inspecting web servers, container entry points, and network daemons:
checksec --proc-all
To evaluate a specific daemon by its process identifier (PID), pass the process ID directly:
checksec --proc=1234
checksec inspects the memory mapping in /proc/1234/maps to confirm whether memory pages have been correctly set with non-executable permissions.
Auditing Entire Directories and Outputting JSON for CI/CD
In automated DevSecOps pipelines and firmware analysis workflows, you often need to audit entire application directories and parse results programmatically:
- To recursively audit an entire binary directory (such as
/usr/local/bin):checksec --dir=/usr/local/bin - To output the findings in structured JSON for automated ingestion by vulnerability scanners:
checksec --dir=/usr/local/bin --format=json > audit_report.json
Using tools like jq, you can parse the resulting JSON file and fail automated build steps if any executable lacks Full RELRO or Stack Canary protection:
cat audit_report.json | jq '.[] | select(.pie == "no")'
Integrating checksec into your regular Linux maintenance and deployment audits ensures that software packages uphold modern defence-in-depth principles before exposing services to network traffic.