The code in the article is correct. There must be something wrong in your system.
In fact its correct to write the value to the symbol "__stack_chk_guard"
itself. This is done by referencing it and then writing the value there.
What you are doing is: You cast the "void*" to a "uint32_t*", then you dereference it and write the value there; thus you're writing the value to the address 0, not to the address of "__stack_chk_guard".
The purpose of this is that when a vulnerable function is called, the canary is taken from the global variable "__stack_chk_guard". GCC doesn't care for the type of this variable; it assumes that at exactly this location there is a value of the size of a pointer on your architecture, and because we are using "void*" it is correct for all architectures. Also we are only writing an "unsigned char" to it because it is initially set to 0 and like this it works even on a 8bit machine.
EDIT: by the way...
Synon wrote:
The address-of operator is a subtle mistake but the fact that it tries to set an unsigned char (8 bits) to a 32-bit value is glaring.
A void* is not necessarily 4 bytes. On a 64 bit system for example its 8 bytes. It always has the size of a pointer on your respective architecture.
There's absolutely nothing wrong with writing 1 byte (8 bits) to a variable that has a size of 4 bytes (32 bits). For example, if you work on an x86 (uses little endian), only the lowest-order byte of the value is overwritten. A little example:
Code:
uint32_t value = 0xDEADBEEF;
uint8_t* p = (uint8_t*) &value;
p[2] = 0xED;
p[3] = 0xFE;
// value is now 0xFEEDBEEF