Abstract
It is hard to say exactly when their story began; chances are that at the beginning they were thought of as just handy tricks to assist more important techniques rather than the essence of exploitation. The classic " Smashing the Stack for Fun and Profit " by Aleph One 11 manages to explain the conversion of an implicit input data flow into altered program control flow in two short paragraphs: So a buffer overflow allows us to change the return address of a function. In this way we can change the flow of execution of the program.... strcpy() will then copy the shellcode onto buffer without doing any bounds checking, and will overflow the return address, overwriting it with the address where our code is now located. Once we reach the end of main and it tried to return it jumps to our code, and execs a shell. For readers who concentrated on the details of constructing the shellcode (and encountered a hands-on exposition of syscalls and ABI for the first time), it was easy to miss the fact that both the implicit data flow and the subsequent transfer of control were performed by the program’s own code, borrowed by the exploit for its own purposes. Yet it was this borrowed code, the copying loop of strcpy() and the function’s post-amble, that added up to the " remote execution " call as good as any API, into which the shellcode was fed. This borrowing turned out to be crucial, far more important than the details of shellcode’s binary instructions, as Solar Designer showed next year (1997): more of the target’s code could be borrowed. In fact, enough code could be borrowed that there was no longer any need to bring any of your own executable code to drop a shell\textemdash the target process’s runtime already conveniently included such code, in libc. One just needed to arrange the overwriting stack data the way that borrowed code expected it, faking a stack frame and giving control to the snippet inside libc’s exec().