Hay dos "incógnitas" con las que el atacante tiene que lidiar.
Primero, el atacante está desbordando un búfer, supuestamente en la pila, y entre los bytes que siguen al búfer en la RAM están los bytes que almacenan la "dirección de retorno" donde la ejecución salta después de que la función actual finaliza. El atacante desea sobrescribir estos bytes con otra dirección, haciendo que la CPU salte al código escrito por el atacante. La primera incógnita es entonces: "¿cuál es la distancia entre el búfer (que se desborda) y la ranura de dirección de retorno?". El atacante debe adivinar eso, para saber en qué punto de los datos proporcionados por el atacante debe configurarse el "reemplazo de la dirección de retorno".
La segunda incógnita es la dirección real de su código de shell. En un desbordamiento de búfer tradicional en la pila, el código de shell es parte de los datos que activan el desbordamiento, es decir, está en el búfer. La dirección de retorno es absoluta , por lo que no es suficiente que el atacante sepa el código de la función atacada; el atacante también debe saber cuál es la profundidad de la pila en ese momento, y esto depende del comportamiento de la aplicación anterior.
La diapositiva NOP , o trineo NOP, es una técnica sencilla para hacer frente al problema de precisión durante el segundo desconocido. Cuando el atacante adivina la dirección de su código de shell con algún posible jitter, entonces el atacante coloca muchos nop
opcodes (u opcodes igualmente inocuos) antes de su código de shell; por lo tanto, es suficiente que la CPU salte a algún lugar en el sled para que, finalmente, llegue al código de shell.
Para el primer desconocido, la herramienta no es un trineo NOP, sino otro tipo de trineo. En pocas palabras, el desbordamiento completo se verá así:
90 90 90 90 90... 90 shellcode addr addr addr... addr
donde shellcode
es la carga útil real, 90
es el código hexadecimal para el código de operación nop
, y addr
es la estimación del atacante de la dirección de inicio del búfer en la RAM. Cuando se produce el desbordamiento, uno de los valores addr
sobrescribirá la ranura de la dirección de retorno y hará que la CPU salte a la dirección addr
; cuál de los addr
hace el truco es el "primer desconocido" descrito anteriormente. Por lo general, el "primer desconocido" no es tan desconocido, ya que solo depende del diseño de las variables locales en la función en sí, que se conoce a través de la ingeniería inversa (desmontaje).
El atacante ha adivinado que el byte en la dirección addr
será uno de los 90
, por lo que la ejecución salta allí. Cuál no es muy importante, ya que la CPU procederá a ejecutar todos los códigos de operación nop
subsiguientes y luego llegará al shellcode.
Las imágenes que se muestran son bastante confusas. Parecen relacionarse con casos más complejos en los que el atacante, por alguna razón, no puede poner su código de shell inmediatamente después de el trineo NOP, pero en algún lugar antes del trineo NOP, por lo tanto, debe organizar un salto apropiado al final del trineo (los códigos de salto utilizan el direccionamiento relativo, para que sea fácil hacer el salto).