Imagine two houses on the street. One is your friend's house and one is his evil paranoid neighbor's house three doors down. The evil paranoid neighbor never enters or leaves, and his place is locked up tight.
Now, your friend is such a good trusting friend, he'll let you store anything in his place, putting down boxes one after the other, starting at one wall. In fact, he's such a good friend that he'll keep putting down boxes one after the other, without checking to see if he's hit the wall, until they keep going in midair and finally pass right through two other houses on the street and into the evil paranoid neighbor's house. But your friend trusts you won't do that because he likes you (and he's a little naive).
So you have the opportunity to put something into the evil paranoid neighbor's house by exploiting your good trusting friend.
Replace the following terms and you'll see the analogy to a buffer overflow attack:
- "your friend's house" --> "a portion of a program that doesn't check for buffer overflow"
- "his evil paranoid neighbor's house" --> "another portion of a program that is supposed to be secure"
- "boxes" --> "arguments/parameters to the program that doesn't check for buffer overflow"
This is successful only if someone figures out where the secure area of memory is, and what would have to be passed as an argument to the program in question, that would end up in the secure area, to have the desired effect. (whether it's data, or code that causes the exploiter's code to be executed)