Buffer Overflow Attack from the Ground-up III: Canary

To combat buffer overflow attack, the “canary” stands out as a notable and effective strategy. Canary serves as an early warning system. It is a small, yet crucial, element placed in the stack memory of a program to detect and prevent buffer overflow attacks.

Buffer Overflow Attack from the Ground-up III: Canary
Canary

In previous sections, we learned about buffer overflow attacks and the methods of injecting shell code. This post will introduce a simple protection mechanism against these attacks, as well as ways to bypass some specific canary protections.

Canary

A canary is a bit or some bits placed in the memory before the return address. If the canary has been modified, the program crashes rather than executing the following instructions. This acts as an integrity check to defend against buffer overflow attacks.

By-passing the Canary

In a buffer overflow attack, the philosophy is to change the memory content (especially the return address) by inputting well-constructed inputs. However, if the canary is fixed each time, it can be easily bypassed because an attacker can brute-force the canary bit by bit.

Say the canary is c4n4, at the position staring at the 129th bit after the buffer input point.

Brute Force Canary

We can construct an input of 129 bytes, where the last byte loops from ASCII 0 to 255. Since we did not modify the 130th, 131st, and 132nd bytes, there must be a value in the loop that does not make the program crash. This value is ‘c’, and from this, we know that the 129th byte is ‘c’.

The logic is, the program will not crash once in each loop, then we can get each bits of the canary.

Once we obtain the canary value, we can easily change the return address without altering the canary. Since we already know the canary value, it can be included in the input string.

The following diagram illustrates this action, after we crack the canary, we can change the return address.

The example code is shown in the following code block, the code tries to discover the canary byte by byte. For each byte position, it iterates through all possible byte values (0-255) until it finds the correct one that does not cause the program to crash, indicating the correct canary byte.

More Readings

Buffer Overflow Attack from the Ground-up I: Simple Overflow
Buffer overflow is a security flaw where data exceeds a buffer’s capacity, spilling into neighboring memory. This overflow can corrupt crucial data, causing system instability or even enabling attackers to hijack control.
Buffer Overflow Attack from the Ground-up II: Gadget and Shell Code Injection
The previous post introduced the heap, stack, and buffer overflow on the stack using disassembly and GDB. In ‘Buffer Overflow Attack from the Ground-Up II,’ I will show how to hijack the shell and control the system through the vulnerable program.