En los días anteriores hubo una exposición de vulnerabilidad común o CVE, conocido como CVE-2018-17144 que advirtió sobre la inflación, es decir, crear bitcoins extras o 21.000.012.5 para ser exactos. ¿Que pasó? ¿Como ocurrió? ¿De donde viene este error?

El usuario conocido como awemany advirtió sobre esto. Para entender este problema, veamos los dos componentes claves del CVE: un crash bug y un bug de inflación. Ambos tienen algo en común: las transacciones que contienen inputs multiples.

Aquí la cronología de las acciones tomadas por el equipo de Bitcoin Core.

¿Que pasó?

Es un bug que fue introducido como parte de la mejora de desempeño para la validación de bloques en la versión introducida de marzo del 2017 (0.14.0). En resumen, este bug permitiría crear inputs duplicados y en consecuencia, permitir el double-spending o falsificación de bitcoins. Los nodos (0.14.0 al 0.14.2) aceptarían los bloques pero al mismo tiempo, algo estaría mal. El problema principal es que no se sabría que es lo que está mal. Ahora la versión 0.15.0 al 0.16.2 tendrían el mismo problema pero sumado a que aceptarían sin problemas las transacciones y los bloques anteriores.

¿Quienes fueron afectados?

Todos los softwares que contengan el commit eecffe50efc3944d713c701fa375dacbf17fb7cf  o todo software que aplicó estos cambios desde Bitcoin Core luego del 10 de noviembre del 2016 fueron afectados.

El modus operandi

Generalmente, funciona así: un minero tiene un ouput pendiente (unspent output) A por 1 BTC. Crean una transacción en la cual usan el input dos veces, es decir, input 1 gasta de ouput A e input 2 también gasta de ouput A. Como vemos, la suma de ambos ouputs nos da 2 BTC dado que el valor del output es mayor que el valor del output A. Si tuvieramos 2 ouput A entonces, el valor sería correcto.

¿Qué hace el minero? El siguiente paso luego sería tomar las transacciones e incluirlos en un bloque que él esta minando. Una vez que el minero encuentro un bloque con la transacción incluida, se transmite a la cadena de bloques. Y es aquí donde inicia el bug.

Como afecta a los nodos 0.14.x

Cuando el nodo del Bitcoin Core 0.14.x recibe el bloque, validará el bloque pero saltará el proceso de verficiar el input duplicado por el parametro false de esta línea. Hasta aquí, el minero hizo pasar este paso de validación y otros pasos de validación hasta que llega a este bucle. En este bucle, los inputs de la transacción serán marcados como gastados en la base de datos de las transacciones no confirmadas (UTXOs). La primera vez la transacción del input será vista como duplicada, así mismo será marcada como gastada. La segunda vez que vuelva, la moneda esta marcada como gastada, entonces coins->vout[nPos].IsNull() dará como resultado TRUE. A continuación, esta transacción irá hasta este if statement y en consecuencia, pasará este assert statement que sigue. El paso de este assert causar que el software caiga.

Como afecta a los nodos 0.15.0 al 0.16.2

Para el Bitcoin Core 0.15.0 al 0.16.2, el comportamiento es diferente, debido a los cambios aplicados sobre los UTXOs. Todo es básicamente lo mismo hasta que llega al mismo bucle. Esta vez, en lugar de dar un retorno del output que fue gastado, SpendCoinretorna el input existente en la base de datos. Así que, por primera vez, pasará todo según lo esperado, pero la segunda vez -al igual que el caso anterior- retornará TRUE cuando en realidad sigue siendo FALSE.

Mirando SpendCoin, nos fijamos que solo retornará FALSEcuando sea incapaz de encontrar la moneda -cuya representación es el UTXO- de la base de datos. Con la nueva base de datos estructurada, cobra un sentido lógico mientras que los outputs son removidos de la base de datos cuando estos son gastados. Sin embargo, si nos fijamos unas líneas más abajo, veremos que las monedas son eliminadas solamente si son marcadas como FRESH. En el caso de que la moneda sea FRESH, SpendCoin igualmente retornará TRUE ya que el objeto sigue existiendo en la memoria, lo que quiere decir que pasa el assert que sucede a SpendCoin (el cual causo el crash cuando la moneda no era FRESH). La validación, en consecuencia, continua normalmente, y el output de la transacción creada, es añadida en la base de datos de UTXOs, lo cual significa que la moneda que no debería existir, ahora  ya existe en la base de datos de las UTXOs.

Y, ¿Cuando las UTXOs son marcadas como FRESH?

Son marcadas FRESH cuando son añadidas a la base de datos de las UTXOs. Pero la base de datos de las UTXOs solo están en la memoria (como caché). Cuando es guradada en el disco, las entradas en la memoria ya no son marcadas como FRESH. Este guardado al disco sucede luego de cada bloque.

Así mismo, si un minero tiene un output que fue parte de una transacción ya confirmada, y decide gastar el output 2 veces en la misma transacción (para que la transacción tenga dos inputs que refieran al mismo output), y esta transacción no fue transmitida a la red sino que se incluye en un bloque que el minero tiene, es capaz de crear un nuevo output que tenga el doble de valor del output que el gastó, y, por lo tanto, crear nuevas monedas.

¿Un no-minero puede hacer esto?

NO.

Todo el proceso revelado anteriormente pasa por fuera de los bloques y son procesados en busca de inputs duplicados. La transacción sería rechazada e invalidada y no insertada en el mempool de los nodos, por lo que la transacción tampoco ingresará al bloque. Solamente las transacciones con inputs duplicados pueden ingresar al bloque y por tanto, aprovecharse de esta vulnerabilidad, y el único que puede hacer esto es el minero, quien debe insertar la transacción inválida en el bloque.

Entonces, ¿estamos jodidos?

No necesariamente. Las investigaciones hechas hasta ahora demustran que el bug no ha sido explotado de ningún modo. Además el bug en sí no es práctico a la hora de explotarlo, dado que que el minero debería haber creado un bloque con la intención especifica de explotar el bloque. ¿Dicho de otro modo? El minero que realiza este ataque, sabe que, al hacerlo, invalida su trabajo de recompensa (al momento de escribir esto, unos USD 80.000) y que al mismo tiempo, un ataque como esto no es poca cosa, dado que hubiera alertado a los mineros a nivel mundial, dado el grado de transparencia de la cadena de bloque.

Esto nunca había pasado

No necesariamente, ya hubo un caso similar: el CVE-2010-5139, cuando el bloque 74638 fue descubierto que tenía 184,467,440,737.09551616 bitcoins para 3 direcciones. Esto fue solucionado luego de 5 horas de su descubrimiento. Ver todos los CVE.

 


 

Este artículo fue redactado en base a la respuesta de Andrew Chow en Bitcoin.SE bajo Licencia Creative Commons 3.0 y el usuario awemany

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.