Realizando doble gasto 0-conf en Bitcoin SV

Siempre me pregunté si sería posible realizar un doble gasto de una transacción 0-conf en Bitcoin. Aunque todos los aspectos técnicos indicaban que sí sería posible, siempre que consultaba a algún experto obtenía las mismas respuesta:

  • La propagación de las transacciones en Bitcoin es muy rápida, es casi imposible hacer doble gasto.
  • Los mineros siguen la regla de “first seen safe”: una vez que aceptan una transacción no aceptarán otra que intente hacer un doble gasto de la primera.
  • Sobornar a un minero para hacer doble gasto de una transacción 0-conf no es rentable para cantidades pequeñas.
  • Siempre que se usen comisiones >= 1 satoshi/byte es seguro.
  • Aunque alguien consiga hacer un doble gasto de una 0-conf, detectarlo es trivial conectándote a varios nodos y esperando 5 segundos.
  • No hay forma de hacer un doble gasto sin ser detectado.

Como esas respuestas no me convencían, decidí hacer por mi cuenta una pequeña investigación. Como suele decirse: no confíes, verifica.

Bitcoin SV

He decidido realizar el estudio basado en Bitcoin SV (BSV), por varias razones. La principal es porque su comunidad cree firmemente que las transacciones 0-conf son lo suficientemente seguras tal como están, y que no necesitan ser mejoradas. Por ejemplo, Craig Wright opina lo siguiente sobre este asunto:

¿Es cierto lo que dice CSW?, ¿las probabilidades de detección de un doble gasto 0-conf son del 99.8%, a no ser que haya una confabulación con un minero deshonesto? Veamos…

Race condition

Lo primero que intenté comprobar fue si era posible enviar una transacción a un nodo y otra transacción diferente (con el mismo input) a otro nodo. Es decir, un doble gasto. La respuesta es clara: sí, es posible siempre que se haga de forma precisa. Para estas pruebas me basé en izubitcoin, una pequeña utilidad que programé hace tiempo para practicar C++. Trabajé sobre una nueva versión aún no publicada (v0.16), con las funcionalidades necesarias para realizar doble gasto. 

Screenshot de opciones izubitcoin v0.16

Explotando la race condition

Para conseguir explotar la race condition de aceptación de transacciones de doble gasto, lo que hace izubitcoin es lo siguiente:

  • Utiliza paralelización. Crea los procesos y threads necesarios para poder manejar la conexión a cada nodo de forma independiente. De este forma, y combinado con un servidor dedicado con una conexión de capacidad media, es capaz de conectarse a miles de nodos de forma simultánea en unos pocos segundos (toda la red de BSV o BCH).
  • Se conecta usando el protocolo de Bitcoin de forma nativa. Concretamente lo que hace es conectar al nodo remoto, intercambiar version/verack, ping/pong y se queda a la espera.
  • Una vez conectado a los nodos remotos (después unos pocos segundos) envío una signal a los procesos. Al recibirla cada thread envía la transacción a su nodo y se desconecta. De esta forma la sincronización es muy efectiva.

Los resultados son positivos en un altísimo porcentaje, variando ligeramente dependiendo del número de nodos a los que se conecte. Para la red BSV (unos 450 nodos) se consigue explotar la race condition con un porcentaje de éxito que varía entre el 90% y el 97%. De esta forma se obtiene un control muy preciso sobre qué transacción se envía a cada nodo.

Evitando que los nodos propaguen la transacción

Una vez que se consigue explotar la race condition de forma controlada la cosa se simplifica. Para evitar que los nodos propaguen la transacción entre ellos y conseguir así un control preciso sobre la distribución de nuestras 2 transacciones, el método es simple. Debemos conectarnos a todos los nodos de la red y enviarles las transacciones simultáneamente. Esto parece complicado, pero no lo es. Utilizando paralelización y una conexión de capacidad media se consigue de forma sencilla. Utilizando izubitcoin lo he realizado muchas veces con la red de BCH (unos 2000 nodos), y otras tantas con la red de BSV.

Utilizando el envío simultáneo puedes enviar la transacción T1 a 300 nodos, y la transacción T2 a 150 nodos. No importa si T1 y T2 comparten algún input (doble gasto). Cada nodo después de recibir su transacción intentará reenviarla, y entonces pueden pasar 2 cosas (excluyentes entre sí):

  1. El nodo destino ya tiene la misma transacción.
  2. El nodo destino tiene la otra transacción (doble gasto), por tanto no la acepta. La rechaza silenciosamente.

Mineros

Llegados a este punto, el objetivo estaba claro. ¿Y si enviamos la transacción T1 a la mayoría de nodos no mineros, y a la minoría de nodos mineros le enviamos la transacción de doble gasto T2? Con esto se conseguiría que la mayoría de la red viese únicamente la transacción T1, mientras que por otro lado la transacción que se minaría en el siguiente bloque sería la T2, puesto que es la única que tendrían los mineros. Debería funcionar, pero… ¿qué nodos son los mineros?

Identificando a los nodos mineros, ¿cuáles son?

Había que identificar los nodos mineros, ¿pero cómo?…

Mi primera idea fue conectarme a todos los nodos de la red de forma permanente, y registrar cada vez que un nodo anunciaba un bloque junto con una marca de tiempo con precisión de microsegundos. Dejándolo el tiempo suficiente (varios días), intentaría descubrir los nodos mineros a través del análisis estadísticos de esos datos. Creía que a medio plazo los nodos mineros anunciarían los bloques mínimamente antes que el resto, y que sería suficiente para identificarlos. Pronto descubrí que, aunque tenía cierto éxito, no era suficiente y el porcentaje de fallos a la hora de hacer doble gasto era demasiado elevado.

Luego se me ocurrió una idea. ¿Y si enviamos a cada nodo una transacción única? En vez de un doble gasto sería una especie de cuatrocientos cincuenta gasto, uno por cada nodo de la red BSV. Modifiqué izubitcoin para que enviase a cada nodo una transacción que utilizase el mismo input, pero añadiendo un output con un OP_RETURN + datos aleatorios. Guardando un registro de a qué nodo se le envió cada transacción (txid), luego podría ver qué transacción de las 450 es la que se minaba en el siguiente bloque. De esa forma me serviría para identificar a los nodos mineros.

Efectivamente, a los pocos bloques descubrí que las transacciones que se minaban eran las que se enviaban casi siempre a los mismos nodos. También confirmé lo que ya sabíamos, que la minería de Bitcoin SV está muy centralizada. Concretamente:

  • El 34% del hashrate es únicamente 1 nodo.
  • El 59% del hashrate son 2 nodos.
  • El 68% del hashrate son 3 nodos.
  • El 75% del hashrate son 4 nodos.

Por tanto, si hay 450 nodos en la red BSV; se podría enviar la transacción T1 a 446 nodos, la transacción T2 a 4 nodos, y las probabilidades de que se minase la transacción T2 serían del 75%.

Pruebas de doble gasto 0-conf reales en BSV

He realizado muchos doble gasto en la red de Bitcoin SV. Desde que utilizo la técnica de enviar una transacción única a cada nodo para identificar a los mineros, las conclusiones son las siguientes:

  • Puedes elegir el porcentaje de éxito que desees. Para conseguir un 90% de éxito sólo tienes que enviar la transacción T2 a 6 nodos. Si quieres un 100% son 20 nodos.
  • Enviando la transacción T2 a 6 nodos, las probabilidades de detectar el doble gasto son muy pequeñas. He hecho una prueba con la aplicación POP! (de Handcash), que se conecta a unos 10 nodos para intentar detectar el doble gasto. Ha fallado y no ha detectado el doble gasto en ninguna de las ocasiones. Es lógico, teniendo en cuenta que si hay 450 nodos en la red BSV sus probabilidades de detección son del 14% apróximadamente.
  • Cuantos más nodos haya en la red, más difícil es detectar un doble gasto.
  • Todas las transacciones tienen una comisión superior a 1 satoshi/byte.
  • El tiempo de ejecución del doble gasto es inferior a 20 segundos.
  • Realizarlo es prácticamente gratis, sólo hace falta una conexión a internet y un router de gama media/alta.
  • Funciona aunque todos los mineros sean honestos.

¿Cómo se podría mitigar el problema?

En mi opinión la solución es simple. Los nodos deben comunicarse entre sí cuando reciban una transacción de doble gasto (enviando una prueba), ignorarla de forma silenciosa no tiene sentido. Creo que Bitcoin Unlimited ha propuesto (o ya ha desarrollado) algo al respecto. De esa forma se podría detectar el intento de doble gasto en el mismo instante en el que se realiza, sólo habría que esperar unos 5 segundos.

Otras soluciones como conectarse a un mayor número de nodos, o hacer pública la lista de nodos mineros; creo que sólo son parches poco eficientes que no solucionan el problema. No creo que lo necesario sea aumentar la complejidad de wallets y procesadores de pago para que intenten detectar el doble gasto de forma poco eficaz, sino modificar el protocolo para conseguir que detectar un intento de doble gasto sea algo tan sencillo que incluso una wallet SPV en un smartphone pueda hacerlo.

Pruebas en entornos reales

He realizado doble gasto en varios servicios de la red BSV, siempre utilizando cuentas y direcciones propias (no de terceros). Adjunto un vídeo demostrativo de un doble gasto en la aplicación POP! de Handcash. Es una aplicación PoS (point of sale) pensada para el comercio minorista, que incorpora detección de doble gasto.

izubitcoin

He creado una pequeña herramienta para experimentar con nodos bitcoin a nivel de protocolo: izubitcoin. Está programada en C++ (para GNU Linux). Quería programar algo en ese lenguaje para practicarlo, principalmente porque es el lenguaje en el que están escritos varios nodos de Bitcoin Cash (como Bitcoin ABC o Bitcoin Unlimited).

Está en sus inicios, de momento sólo consigue la versión de un nodo bitcoin remoto. La idea es ir añadiendo funcionalidades y hacer una especie de Nmap para bitcoin.

Si alguien se anima a probarla, o quiere colaborar programando algo, bienvenido sea.  🙂

Dejo por aquí la URL de su repositorio en GitHub:

https://github.com/segoverflow/izubitcoin

Grupo de Telegram: no es la mejor opción

Hace más de un mes creé un grupo de Telegram llamado Seguridad Overflow (a modo de experimento), para hablar sobre temas relacionados con la seguridad informática. O al menos esa era mi idea. Con el paso de las semanas he llegado a la conclusión de que Telegram no es el medio adecuado para mantener debates en grupo.

Uno de los problemas es que no puedes elegir a quien escuchar dentro del grupo, o escuchas a todos o no escuchas a nadie. Eso hace al grupo de Telegram una opción menos interesante respecto a Twitter, donde tienes mucho más control sobre a qué personas seguir. Obviamente hay temas y personas que te parecen más interesantes que otras, por lo que la posibilidad de poder hacer un filtrado es importante.

El segundo problema, directamente enlazado con el anterior, es que muchas veces las conversaciones derivan en temas que nada tienen que ver con la seguridad informática. Cada uno tiende a hablar sobre lo que le interesa o le preocupa; ya sea política, conspiraciones, historia, deportes y un largo etcétera. Al no haber un sistema de etiquetado de conversaciones (como pueden ser los hashtags en Twitter), se hace imposible evitar conversaciones que no te interesan.

La suma de ambos problemas da como resultado la “obligación” para todos los usuarios de leer todas las conversaciones existentes, independientemente de su temática. Podría mitigarse aplicando un férreo control sobre el grupo, intentando ceñir los temas a la seguridad informática, pero no creo que esa sea la solución. Lo primero porque detesto la censura de un poder centralizado (el administrador del grupo de Telegram en este caso), y lo segundo porque la solución no creo que sea obcecarse en utilizar un sistema que no cumple tus necesidades. Lo que hay que hacer es utilizar un sistema mejor.

Y hay muchos más inconvenientes con el grupo de Telegram… Por nombrar el último: la nula posibilidad del usuario de marcar mensajes favoritos. Ahora éramos unas 14 personas en el grupo, pero si ese número crece la cantidad de mensajes también lo haría. Imaginad que entráis al grupo y os encontráis 600 mensajes sin leer, ¿son todos igual de relevantes? Para Telegram sí, para el usuario lo dudo.

Por todo, creo que sería mejor opción utilizar Twitter, ya sea por medio de un hashtag concreto para mantener conversaciones entre varios usuarios, o soluciones similares. No creo que haya que reinventar la rueda.

El grupo de Telegram actual se cerrará dentro de unos días, dejando algo de plazo por si los usuarios quieren crear un grupo nuevo (a modo de fork).

¡Nos vemos en Twitter!

Podcast-blog

He decidido que voy a intentar convertir Seguridad Overflow en un podcast-blog.

¿Y qué es un podcast-blog?, os estaréis preguntando. Pues no lo tengo yo muy claro, imagino que la mezcla de publicar audios en formato podcast y artículos en formato texto. Lo que en mi caso se traduce por: publicar un audio cada 10 meses y un artículo cada 2 años. Eso sí, aprovechando cada ocasión que se me presente para prometer y reprometer que a partir de ese momento empezaría a hacerlo con una regularidad pasmosa. Los viejos del lugar ya sabéis cómo va el tema…

Fuera bromas, me apetece escribir algún artículo de vez en cuando. No sólo artículos técnicos (que los habrá), sino también poder escribir sobre cualquier tema relacionado con la tecnología de una u otra forma. Por ejemplo podría escribir un artículo técnico para complementar un episodio del podcast, pero también otro sobre el postureo en el mundo del podcasting (adelanto en exclusiva de mi próximo post). Según me dé.

Supongo que es el tiempo libre del que dispongo desde que estoy desempleado, pero me ha dado por intentar mejorar Seguridad Overflow. He pensado en los siguientes aspectos:

  • Lo primero, obviamente, sería aumentar la regularidad del podcast (léase parte final del segundo párrafo de este post).
  • Complementar audios técnicamente complejos con artículos de texto en el blog.
  • Escribir de vez en cuando (es decir, prometiendo cada 2 meses y haciéndolo cada 2 años) artículos relacionados con la seguridad informática o con la tecnología en general.
  • Escribir algún programita y subirlo a github.com/segoverflow.
  • Intentar crear una pequeña comunidad para hablar sobre seguridad informática, hacking, podcasting o sobre cualquier tema relacionado con la tecnología. De ahí surge el grupo de Telegram (al que os podéis unir accediendo a seguridadoverflow.com/telegram desde vuestro móvil o tablet).

Respecto al RSS; para el blog (sólo los artículos de texto) hay un feed RSS diferente al del podcast. Es decir, los artículos del blog no aparecerán en vuestras aplicaciones de podcast como Pocket Casts, iOS Podcasts, etc. Si queréis suscribiros al blog por RSS desde algún servicio tipo Feedly la URL es: seguridadoverflow.com/c/blog/feed.

Nos vemos en el siguiente podcast-blog 😉

Euskal, Bitcoin, Seguridad Spreaker, iPad Pro, Hackers, Mr. Robot

Hablo sobre la futura Euskal Encounter 2017, cotización al alza de bitcoin, varias debilidades de seguridad en Spreaker, multitarea en el iPad Pro, el listón para llamar a alguien hacker y mi opinión sobre la serie Mr. Robot.

Seguridad Meetup, Podcasts de seguridad, Bitcoin Mac mini, Apps nativas

¡Comienza la segunda temporada de Seguridad Overflow!

En este audio hablo sobre: debilidades de seguridad en la red social Meetup, otros podcasts de seguridad informática, minar bitcoins en Mac mini, aplicaciones nativas versus web y la aplicación Pocket Casts.

Fallo de seguridad, Programación, Euskal encounter, Cajero bitcoin, Fitbit Charge HR

Hablo sobre la euskal encounter (lan party), mi futura perra, seguridad y rendimiento en programación, cajero bitcoin, fitbit charge hr, bici eléctrica, licencia de windows 10, lg watch r, spreaker y podcast conjunto.

Bitcoin, CloudFlare, Programación, Mac mini, OS X, Euskal

Hablo sobre bitcoin y la crisis griega, cloudflare, editores de código, mac mini y OS X, euskal encounter, galaxy note 4, wunderlist, windows, linux, programación y movistar.

Vivir en Madrid, Git, XSS php, Note 4, Bitcoin

Hablo sobre mi experiencia de vivir en Madrid, varias aplicaciones para android si eres programador informático, ejecutar evernote en linux con wine, cross-site scripting en php, el sensor de huella del Galaxy Note 4, la fibra óptica de Movistar, Sleep as Android para medir la calidad del sueño, bitcoin y los robos a casas de intercambios, la situación de Grecia y una recomendación de un juego para android.