Scene 1: Too Much into Too Little
Yusuf wrote two words on the board: buffer and overflow. He turned to face the class of twelve students. "You already know what a buffer is," he said. "Every program that runs on a computer uses memory to store data temporarily while it is being processed. That reserved area of memory β the space the program sets aside to hold incoming data β is the buffer."
He drew a small rectangle on the board, labelled it buffer, and wrote the number 8 next to it. "This buffer holds 8 bytes. The program was designed expecting that nobody will ever send more than 8 bytes into it. The developer built the program this way."
"Now β what happens if an attacker sends 9 bytes?"
He paused. Several students started to answer, then hesitated. Yusuf continued. "The first 8 bytes fill the buffer exactly as designed. The 9th byte has nowhere to go in the intended space. But it does not simply disappear. It overflows. It spills into whatever memory sits directly next to the buffer β the adjacent memory."
"That," he said, pointing at the word he had written, "is a buffer overflow. Writing more data into a buffer than it was allocated to hold, so the excess spills into adjacent memory areas."
Scene 2: The Developer's Job
A student in the front row raised her hand. "Couldn't the developer just stop this from happening?"
"Exactly the right question," Yusuf said. "And yes β the developer can. The technique is called bounds checking. Before the program writes data into a buffer, it checks whether the incoming data actually fits. If the data is 8 bytes and the buffer holds 8 bytes β fine, proceed. If the data is 9 bytes and the buffer holds 8 bytes β reject it. Stop. Don't write."
He wrote it on the board: Is the data smaller than or equal to the buffer size? If yes: write it. If no: reject it.
"That check is the developer's responsibility," Yusuf said. "If a developer performs proper bounds checking everywhere that data is written into memory, buffer overflows cannot occur. The overflow is stopped before it starts."
"The problem," he continued, "is that developers make mistakes. They forget to add the check. They check the wrong size. They use a function that doesn't check at all. Attackers know this, and they spend a significant amount of time going through applications looking for exactly these openings β places where data flows into memory without a proper bounds check in place."
Scene 3: Harder Than It Looks
"Now," Yusuf said, "you might think: if I find a buffer overflow, I instantly own the system. That's not how it works." He put down the marker. "Buffer overflows are not simple vulnerabilities to exploit. Finding one is the beginning of a long process, not the end."
He explained the problem. When an attacker writes more data than a buffer holds, the overflow corrupts adjacent memory. But adjacent memory may contain anything. If the overflow damages something the program relies on to run correctly, the application crashes. Not a useful outcome for the attacker β a crashed application cannot do anything the attacker wants it to do.
"Attackers spend a lot of time trying different inputs, different amounts of overflow, different positions," he said. "They are trying to find the overflow that corrupts memory in a controlled, predictable way β not one that just crashes everything. The gap between 'I found an overflow' and 'I have a working exploit' is often enormous."
The same student spoke again. "So most overflows just crash things?" "Many of them do, yes," Yusuf said. "An attacker can make an application crash repeatedly. That might be a denial-of-service β stopping the application from working. But if what they really want is to make the application do something specific, crashes are worthless. They need something more precise."
Scene 4: The Requirement for Repeatability
"There is one requirement," Yusuf said, "that separates a truly dangerous buffer overflow from an interesting curiosity. The exploit must be repeatable."
He wrote it on the board and underlined it twice.
"Repeatable means: every time the attacker sends this specific input to this specific application, the same thing happens. Not sometimes. Not most of the time. Every time. The overflow always lands in the same place, always changes memory in the same way, always produces the same outcome." He paused. "When an attacker finds an overflow that is repeatable, the system can be compromised reliably. That overflow can be turned into a tool. It can be automated. It can be deployed against every machine running that software."
"A buffer overflow that crashes the application 60% of the time and does something useful 40% of the time is not particularly dangerous. A buffer overflow that does exactly what the attacker wants 100% of the time β every single attempt β that is what makes an application vulnerable in a serious way."
Scene 5: The Variable A and Variable B Demo
Yusuf turned back to the board and drew a new diagram. Two rectangles, side by side in memory.
"Let me show you a concrete example of what this looks like β and what an attacker can achieve with it." He labelled the first rectangle Variable A and wrote 8 bytes β currently empty (all zeros) beneath it. He labelled the second rectangle Variable B and wrote 2 bytes β current value: 1,979.
"These two variables sit next to each other in memory. Variable A is 8 bytes and is currently empty. Variable B is 2 bytes and currently holds the value 1,979." He turned to the class. "Variable B controls how this application grants rights and permissions. If variable B's value is below 2,000 β user gets guest rights. If variable B's value is above 24,000 β user gets administrator rights."
"Variable B currently sits at 1,979. This user has guest rights. And under normal operation, there is no way for the user to change variable B's value. It is not exposed through the application's interface. It can only be changed from inside the program itself β or so the developer believed."
He circled variable A. "But the attacker has found a vulnerability here. The program allows input to be written into variable A β and it performs no bounds checking. And the attacker knows that if they can write 9 bytes into variable A, the first 8 bytes fill variable A, and the 9th byte overflows into variable B."
"So the attacker chooses their input carefully. They want to write a word into variable A that is exactly 9 characters long. The first 8 characters fill the buffer. The 9th character is the one that matters β it will overflow into variable B and change its value." He wrote on the board: "excessive". "Nine characters. E-X-C-E-S-S-I-V-E."
"The first 8 characters β E, X, C, E, S, S, I, V β are stored in variable A. Everything looks fine so far. Then comes the 9th character: the letter E." He pointed at the diagram. "That E overflows past the end of variable A and lands in variable B."
"In memory, the letter E has a value. Its hexadecimal value is 65. In decimal, that is 101. But that single byte landing in variable B changes variable B's value to 25,856." He wrote the number on the board. "25,856. Is that above 24,000?" He looked at the class. Several students nodded. "The attacker now has administrator rights. No username. No password. No admin credentials of any kind. Just the word 'excessive' sent as input."
Scene 6: The Point
Yusuf set down his marker. "What this example shows is not just how a buffer overflow works mechanically. It shows what the consequence can be. An attacker who finds a repeatable, controlled buffer overflow can change values in memory that the developer never intended to be changeable. In this case, the value that changed controlled administrative access."
"Adjacent memory can hold anything. Another variable. A value that controls permissions. An instruction that determines what the program does next. Every one of those is a potential target if a buffer sits nearby and an attacker can overflow it in a controlled way."
He wrote the three requirements for a dangerous buffer overflow on the board:
1. A buffer with no bounds checking β somewhere data is written without verifying it fits.
2. Something valuable in adjacent memory β a variable, a permission flag, a control structure worth overwriting.
3. Repeatability β the overflow consistently changes adjacent memory in the desired way.
"When all three are present," he said, "the developer has created a door that they didn't know was there. And the attacker walks right through it."