Análisis profundo de la vulnerabilidad de seguridad en el lenguaje Move
Recientemente, durante nuestra investigación profunda sobre Aptos Moveevm, descubrimos una nueva vulnerabilidad de desbordamiento de enteros. El proceso de activación de esta vulnerabilidad es bastante interesante, a continuación, realizaremos un análisis profundo y presentaremos el conocimiento de fondo relacionado con el lenguaje Move. A través de esta explicación, creemos que los lectores podrán tener una comprensión más profunda del lenguaje Move.
El lenguaje Move realiza una verificación de unidades de código antes de ejecutar el bytecode, y este proceso se divide en 4 pasos. La vulnerabilidad discutida en este artículo se presenta en el paso reference_safety.
El módulo reference_safety define una función de transferencia utilizada para verificar la seguridad de las referencias del sujeto del proceso. Principalmente, revisa si existen referencias colgantes, si el acceso a las referencias mutables es seguro, si el acceso a las referencias de almacenamiento global es seguro, entre otros problemas.
El proceso de verificación comienza con la función de entrada de verificación de seguridad, que llamará a analyze_function. En analyze_function, se verificará cada bloque básico. Un bloque básico es una secuencia de código que no tiene instrucciones de bifurcación, excepto por la entrada y la salida.
El lenguaje Move identifica bloques básicos mediante la exploración de los bytecodes, buscando todas las instrucciones de bifurcación y secuencias de instrucciones de bucle. Un ejemplo típico de un bloque básico de código IR de Move podría contener 3 bloques básicos, determinados por las instrucciones BrTrue, Branch y Ret.
El lenguaje Move admite dos tipos de referencias: referencias inmutables (&) y referencias mutables (&mut). Las referencias inmutables se utilizan para leer datos, mientras que las referencias mutables se utilizan para modificar datos. Este diseño ayuda a mantener la seguridad del código y a identificar los módulos de lectura.
El proceso principal de verificación de seguridad de referencias incluye: escanear las instrucciones de bytes de los bloques básicos en la función y determinar si todas las operaciones de referencia son legales. Este proceso utiliza la estructura AbstractState, que contiene el grafo de préstamos y las variables locales, para garantizar la seguridad de las referencias en la función.
Durante el proceso de verificación se ejecutará el código del bloque básico, generando el estado post, luego se combinarán el estado pre y el estado post para actualizar el estado del bloque, y se propagará la condición posterior del bloque a los bloques posteriores. Este proceso es similar a la idea Sea of Nodes en V8 turbofan.
La vulnerabilidad se encuentra en la función join_. Cuando la suma de la longitud de los parámetros y la longitud de las variables locales es mayor a 256, se produce un desbordamiento de entero debido a que local es de tipo u8. Aunque Move tiene un proceso para verificar la cantidad de locals, en el módulo de verificación de límites solo se verifica los locals, sin incluir la longitud de los parámetros.
Esta vulnerabilidad de desbordamiento de enteros puede llevar a ataques de DoS. Al crear un bloque de código en bucle y aprovechar el desbordamiento para cambiar el estado del bloque, se puede hacer que el nuevo mapa de locales sea diferente del anterior. Cuando se vuelve a ejecutar la función execute_block, si el índice que la instrucción necesita acceder no existe en el nuevo mapa de locales de AbstractState, se producirá un DoS.
Hemos descubierto que los códigos de operación MoveLoc/CopyLoc/FreeRef en el módulo de referencia de seguridad pueden lograr este objetivo. Tomando como ejemplo la función copy_loc, si LocalIndex no existe, causará un pánico, lo que hará que todo el nodo se bloquee.
Para verificar esta vulnerabilidad, hemos escrito un PoC. El bloque de código en este PoC contiene una instrucción de salto incondicional que, cada vez que se ejecuta la última instrucción, regresa a la primera instrucción, por lo que este bloque de código llamará varias veces a las funciones execute_block y join.
Al establecer los parámetros adecuados, podemos hacer que la longitud del nuevo mapa de locales sea 8. En la segunda ejecución de la función execute_block, debido a que la longitud de locales es insuficiente, se producirá un panic.
Esta vulnerabilidad nos recuerda que incluso lenguajes que enfatizan la seguridad como Move pueden tener fallas. Sugerimos a los diseñadores del lenguaje Move que añadan más código de verificación en tiempo de ejecución para prevenir situaciones inesperadas. Actualmente, el lenguaje Move realiza verificaciones de seguridad principalmente en la fase de verificación, pero esto puede no ser suficiente. Una vez que la verificación es eludida, si no hay suficientes refuerzos de seguridad en la fase de ejecución, esto podría llevar a problemas más graves.
Como líder en la investigación de seguridad del lenguaje Move, continuaremos investigando en profundidad los problemas de seguridad de Move y compartiremos más hallazgos en el futuro.
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
12 me gusta
Recompensa
12
8
Compartir
Comentar
0/400
AirdropHunterXiao
· Hace46m
Cavando, cavando, ¡hay trabajo bueno otra vez!
Ver originalesResponder0
ChainSherlockGirl
· hace9h
¡Ja! Otro teatro de vulnerabilidades de seguridad on-chain, esta vez es una gran obra de desbordamiento de enteros protagonizada por Move~ Según mi análisis personal, probablemente algún Grandes inversores quiera aprovechar la oportunidad para hacer shorting.
Ver originalesResponder0
SerumSquirter
· hace14h
Otro problema de seguridad, se acabó.
Ver originalesResponder0
rugged_again
· hace14h
Ya salió del agujero, se escapó.
Ver originalesResponder0
LiquidatedDreams
· hace14h
¿Quién todavía juega a move?
Ver originalesResponder0
DarkPoolWatcher
· hace14h
Aptos realmente no es confiable, hay un montón de vulnerabilidades.
Ver originalesResponder0
MondayYoloFridayCry
· hace14h
¿Ya se movió el negro? Tsk tsk tsk
Ver originalesResponder0
PretendingSerious
· hace14h
Este agujero es demasiado evidente, la base de desarrollo no es sólida.
Vulnerabilidades de referencia en el lenguaje Move: riesgo de desbordamiento de enteros y recomendaciones de prevención
Análisis profundo de la vulnerabilidad de seguridad en el lenguaje Move
Recientemente, durante nuestra investigación profunda sobre Aptos Moveevm, descubrimos una nueva vulnerabilidad de desbordamiento de enteros. El proceso de activación de esta vulnerabilidad es bastante interesante, a continuación, realizaremos un análisis profundo y presentaremos el conocimiento de fondo relacionado con el lenguaje Move. A través de esta explicación, creemos que los lectores podrán tener una comprensión más profunda del lenguaje Move.
El lenguaje Move realiza una verificación de unidades de código antes de ejecutar el bytecode, y este proceso se divide en 4 pasos. La vulnerabilidad discutida en este artículo se presenta en el paso reference_safety.
El módulo reference_safety define una función de transferencia utilizada para verificar la seguridad de las referencias del sujeto del proceso. Principalmente, revisa si existen referencias colgantes, si el acceso a las referencias mutables es seguro, si el acceso a las referencias de almacenamiento global es seguro, entre otros problemas.
El proceso de verificación comienza con la función de entrada de verificación de seguridad, que llamará a analyze_function. En analyze_function, se verificará cada bloque básico. Un bloque básico es una secuencia de código que no tiene instrucciones de bifurcación, excepto por la entrada y la salida.
El lenguaje Move identifica bloques básicos mediante la exploración de los bytecodes, buscando todas las instrucciones de bifurcación y secuencias de instrucciones de bucle. Un ejemplo típico de un bloque básico de código IR de Move podría contener 3 bloques básicos, determinados por las instrucciones BrTrue, Branch y Ret.
El lenguaje Move admite dos tipos de referencias: referencias inmutables (&) y referencias mutables (&mut). Las referencias inmutables se utilizan para leer datos, mientras que las referencias mutables se utilizan para modificar datos. Este diseño ayuda a mantener la seguridad del código y a identificar los módulos de lectura.
El proceso principal de verificación de seguridad de referencias incluye: escanear las instrucciones de bytes de los bloques básicos en la función y determinar si todas las operaciones de referencia son legales. Este proceso utiliza la estructura AbstractState, que contiene el grafo de préstamos y las variables locales, para garantizar la seguridad de las referencias en la función.
Durante el proceso de verificación se ejecutará el código del bloque básico, generando el estado post, luego se combinarán el estado pre y el estado post para actualizar el estado del bloque, y se propagará la condición posterior del bloque a los bloques posteriores. Este proceso es similar a la idea Sea of Nodes en V8 turbofan.
La vulnerabilidad se encuentra en la función join_. Cuando la suma de la longitud de los parámetros y la longitud de las variables locales es mayor a 256, se produce un desbordamiento de entero debido a que local es de tipo u8. Aunque Move tiene un proceso para verificar la cantidad de locals, en el módulo de verificación de límites solo se verifica los locals, sin incluir la longitud de los parámetros.
Esta vulnerabilidad de desbordamiento de enteros puede llevar a ataques de DoS. Al crear un bloque de código en bucle y aprovechar el desbordamiento para cambiar el estado del bloque, se puede hacer que el nuevo mapa de locales sea diferente del anterior. Cuando se vuelve a ejecutar la función execute_block, si el índice que la instrucción necesita acceder no existe en el nuevo mapa de locales de AbstractState, se producirá un DoS.
Hemos descubierto que los códigos de operación MoveLoc/CopyLoc/FreeRef en el módulo de referencia de seguridad pueden lograr este objetivo. Tomando como ejemplo la función copy_loc, si LocalIndex no existe, causará un pánico, lo que hará que todo el nodo se bloquee.
Para verificar esta vulnerabilidad, hemos escrito un PoC. El bloque de código en este PoC contiene una instrucción de salto incondicional que, cada vez que se ejecuta la última instrucción, regresa a la primera instrucción, por lo que este bloque de código llamará varias veces a las funciones execute_block y join.
Al establecer los parámetros adecuados, podemos hacer que la longitud del nuevo mapa de locales sea 8. En la segunda ejecución de la función execute_block, debido a que la longitud de locales es insuficiente, se producirá un panic.
Esta vulnerabilidad nos recuerda que incluso lenguajes que enfatizan la seguridad como Move pueden tener fallas. Sugerimos a los diseñadores del lenguaje Move que añadan más código de verificación en tiempo de ejecución para prevenir situaciones inesperadas. Actualmente, el lenguaje Move realiza verificaciones de seguridad principalmente en la fase de verificación, pero esto puede no ser suficiente. Una vez que la verificación es eludida, si no hay suficientes refuerzos de seguridad en la fase de ejecución, esto podría llevar a problemas más graves.
Como líder en la investigación de seguridad del lenguaje Move, continuaremos investigando en profundidad los problemas de seguridad de Move y compartiremos más hallazgos en el futuro.