Por lo general, no, las explotaciones de desbordamiento de búfer no se trata de sobrescribir el código. Pero hay problemas de definición.
Un exploit de desbordamiento de búfer (del tipo "escritura") aprovecha una situación en la que se puede hacer que el sistema de destino escriba más datos de los que caben en el área en la que escribe, sobrescribiendo así todo lo que haya en la RAM junto al búfer, con datos que pueden ser más o menos controlados por el atacante. La técnica de explotación clásica consiste en ubicar en los datos sobrescritos un puntero al código que, en algún momento, será seguido por la aplicación de destino. Por lo tanto, el atacante puede hacer que la aplicación descarrile y obtener instrucciones de ejecución que están en otro lugar en la RAM.
Mientras el código está en la RAM, la mayoría, si no todo, está en las secciones de solo lectura; el sistema operativo utiliza la MMU de la plataforma para marcar estas secciones como tales, y cualquier intento de escribir sobre el código activará una excepción en el núcleo del sistema operativo. Además, en un sistema típico, las secciones de código y las secciones de datos están bastante alejadas en el espacio de direcciones, lo que dificulta el intento de saturación.
Una situación muy clásica es cuando el búfer desbordado está en la pila (en el lenguaje C, es una "variable local"), porque la pila también incluye punteros a código, a saber, el puntero de instrucción guardado . Cuando se ingresa una función, el puntero de instrucción se guarda en la pila, de modo que cuando la función regresa, la ejecución puede saltar al sitio de llamada. Este puntero de instrucciones guardado es, por lo tanto, un puntero de código que se seguirá en algún momento de la ejecución, por lo que es un objetivo primordial para los desbordamientos.
Otro caso bastante común está relacionado con el uso de vtables en idiomas que admiten un estilo de desarrollo orientado a objetos (normalmente C ++, pero "C orientado a objetos" también calificaría). Vtables son tablas en RAM, llenas de punteros a funciones, que se siguen cuando se invocan métodos. Tales punteros son buenos objetivos para explotaciones de desbordamiento (el Jailbreak de PS3 funcionaba de esa manera).
Ahora hay idiomas que no están compilados a instrucciones en bruto, sino a un formato especial llamado código enlazado . El código roscado es básicamente una larga sucesión de punteros a código (a otro código roscado, oa secuencias de instrucciones nativas). Esto es típico de los idiomas que aceptan el código de construcción en tiempo de ejecución, es decir, cosas que a menudo se describen como "intérpretes". Un desbordamiento de búfer en ese contexto podría llevar a una sobrescritura del código (subprocesado) porque, desde el punto de vista del kernel y la CPU, el código enhebrado es información. Esta es la parte donde los detalles de la definición pueden morderte.
Tenga en cuenta que todo lo anterior se trata de un desbordamiento donde los datos se escriben en un búfer y pasan ese búfer. También hay desbordamientos de "lectura" (tal vez el término "saturación" sería más apropiado), en el que los datos se leen más allá de un búfer de origen (y probablemente se escriben en otro búfer). Esto puede llevar a la fuga de secretos, y también a la aplicación que trabaja en datos inconsistentes. Las consecuencias varían mucho, según lo que la aplicación haga con los datos. Esto puede ser muy inconveniente, es decir, muy conveniente para un atacante, si el desbordamiento es tal que el atacante obtiene partes de claves criptográficas u otros datos confidenciales.