but there are other, far more subtle mistakes that can create potential buffer over-
flow bugs.
One technique that aims to automatically prevent these problems from occur-
ring is by the use of automatic, compiler-generated stack checking. The idea is
quite simple: For any function that accesses local variables by reference, push an
extra cookie or canary to the stack between the last local variable and the func-
tion’s return address. This cookie should then be validated before the function
returns to the caller. If the cookie has been modified, program execution imme-
diately stops. This ensures that the return value hasn’t been overwritten with
some other address and prevents the execution of any kind of malicious code.
One thing that’s immediately clear about this approach is that the cookie must
be a random number. If it’s not, an attacker could simply add the cookie’s value
as part of the overflowing payload and bypass the stack protection. The solution
is to use a pseudorandomnumber as a cookie. If you’re wondering just how ran-
dom pseudorandom numbers can be, take a look at [Knuth2] Donald E. Knuth.
The Art of Computer Programming—Volume 2: Seminumerical Algorithms (Second
Edition).Addison Wesley, but suffice it to say that they’re random enough for
this purpose. With a pseudorandom number, the attacker has no way of know-
ing in advance what the cookie is going to be, and so it becomes impossible to
fool the cookie verification code (though it’s still possible to work around this
whole mechanism in other ways, as explained later in this chapter).
The following code is the same launchfunction from before, except that
stack checking has been added (using the /GSoption in the Microsoft C/C++
compiler).
Chapter7!launch:
00401060 sub esp,0x68
00401063 mov eax,[Chapter7!__security_cookie (0040a428)]
00401068 mov [esp+0x64],eax
0040106c mov eax,[esp+0x6c]
00401070 lea edx,[esp]
00401073 sub edx,eax
00401075 mov cl,[eax]
00401077 mov [edx+eax],cl
0040107a inc eax
0040107b test cl,cl
0040107d jnz Chapter7!launch+0x15 (00401075)
0040107f push edi
00401080 lea edi,[esp+0x4]
00401084 dec edi
00401085 mov al,[edi+0x1]
00401088 inc edi
00401089 test al,al
0040108b jnz Chapter7!launch+0x25 (00401085)
0040108d mov eax,[Chapter7!'string’ (00408128)]
00401092 mov cl,[Chapter7!'string’+0x4 (0040812c)]
Auditing Program Binaries 251