Un búfer es un área de memoria asignada previamente donde almacena sus datos mientras los procesa. Básicamente, solo se dice que desde una determinada dirección en la memoria hasta la dirección de la memoria + x Bytes se reserva para asignar datos. En C, esto suele denominarse array .
Se produce un desbordamiento de búfer cuando asigna más datos de los que pueden caber en el búfer y sobrescribe el código más allá de la dirección de memoria + x. Es posible que haya hecho esto antes y notará que su programa se bloquea. Ahora el problema es que en algún lugar más allá de su búfer está la dirección de retorno (esto apunta a la siguiente instrucción que se ejecutará después de asignar el búfer y cargar los datos) y si lo sobrescribe con datos aleatorios, su programa se bloqueará. Sin embargo, si logra cargar código de bytes (este es un programa compilado que la CPU puede ejecutar directamente) y realmente puede hacer que apunte a su programa, entonces puede ejecutar el código en esa máquina.
Ahora puede pensar que esto no es realmente un problema si lo está ejecutando localmente, pero imagine programas como los servidores SSH o FTP que se ejecutan en Internet o imagine un entorno restringido donde ciertos programas se ejecutan con privilegios elevados. Si pudo ejecutar código dentro del contexto y los privilegios del otro programa, podría salir de sus restricciones o tomar el control de un servidor remoto.
Si desea obtener más información sobre el ensamblaje, los flujos de desbordamiento de búfer y el código de shell, sugiero comprar el Manual de Shellcoder. Es el libro EL para aprender esto.