Skip to Content
logologo
AI Incident Database
Open TwitterOpen RSS FeedOpen FacebookOpen LinkedInOpen GitHub
Open Menu
Descubrir
Enviar
  • Bienvenido a la AIID
  • Descubrir Incidentes
  • Vista espacial
  • Vista Tabular
  • Vista de lista
  • Entidades
  • Taxonomías
  • Enviar Informes de Incidentes
  • Ranking de Reportadores
  • Blog
  • Resumen de noticias de IA
  • Control de Riesgos
  • Incidente aleatorio
  • Registrarse
Colapsar
Descubrir
Enviar
  • Bienvenido a la AIID
  • Descubrir Incidentes
  • Vista espacial
  • Vista Tabular
  • Vista de lista
  • Entidades
  • Taxonomías
  • Enviar Informes de Incidentes
  • Ranking de Reportadores
  • Blog
  • Resumen de noticias de IA
  • Control de Riesgos
  • Incidente aleatorio
  • Registrarse
Colapsar

Problema 902

Incidentes Asociados

Incidente 5024 Reportes
The DAO Hack

Loading...
Análisis del exploit DAO
hackingdistributed.com · 2016

Análisis del exploit DAO

phil daian

Así que estoy seguro de que todo el mundo ha oído hablar de las grandes noticias que rodean a la DAO y que un hacker se la llevó por una suma de 150 millones de dólares utilizando el exploit de envío recursivo de Ethereum.

Esta publicación será la primera de lo que es potencialmente una serie, deconstruyendo y explicando lo que salió mal a nivel técnico mientras proporciona una línea de tiempo que rastrea las acciones del atacante a través de la cadena de bloques. Esta primera publicación se centrará en cómo exactamente el atacante robó todo el dinero en el DAO.

Un ataque de varias etapas Este exploit en el DAO claramente no es trivial; el patrón de programación exacto que hizo que el DAO fuera vulnerable no solo se conocía, sino que los propios creadores del DAO lo arreglaron en una actualización anterior del código del marco. Irónicamente, mientras escribían las publicaciones de su blog y reclamaban la victoria, el pirata informático estaba preparando y desplegando un exploit que tenía como objetivo la misma función que acababan de arreglar para drenar todos los fondos de la DAO. Entremos en la descripción general del ataque. El atacante estaba analizando DAO.sol y notó que la función 'splitDAO' era vulnerable al patrón de envío recursivo que describimos anteriormente: esta función actualiza los saldos y totales del usuario al final, por lo que si podemos obtener cualquiera de las llamadas de función antes de que esto suceda para volver a llamar a splitDAO, obtenemos la recursividad infinita que se puede usar para mover tantos fondos como queramos (los comentarios del código están marcados con XXXXX, es posible que tenga que desplazarse para verlos): función splitDAO ( uint _proposalID , dirección _newCurator ) noEther onlyTokenholders devuelve ( bool _success ) { ... uint fondos a mover = ( saldos [ msg . sender ] * p . splitData [ 0 ]. splitBalance ) / p . datos divididos [ 0 ]. suministro total ; if (p. splitData [0]. newDAO. createTokenProxy. value (fundsToBeMoved) (msg. sender) == false) throw; ... Transferir ( msj . remitente , 0 , saldos [ msj . remitente ]); retirarRecompensaPara (mensaje. remitente); totalSupply -= saldos [ msj . remitente]; saldos [ msj . remitente] = 0; pagado [mensaje. remitente] = 0; devolver verdadero; } La idea básica es esta: proponer una división. Ejecutar la división. Cuando el DAO vaya a retirar su recompensa, llame a la función para ejecutar una división antes de que finalice el retiro. La función comenzará a ejecutarse sin actualizar su saldo, y la línea que marcamos anteriormente como "el atacante quiere ejecutar más de una vez" se ejecutará más de una vez. ¿Qué hace eso? Bueno, el código fuente está en TokenCreation.sol y transfiere tokens del DAO principal al DAO secundario. Básicamente, el atacante está usando esto para transferir más tokens de los que debería poder transferir a su DAO secundario. ¿Cómo decide la DAO cuántas fichas mover? Usando la matriz de saldos, por supuesto: uint fondos a mover = ( saldos [ msj . sender ] * p . splitData [ 0 ]. splitBalance ) / p . datos divididos [ 0 ]. suministro total ; Porque p.splitData[0] va a ser el mismo cada vez que el atacante llame a esta función (es una propiedad de la propuesta p, no el estado general de la DAO), y porque el atacante puede llamar a esta función desde retirarRecompensaPor antes que el balances se actualiza, el atacante puede hacer que este código se ejecute de forma arbitraria muchas veces usando el ataque descrito, con los fondos para ser movidos con el mismo valor cada vez. Lo primero que el atacante debía hacer para allanar el camino para su explotación exitosa era tener la función de retiro para el DAO, que era vulnerable a la explotación crítica de envío recursivo, en realidad ejecutándose. Veamos lo que se requiere para que eso suceda en el código (de DAO.sol): función retirarRecompensaPara ( dirección _cuenta ) noEther retornos internos ( bool _éxito ) { if (( saldoDe ( _cuenta ) * cuentarecompensa . Entrada Acumulada ()) / SuministroTotal <pagadoFuera [ _cuenta ]) tirar ; uint recompensa = ( saldoDe ( _cuenta ) * cuentaRecompensa . EntradaAcumulada ()) / SuministroTotal - SaldoPagado [ _cuenta ]; if ( ! cuentaRecompensa . pago ( _cuenta , recompensa )) throw ; pagado [ _cuenta ] += recompensa ; devolver verdadero; } Si el pirata informático pudiera obtener la primera declaración if para evaluar como falsa, se ejecutaría la declaración marcada como vulnerable. Cuando se ejecutan esas instrucciones, se llamaría al código que se parece a esto: function payOut ( address _recipient , uint _amount ) devuelve ( bool ) { if ( msg . sender != propietario || msg . value > 0 || ( payOwnerOnly && _recipient ! = dueño )) tirar ; if ( _destinatario . llamada . valor ( _cantidad )()) { Pago ( _destinatario , _cantidad ); devolver verdadero; } más { devuelve falso ; } ¡Observe cómo la línea marcada es exactamente el código vulnerable mencionado en la descripción del exploit que vinculamos! Esa línea luego enviaría un mensaje del contrato de DAO a "_recipient" (el atacante). Por supuesto, "_recipient" contendría una función predeterminada, que volvería a llamar a splitDAO con los mismos parámetros que la llamada inicial del atacante. Recuerde que debido a que todo esto está sucediendo desde adentro del retiro desde el interior de splitDAO, el código que actualiza los saldos en splitDAO no se ha ejecutado. Entonces, la división enviará más tokens al niño DAO y luego solicitará la recompensa.

Leer la Fuente

Investigación

  • Definición de un “Incidente de IA”
  • Definición de una “Respuesta a incidentes de IA”
  • Hoja de ruta de la base de datos
  • Trabajo relacionado
  • Descargar Base de Datos Completa

Proyecto y Comunidad

  • Acerca de
  • Contactar y Seguir
  • Aplicaciones y resúmenes
  • Guía del editor

Incidencias

  • Todos los incidentes en forma de lista
  • Incidentes marcados
  • Cola de envío
  • Vista de clasificaciones
  • Taxonomías

2024 - AI Incident Database

  • Condiciones de uso
  • Política de privacidad
  • Open twitterOpen githubOpen rssOpen facebookOpen linkedin
  • e1b50cd