La respuesta a esta pregunta dependerá en gran medida de varios factores, incluida la cadena de herramientas utilizada y la arquitectura de destino. Para simplificar, limitaré esta respuesta al Arduino Uno y al microcontrolador AVR ATMega328.
tl; dr: Sí, es posible, pero solo si incluye WriteFlashByte()
, o WriteFlashPage()
en su fuente, y si el atacante tiene acceso a su fuente, o acceso físico a su dispositivo.
Explotaciones de desbordamiento de búfer
Las vulnerabilidades de desbordamiento de búfer son bastante sencillas. La idea general es escribir una carga útil de shellcode en una ubicación conocida en la pila y sobrescribir la dirección de retorno para que apunte a ese shellcode. Esto funciona porque la arquitectura x86 permite la ejecución desde ram. Este no es el único exploit de este tipo, pero es muy común.
Por qué la arquitectura es importante
La arquitectura AVR8 (la utilizada por ATMega micro en Arduino) es lo que se conoce como Harvard Architecture . La parte importante a tener en cuenta aquí es que en la arquitectura de Harvard la "memoria de instrucciones" o "memoria de programa" es completamente independiente de la "memoria de datos". En la arquitectura AVR8, la memoria del programa se implementa en Flash, la memoria de datos se implementa en SRAM y las instrucciones solo se pueden obtener y ejecutar desde la memoria Flash. Lo que esto significa es que el exploit de desbordamiento de búfer descrito anteriormente no funcionará. Puede anular la dirección de retorno, pero la dirección que cambie se leerá en Flash y no en SRAM. Ahora, usted podría pensar que esto haría imposible un aprovechamiento de desbordamiento de búfer, pero no lo hace.
Explotaciones de desbordamiento de búfer AVR8
Dado que la única forma de ejecutar código en un ATMega328 es ejecutar desde la memoria Flash, tendremos que colocar nuestro código de shell en la memoria Flash. Aquí , encontrará un appnote con la información necesaria sobre la lectura / escritura en la memoria flash. Entonces, ahora sabemos que en realidad es posible escribir una carga útil en la memoria del programa durante el tiempo de ejecución, pero hay un problema. La única forma en que podemos escribir datos en flash es usando WriteFlashByte()
o WriteFlashPage()
, y la única forma de usar esas funciones es que ya estén en la memoria Flash de ese dispositivo. Sin embargo, no solo es necesario programar el dispositivo con una de estas funciones, sino que también debe saber la dirección donde reside esa función en la memoria. Hay dos formas de descubrir esta información:
- Compile la fuente usando los indicadores exactos , luego use
avr-objdump
para determinar si estas funciones están presentes y en qué dirección residen.
- Lea el contenido de la memoria Flash presente en la micro, luego use
avr-objdump
para determinar si estas funciones están presentes y en qué dirección residen. Tenga en cuenta que si los bits de bloqueo están establecidos, es posible que no pueda leer el contenido de la memoria Flash.
Si no tiene acceso a la fuente, o no puede leer la memoria flash para volcarla, un ataque de desbordamiento de búfer de este tipo sería casi imposible.