Advanced¶
FORTIFY breakdown¶
fortifyFile and fortifyProc print the per-function FORTIFY picture: which
fortifiable libc calls the binary uses, and which were routed through the
bounds-checked *_chk variants.
$ checksec fortifyProc 1
* Process name (PID) : init (1)
* FORTIFY_SOURCE support available (libc) : Yes
* Binary compiled with FORTIFY_SOURCE support: Yes
------ EXECUTABLE-FILE ------- . -------- LIBC --------
FORTIFY-able library functions | Checked function names
-------------------------------------------------------
read | __read_chk
memcpy | __memcpy_chk
...
SUMMARY:
* Number of checked functions in libc : 78
* Number of FORTIFY-able functions in the executable : 13
* Number of checked functions in the executable : 7
Determining the FORTIFY level
There is no fully reliable way to recover whether a binary was compiled at
_FORTIFY_SOURCE level 1, 2, or 3 unless it carries
annobin notes (see
FORTIFY Lvl). Some binaries embed the
compile command in a string, which you can grep for:
$ strings /usr/bin/vim | grep FORTIFY
... -D_FORTIFY_SOURCE=1
Most binaries don't include this, which is why FORTIFY Lvl reports
Unknown so often outside annobin toolchains.
Cross-compiled / offline filesystems¶
checksec can inspect a cross-compiled target's filesystem offline, with two caveats:
- Kernel checks read live kernel resources, so they must run on the target system — or you must point checksec at the target's kernel config file.
-
FORTIFY resolves libc from the running system by default. For an offline rootfs, point checksec at the target's libc:
checksec file /mnt/target/usr/bin/app --libc /mnt/target/lib/libc.so.6
Alternatively run inside a chroot of the target rootfs. All other checks
work directly against the offline files.
OSX and BSD¶
Most checks target ELF binaries and the Linux kernel. They do not work on Mach-O binaries or the macOS/BSD kernels. checksec may run on some BSD systems but those platforms are not officially supported.
Verifying a release signature¶
Releases are signed with cosign using keyless signing — there is no long-lived public key to distribute. Each release's checksums file is signed in CI, and the signature is tied to the project's GitHub Actions identity and recorded in the public Rekor transparency log.
You'll need cosign installed.
1. Download the checksums file and its signature¶
From the release page (or with
gh release download <tag>), grab:
checksec_checksums.sha512— the checksums of every artifactchecksec_checksums.sha512.sig— its cosign signaturechecksec_checksums.sha512.pem— the signing certificate
2. Verify the checksums file is authentic¶
cosign verify-blob \
--certificate-identity-regexp 'https://github.com/slimm609/checksec/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate checksec_checksums.sha512.pem \
--signature checksec_checksums.sha512.sig \
checksec_checksums.sha512
A successful check prints Verified OK. This proves the checksums file was
produced by the project's release workflow and hasn't been tampered with.
3. Verify your downloaded artifact against the checksums¶
# Run from the directory containing both the artifact and the checksums file
sha512sum --ignore-missing -c checksec_checksums.sha512
This confirms the binary or package you downloaded matches the authenticated checksums.
Older releases
Releases prior to cosign signing used an OpenSSL-based checksec.sig /
checksec.pub scheme. That method is no longer used.