How do hackers attack systems using viruses and malware? Sometimes, it can be ransomware; sometimes, it can be an attack that consumes your system requirements. Buffer overflow is one of these attack methods—but what actually is it? How do these attacks work?

What Is a Buffer Overflow?

So what actually are a buffer and stack? The buffer is a field where some input information you give to your computer wait before they reach the memory. Recalling data from memory is a system-tiring operation. So when there is enough space in the buffer area, you call the data directly from here. This means a performance boost for your device. Of course, when the space available for the buffer is full, it becomes necessary to write it into memory.

Stack is essentially a data structure in which data push (add) and pop (remove) operations take place. The concepts of buffer and stack are quite similar; however, the buffer works like a stack that temporarily stores incoming data.

Buffer overflows can be a challenging topic, but as the name suggests, it occurs when there is an overload of data. For example, you want to log into a system. The developers may allocate 250 bytes of space for the username. If you enter 300 bytes of data, the buffer overflows. This overflow can affect other data in the memory, causing harm.

This is great for hackers. Cybercriminals can combine this mess with different attack vectors, for example, to hack the system and log in as an administrator.

To understand buffer overflow, the main topics you need to recognize will be the CPU's internal architecture, memory registers, and how memory processes data. Here are some terms about the CPU you need to know about.

Assembly Code

A low level programming language, i.e. close to machine language.

Buffer

A fixed size allocated memory space.

Byte Code

A compilable intermediate language form of code written in a high-level language.

Compiler

A program that converts programming language into machine code.

Heap

Dynamic, variable memory space.

The Fundamentals of Memory Theory

Without understanding memory theory, it can be difficult to address buffer overflow issues in practice. You can think of it like trying to build a house without knowing how to make a wall.

Imagine you want to run a buffer overflow from a hacker's point of view. For that, you have to manipulate the memory and have the CPU execute your code. If you were someone with malicious intent, your goal here would be to overload the memory and manipulate contiguous memory areas as well.

Diagram showing stack growing down and heap growing up

But first of all, you need to focus on the concepts of heap, stack, and text segment.

While the stack is being created, memory uses high memory addresses. High memory addresses mean the extended memory area. Then the address values start to decrease. The memory stack uses a method called LIFO (Last In, First Out) during memory usage. Variables in stack memory are valid only within the scope in which they are defined. If they are outside this scope, an error will occur.

Stack memory, on the other hand, works dynamically and does not have to start at high addresses. There is no set limit on heap memory; all limits are set by the operating system. It is possible to change the heap memory dynamically and these limits may alter according to the user's needs during heap usage. The limits of heap memory depend on factors determined by the operating system and hardware. In other words, it offers a dynamic usage within these limits.

The text segment contains the program code and the data segments contain global data. High addresses share stack and heap memory among themselves. The system allocates both memory at runtime.

To better understand buffer overflow, you should examine the general-purpose data registers that your computer architecture uses to store data. Instead of analyzing each record individually, focus on the essentials.

  • ESP (Extended Stack Pointer): This register holds the address at the top of the stack.
  • EBP (Extended Base Pointer): This holds the base pointer.
  • EIP (Extended Instruction Pointer): And this register holds the address of the next instruction to be executed.

These technical terms may sound a bit confusing, but imagine all of them as small partitions on memory.

How Do Buffer Overflow Attacks Work?

When you add new data to any stack, this data will be slotted in at the top. All new data is then moved down. ESP is at the top of the stack. So in this case the ESP goes to a lower memory address. Imagine the data added above pushing the ESP down.

Diagram showing the buffer space being somewhere between ESP and EBP

When a program starts running, the system creates a stack frame with local variables. The main purpose of a buffer overflow attack is to gain access to the EIP or return address. A hacker with access to this address can command it to point to any malicious code they want, which will then affect the wider system.

A diagram showing the data in the ESP targeting the Return Address

With each new bit of data, the stack grows towards the EBP. The real question here is, if we enter too much data, can we push the EBP toward the EIP? That way, the data or code you want is located on the EIP and you can see the results you want. All that remains is to run it. When you run the program, it points to your EIP code and starts execution. As a result, if you were a hacker, you'll have carried out your first buffer overflow attack.

To take the example from a different angle, you can consider liquids of different densities, called ESP, EBP, and EIP, in a container. Imagine that the ESP is located at the top of the container because its density is lower. Just like olive oil and water, they should not mix. The malicious code, then, is another liquid—when you add it to the container, it messes up this balance, displaces some liquid, and mixes with the EIP. This will indicate a buffer overflow.

How to Protect Against Buffer Overflow Attacks

So how do you stop this from happening?

Firstly, it's important to adopt good coding practice throughout the software development process to minimize security vulnerabilities. Carefully written code can reduce the likelihood of buffer overflows.

Another step is to use defense mechanisms to allow monitoring memory regions, checking the limits of buffers, and detecting attacks. Finally, you need to regularly update systems and apply patches. Updates that fix vulnerabilities make it harder for attackers to exploit known vulnerabilities. Also, using defense tools such as software and firewall provides an additional layer of security.

Take Action Against Buffer Overflows

Buffer overflow attacks pose a significant threat to your cybersecurity and taking precautions against them is naturally important. Fortunately, it is possible to block these attacks and strengthen defense mechanisms. Many good security practises, like keeping software updated to fix patches, help protect against such attacks, as well as other vulnerabilities.