🏳️
The CTF Recipes
  • Introduction
  • Cryptography
    • Introduction
    • General knowledge
      • Encoding
        • Character encoding
          • ASCII
          • Unicode
          • UTF-8
        • Data encoding
          • Base16
          • Base32
          • Base64
      • Maths
        • Modular arithmetic
          • Greatest Common Divisor
          • Fermat's little theorem
          • Quadratic residues
          • Tonelli-Shanks
          • Chinese Remainder Theorem
          • Modular binomial
      • Padding
        • PKCS#7
    • Misc
      • XOR
    • Mono-alphabetic substitution
      • Index of coincidence
      • frequency analysis
      • Well known algorithms
        • 🔴Scytale
        • 🔴ROT
        • 🔴Polybe
        • 🔴Vigenere
        • 🔴Pigpen cipher
        • 🔴Affine cipher
    • Symmetric Cryptography
      • AES
        • Block Encryption procedure
          • Byte Substitution
          • Shift Row
          • Mix Column
          • Add Key
          • Key Expansion / Key Schedule
        • Mode of Operation
          • ECB
            • Block shuffling
              • Challenge example
            • ECB Oracle
              • Challenge example
          • CBC
            • Bit flipping
              • Challenge example
            • Padding oracle
              • Challenge example
          • OFB
            • Key stream reconstruction
            • Encrypt to Uncrypt
  • 🛠️Pwn
    • General knowledge
      • STACK
        • Variables storage
        • Stack frame
      • PLT and GOT
      • HEAP
        • HEAP operations
        • Chunk
        • Bins
        • Chunk allocation and reallocation
      • Syscall
    • Architectures
      • aarch32
        • Registers
        • Instruction set
        • Calling convention
      • aarch64
        • Registers
        • Instruction set
        • Calling convention
      • mips32
        • Registers
        • Instruction set
        • Calling convention
      • mips64
        • Registers
        • Instruction set
        • Calling convention
      • x86 / x64
        • Registers
        • Instruction set
        • Calling convention
    • Stack exploitation
      • Stack Buffer Overflow
        • Dangerous functions
          • gets
          • memcpy
          • sprintf
          • strcat
          • strcpy
        • Basics
          • Challenge example
        • Instruction pointer Overwrite
          • Challenge example
        • De Bruijn Sequences
        • Stack reading
          • Challenge example
      • Format string
        • Dangerous functions
          • printf
          • fprintf
        • Placeholder
        • Data Leak
          • Challenge example
        • Data modification
          • Challenge example
      • Arbitrary code execution
        • Shellcode
        • ret2reg
        • Code reuse attack
          • Ret2plt
          • Ret2dlresolve
          • GOT Overwrite
          • Ret2LibC
          • Leaking LibC
          • Ret2csu
          • Return Oriented Programming - ROP
          • Sigreturn Oriented Programming - SROP
          • Blind Return Oriented Programming - BROP
            • Challenge example
          • 🔴Call Oriented Programming - COP
          • 🔴Jump Oriented Programming - JOP
          • One gadget
        • Stack pivoting
    • 🛠️Heap exploitation
      • Heap overflow
        • Challenge example
      • Use after free
        • Challenge example
      • 🛠️Double free
      • 🔴Unlink exploit
    • Protections
      • Stack Canaries
      • No eXecute
      • PIE
      • ASLR
      • RELRO
    • Integer overflow
Powered by GitBook
On this page
  • Bypassing canaries
  • Leak
  • Bruteforce
  1. Pwn
  2. Protections

Stack Canaries

Buffer Overflow prevention

Stack Canaries are very simple - at the beginning of the function, a random value is pushed on the stack. Before the program executes ret, the current value of that variable is compared to the initial: if they are the same, no buffer overflow has occurred.

If they are not, the attacker attempted a buffer overflow to control the return pointer and the program crashes, often with a ***stack smashing detected*** error message.

On Linux, stack canaries end with00. This is so that they null-terminate any strings in case you make a mistake when using print functions, but it also makes them easier to spot.

   address     |   values
---------------+------------------------------------------------------------------
               |   +---------------- HelloWorld stack frame -----------------+
               |   | +------------ stack marge -------------+ +-- canary --+ |
   0xffffd264  |   | | 0x00000000   0x00000000   0x00000000 | | 0x54869500 | | 
               |   | +--------------------------------------+ +------------+ |
               |   +---------------------------------------------------------+
               |   +-------------------- main stack frame -------------------+
               |   | +-saved ebp -+ +-saved eip -+ +---- function params ---+|
   0xffffd274: |   | | 0xffffd298 | | 0x565561dd | | 0x00000001  0x00000002 ||
               |   | +------------+ +------------+ +------------------------+|

Add the parameter -fno-stack-protector using gcc in order to disable stack canary when compiling the binary

Bypassing canaries

Leak

After the canary has been determined, the correct canary value can be rewritten when an overflow occurs.

Bruteforce

The canary is generated randomly for each process at run-time.

For a 32-bits process, there is 4294967296 possibilities, then by injecting random 4 bytes there is a quasi-null but non null possibility to bypass it. On linux there is only 3 bytes to retrieve which is only 16777216 possibilities.

For a 64-bits process there is 1.844674407e+19 possibilities... So this is impossible.

There is still a situation where the canary can be bruteforce: when the process make a fork().

When the process make a fork()the entire process is exactly duplicate, canary included. Then it's possible to guess the canary one byte at a time.

             |   Canary
    Buffer   | 42 52 18 42
 ------------|-------------|
 4141...4141 | 00 52 18 42 | <-- Crash
 4141...4141 | 01 52 18 42 | <-- Crash
 ...         | ...         |
 4141...4141 | 42 52 18 42 | <-- No crash
PreviousProtectionsNextNo eXecute

Last updated 8 months ago

The main aim is to read the value, which can differ from binary to binary. One simple option is to use a if it is present, as the canary, like other local variables, is on the stack and can be easily leaked off the stack through this method.

🛠️
format string