elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


  Mostrar Temas
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 18
1  Programación / Programación C/C++ / #if 0 ¿Se ejecuta? (Resuelto) en: 13 Abril 2021, 19:24 pm
Código
  1. #if 0
  2. //Code
  3. #endif

Es mi duda, Se ejecuta o no se ejecuta el codigo, Lo comento por que estoy migrando parte de una funcion en programa a otro:

Linea 210 de https://github.com/JeanLucPons/BSGS/blob/master/BSGS.cpp

Código
  1. #if 0
  2.      pp.y.ModSub(&Gn[i].x,&pp.x);
  3.      pp.y.ModMulK1(&_s);
  4.      pp.y.ModSub(&Gn[i].y);           // ry = - p2.y - s*(ret.x-p2.x);  
  5. #endif

Hay varias partes del codigo asi, y mi pregunta es, si no se ocupan para que estan ahi? Si fueran referencia yo las hubiese comentado en lugar de poner ese if 0


Edit

Acabo de comprobarlo, No, no se ejecuta

Código
  1. #include<stdio.h>
  2.  
  3. int main(){
  4. int  i = 10;
  5. printf("%i\n",i);
  6. #if 0
  7. i = 200;
  8. #endif
  9. printf("%i\n",i);
  10. }

Código:
C:\codigos>testif.exe
10
10

¿Por que esta ahí entonces ese segmento de código?

Saludos!
2  Seguridad Informática / Criptografía / Keyhunt en: 8 Abril 2021, 17:06 pm
Buenos días a todos. Quiero abrir este tema para presentar la herramienta que he estado desarrollando en los últimos meses.

Se llama keyhunt y sirve para buscar llaves privadas de criptomonedas (La mayoría de criptomonedas utilizan la misma curva elíptica y por eso se pueden atacar varios al mismo tiempo solo es cuestión de saber que datos se tiene y que se esta haciendo
)

keyhunt utiliza varios métodos para hacerlo y es bastante adaptable, podras desde tu android buscar resolver puzzles de hasta 1.6 bitcoin a una velocidadde Gigakeys/s o Terakeys/s

Link: https://github.com/albertobsd/keyhunt

Yo lo estoy utilizando para tratar de romper unos puzzles de los cuales ya abrí un hilo en este mismo subforo :Rompecabezas de Bitcoin, Medio millón USD en premios

Metodos disponibles

  • address
  • rmd160
  • xpoint
  • pub2rmd
  • bsgs

metodo address

Este método es el mas rudimentario ataque por fuerza bruta que pueda existir y consiste en buscar una privatekey que genere el address indicado.

Ejemplo del archivo de entrada:

Código:
1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb
19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA
1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e
1E6NuFjCi27W5zoXg8TRdcSRq84zJeBW3k
1PitScNLyp2HCygzadCh7FveTnfmpPbfp8
1McVt1vMtCC7yn5b9wgX1833yCcLXzueeC
1M92tSqNmQLYw33fuBvjmeadirh1ysMBxK
1CQFwcjw1dwhtkVWBttNLDtqL7ivBonGPV
1LeBZP5QCwwgXRtmVUvTVrraqPUokyLHqe
1PgQVLmst3Z314JrQn5TNiys8Hc38TcXJu
1DBaumZxUkM4qMQRt2LVWyFJq5kDtSZQot
1Pie8JkxBT6MGPz9Nvi3fsPkr2D8q3GBc1
1ErZWg5cFCe4Vw5BzgfzB74VNLaXEiEkhk
1QCbW9HWnwQWiQqVo5exhAnmfqKRrCRsvW
1BDyrQ6WoF8VN3g9SAS1iKZcPzFfnDVieY
1HduPEXZRdG26SUT5Yk83mLkPyjnZuJ7Bm
1GnNTmTVLZiqQfLbAdp9DVdicEnB5GoERE
1NWmZRpHH4XSPwsW6dsS3nrNWfL1yrJj4w
1HsMJxNiV7TLxmoF6uJNkydxPFDog4NQum
14oFNXucftsHiUMY8uctg6N487riuyXs4h
1CfZWK1QTQE3eS9qn61dQjV89KDjZzfNcv
1L2GM8eE7mJWLdo3HZS6su1832NX2txaac
1rSnXMr63jdCuegJFuidJqWxUPV7AtUf7
15JhYXn6Mx3oF4Y7PcTAv2wVVAuCFFQNiP
1JVnST957hGztonaWK6FougdtjxzHzRMMg
128z5d7nN7PkCuX5qoA4Ys6pmxUYnEy86k
12jbtzBb54r97TCwW3G1gCFoumpckRAPdY
19EEC52krRUK1RkUAEZmQdjTyHT7Gp1TYT
1LHtnpd8nU5VHEMkG2TMYYNUjjLc992bps
1LhE6sCTuGae42Axu1L1ZB7L96yi9irEBE
1FRoHA9xewq7DjrZ1psWJVeTer8gHRqEvR

Ejemplo de ejecucion:

Código:
./keyhunt -m address -f tests/1to32.txt -r 1:FFFFFFFF

Se especifica el rango de búsqueda del 1 al FFFFFFFF siempre en hexadecimal con -r 1:FFFFFFFF en este caso se especifica ese rango porque sabemos a priori que las address en la lista se encuentran en ese rango indicado, por que fueron address de puzzles anteriores y ya fueron resueltos.

Ejemplo de la salida:

Código:
[+] Version 0.1.20210328
[+] Setting mode address
[+] Opening file tests/1to32.txt
[+] Setting search for btc adddress
[+] Allocating memory for 32 elements: 0.00 MB
[+] Initializing bloom filter for 32 elements.
[+] Loading data to the bloomfilter
[+] Bloomfilter completed
[+] Sorting data
[+] 32 values were loaded and sorted
Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001
pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003
pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9
address: 1CUNEBjYrCn2y1SdiUMohaKUi4wpP326Lb
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007
pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc
address: 19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008
pubkey: 022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01
address: 1EhqbyUMvvs7BfL8goY6qcPbD6YKfPqb7e
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000015
pubkey: 02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5
address: 1E6NuFjCi27W5zoXg8TRdcSRq84zJeBW3k
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000031
pubkey: 03f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530
address: 1PitScNLyp2HCygzadCh7FveTnfmpPbfp8
(Output omitted)

metodo rmd160

Todas las address lagacy (Estas empiezan con 1) se pueden buscar también por su hash rmd160 previo al ser convertidas en base58

ejemplo del archivo de entrada:

Código:
751e76e8199196d454941c45d1b3a323f1433bd6
7dd65592d0ab2fe0d0257d571abf032cd9db93dc
5dedfbf9ea599dd4e3ca6a80b333c472fd0b3f69
9652d86bedf43ad264362e6e6eba6eb764508127
8f9dff39a81ee4abcbad2ad8bafff090415a2be8
f93ec34e9e34a8f8ff7d600cdad83047b1bcb45c
e2192e8a7dd8dd1c88321959b477968b941aa973
dce76b2613052ea012204404a97b3c25eac31715
7d0f6c64afb419bbd7e971e943d7404b0e0daab4
d7729816650e581d7462d52ad6f732da0e2ec93b
f8c698da3164ef8fa4258692d118cc9a902c5acc
85a1f9ba4da24c24e582d9b891dacbd1b043f971
f932d0188616c964416b91fb9cf76ba9790a921e
97f9281a1383879d72ac52a6a3e9e8b9a4a4f655
fe7c45126731f7384640b0b0045fd40bac72e2a2
7025b4efb3ff42eb4d6d71fab6b53b4f4967e3dd
b67cb6edeabc0c8b927c9ea327628e7aa63e2d52
ad1e852b08eba53df306ec9daa8c643426953f94
ebfbe6819fcdebab061732ce91df7d586a037dee
b907c3a2a3b27789dfb509b730dd47703c272868
29a78213caa9eea824acf08022ab9dfc83414f56
7ff45303774ef7a52fffd8011981034b258cb86b
d0a79df189fe1ad5c306cc70497b358415da579e
0959e80121f36aea13b3bad361c15dac26189e2f
2f396b29b27324300d0c59b17c3abc1835bd3dbb
bfebb73562d4541b32a02ba664d140b5a574792f
0c7aaf6caa7e5424b63d317f0f8f1f9fa40d5560
1306b9e4ff56513a476841bac7ba48d69516b1da
5a416cc9148f4a377b672c8ae5d3287adaafadec
d39c4704664e1deb76c9331e637564c257d68a08
d805f6f251f7479ebd853b3d0f4b9b2656d92f1d
9e42601eeaedc244e15f17375adb0e2cd08efdc9

Linea de busqueda:

Código:
./keyhunt -m rmd160 -f tests/1to32.rmd -r 1:FFFFFFFF -l compress

En este ejemplo anterior sabemos que las direcciones están comprimidas (Existen adress descomprimidas y comprimidas) esto se debe a que provienen de un public compress o compacto o sin compactar eso lo veremos en otro ejemplo mas adelante.

Ejemplo de salida:

Código:
[+] Version 0.1.20210328
[+] Setting mode rmd160
[+] Search compress only
[+] Opening file tests/1to32.rmd
[+] Allocating memory for 32 elements: 0.00 MB
[+] Initializing bloom filter for 32 elements.
[+] Loading data to the bloomfilter
[+] Bloomfilter completed
[+] Sorting data
[+] 32 values were loaded and sorted
Thread 0 : Setting up base key: 0000000000000000000000000000000000000000000000000000000000000001HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000001
pubkey: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000003
pubkey: 02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000007
pubkey: 025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000008
pubkey: 022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000015
pubkey: 02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5
HIT!! PrivKey: 0000000000000000000000000000000000000000000000000000000000000031
(Output omited)


metodo xpoint

Este metodo permite hacer lo mismo que antes pero busca exclusivamente el valor X de la clave publica, saltándose los costosos pasos de el hash sha256, hash rmd160 y el base58 encode.

Ejemplo del archivo de entrada:

Código:
034eee474fe724cb631d19f24934e88016e4ef2aee80d086621d87d7f6066ff860 # - 453856235784
0274241b684e7c31e7933510b510aa14de9ac88ec3635bdd35a3bcf1d16da210be # + 453856235784
03abc6aff092b9a64bf69e00f4ec7a8b7ca51cfc6656732cbbc9f5674925b88609 # - 529328067324
034f4fe33b02c202b732d278f90eedc635af6f3be8a93c8d1cb0a01f6399aab2a4 # + 529328067324
03716ff57705e6446ac3e217c8c8bd9e9c8e58547457a6fe93ac254c37fd48afcb # - 14711740067
02ffa0769b0459c64b41f59f93495063ae031de0b846180bee37f921f20e141f60 # + 14711740067
03de1df5d801bbd5e7d86577bf14950f732fd41e586945d06d19e0fdea41a37d62 # - 549755814000
038d3711fd681e26c05b2f0cd423fa596e15054024e40add24a93bfa0c630531f1 # + 549755814000
03a2efa402fd5268400c77c20e574ba86409ededee7c4020e4b9f0edbee53de0d4 # target


El primer valor es la llave publica comprimida o compacta, el segundo valor es un offset, esto es debido a que podemos crear varias copias de una llave publica a diferentes distancia de la misma, tal vez no conoceremos el valor de la privatekeys pero si podemos realizar varias operaciones matemáticas con los valores de las llaves publicas en este caso son valores que se encuentran sumándole o restándole otras llaves publicas con valores ya conocidos, en caso de encontrar alguna de las copias solo es cuestión de hacer sumas o restas para encontrar el valor de la llave original.

Ejemplo de lineal de ejecución:

Código:
./keyhunt -m xpoint -f tests/substracted40.txt -n 65536 -t 4 -b 40

En este caso especificamos que el area de busqueda sea en el bit numero 40 ya que los valores mostrados fueron estrados o sumados apartir del publickey del puzzle numero 40.

Ejemplo de salida:

Código:
[+] Version 0.1.20210330a
[+] Setting mode xpoint
[+] Setting 4 threads
[+] Min range: 8000000000
[+] Max range: ffffffffff
[+] Opening file tests/substracted40.txt
[+] Allocating memory for 6003 elements: 0.11 MB
[+] Initializing bloom filter for 6003 elements.
[+] Loading data to the bloomfilter
[+] Bloomfilter completed
[+] Sorting data
[+] 6003 values were loaded and sorted
Thread 3 : Setting up base key: 0000000000000000000000000000000000000000000000000000008001d00000
Thread 0 : Setting up base key: 00000000000000000000000000000000000000000000000000000080025b0000
HIT!! PrivKey: 000000000000000000000000000000000000000000000000000000800258a2ce
pubkey: 0274241b684e7c31e7933510b510aa14de9ac88ec3635bdd35a3bcf1d16da210be
Thread 1 : Setting up base key: 0000000000000000000000000000000000000000000000000000008002910000^C

Este es un ejemplo basico para obtener la llave privada orignal tenemos que sumarle a 800258a2ce hexadecimal el valor de + 453856235784 (decimal) en este caso el resultado es E9AE4933D6

El puzzle por ser resulto actualmente es de 120 bits y he utilizado este método y otros mas aun sin tener suerte aun

Metodo pub2rmd

Este método lo que hace es buscar por fuerza bruta la llave publica de address o hashes específicos, esto es util por que de conocer la llave publica de una dirección de los puzzles de 64, 65 y varios menores que 100 bits podremos fácilmente resolverlos.

La ventaja es que puedes puedes buscar al mismo tiempo la llave publica de todas las direcciones sin clave publica conocida.
La desventaja es que tiene la misma complejidad de encontrar una clave privada de 256 bits (prácticamente imposible en nuestro tiempo de vida)

Ejemplo de entrada:

Código:
3ee4133d991f52fdf6a25c9834e0745ac74248a4
20d45a6a762535700ce9e0b216e31994335db8a5
739437bb3dd6d1983e66629c5f08c70e52769371
e0b8a2baee1b77fc703455f39d51477451fc8cfc
61eb8a50c86b0584bb727dd65bed8d2400d6d5aa
f6f5431d25bbf7b12e8add9af5e3475c44a0a5b8
bf7413e8df4e7a34ce9dc13e2f2648783ec54adb
105b7f253f0ebd7843adaebbd805c944bfb863e4
9f1adb20baeacc38b3f49f3df6906a0e48f2df3d
86f9fea5cdecf033161dd2f8f8560768ae0a6d14
783c138ac81f6a52398564bb17455576e8525b29
35003c3ef8759c92092f8488fca59a042859018c
67671d5490c272e3ab7ddd34030d587738df33da
351e605fac813965951ba433b7c2956bf8ad95ce
20d28d4e87543947c7e4913bcdceaa16e2f8f061
24cef184714bbd030833904f5265c9c3e12a95a2
7c99ce73e19f9fbfcce4825ae88261e2b0b0b040
c60111ed3d63b49665747b0e31eb382da5193535
fbc708d671c03e26661b9c08f77598a529858b5e
38a968fdfb457654c51bcfc4f9174d6ee487bb41
5c3862203d1e44ab3af441503e22db97b1c5097e
9978f61b92d16c5f1a463a0995df70da1f7a7d2a
6534b31208fe6e100d29f9c9c75aac8bf06fbb38
463013cd41279f2fd0c31d0a16db3972bfffac8d
c6927a00970d0165327d0a6db7950f05720c295c
2da63cbd251d23c7b633cb287c09e6cf888b3fe4
578d94dc6f40fff35f91f6fba9b71c46b361dff2
7eefddd979a1d6bb6f29757a1f463579770ba566
c01bf430a97cbcdaedddba87ef4ea21c456cebdb

Código:
./keyhunt -m pub2rmd -f tests/puzzleswopublickey.txt -q

Ejemplo de salida:

Código:
[+] Version 0.1.20210331
[+] Setting mode pub2rmd
[+] Set quiet thread output
[+] Opening file tests/puzzleswopublickey.txt
[+] Allocating memory for 29 elements: 0.00 MB
[+] Initializing bloom filter for 29 elements.
[+] Loading data to the bloomfilter total: 0.00 MB
[+] Bloomfilter completed
[+] Sorting data
[+] 29 values were loaded and sorted
Total 76546048 keys in 90 seconds: 850511 keys/s

metodo bsgs

Las siglas de este método son por baby step giant step y es un metodo bastate veloz para buscar llaves privadas. Ejemplo de entrada:

Código:
043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde # 0000000000000000000000000000000000800000000000000000100000000000
046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69 # 0000000000000000000000000000000000800000000000000000200000000000

Linea de ejecucion:

Código:
./keyhunt -m bsgs -f tests/test120.txt -b 120


Ejemplo de salida:

Código:
[+] Version 0.1.20210328
[+] Setting mode BSGS
[+] Min range: 800000000000000000000000000000
[+] Max range: ffffffffffffffffffffffffffffff
[+] Opening file tests/test120.txt
[+] Added 2 points from file
[+] Bit Range 120
[+] Setting N up to 17592186044416.
[+] Init 1st bloom filter for 4194304 elements : 14.00 MB
[+] Init 2nd bloom filter for 209716 elements : 0.00 MB
[+] Allocating 128.0 MB for 4194304 aMP Points
[+] Precalculating 4194304 aMP points
[+] Allocating 3.00 MB for 209716 bP Points
[+] processing 4194304/4194304 bP points : 100 %
[+] Sorting 209716 elements
[+] Thread 0: 0000000000000000000000000000000000800000000000000000000000000000
[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000100000000000
[+] Publickey 043ffa1cc011a8d23dec502c7656fb3f93dbe4c61f91fd443ba444b4ec2dd8e6f0406c36edf3d8a0dfaa7b8f309b8f1276a5c04131762c23594f130a023742bdde
[+] Thread 0: 0000000000000000000000000000000000800000000000000000100000000000
Total 17592186044416 keys in 30 seconds: 586406201480 keys/s
[+] Thread 0 Key found privkey 0000000000000000000000000000000000800000000000000000200000000000
[+] Publickey 046534b9e9d56624f5850198f6ac462f482fec8a60262728ee79a91cac1d60f8d6a92d5131a20f78e26726a63d212158b20b14c3025ebb9968c890c4bab90bfc69
All points were found

La ventaja de este metodo es que la velocidad del mismo esta dada por la cantidad de RAM, con algunos cuantos Gigabytes de RAM puedes igualar la velocidad de búsqueda de varias tarjetas de video potentes y en general la memoria RAM es mas barata que las Tarjetas de video, adicionalmente consume menos electricidad.

Llave publica del puzzle 120

Código:
02CEB6CBBCDBDF5EF7150682150F4CE2C6F4807B349827DCDBDD1F2EFA885A2630

Lineal de ejecución:

Código:
./keyhunt -m bsgs -f tests/120.txt -b 120 -R

El -b 120 es para indicar que el rango es el el bit 120 de 800000000000000000000000000000 a ffffffffffffffffffffffffffffff hexadecimal

y el -R es para que la búsqueda sea aleatoria.

Ejemplo buscando el privatekey a una valocidad de 5.2 Petakeys/s

Código:
./keyhunt -m bsgs -f tests/120.txt -b 120 -R -k 1024 -q -p ./bPfile.bin -t 6

Salida:

Código:
[+] Version 0.1.20210328
[+] Setting mode BSGS
[+] Min range: 800000000000000000000000000000
[+] Max range: ffffffffffffffffffffffffffffff
[+] Setting random mode.
[+] Setting k factor to 1024
[+] Set quiet thread output
[+] Setting 6 threads
[+] Opening file tests/120.txt
[+] Added 1 points from file
[+] Bit Range 120
[+] Setting N up to 17592186044416.
[+] Init 1st bloom filter for 4294967296 elements : 14722.00 MB
[+] Init 2nd bloom filter for 214748365 elements : 736.00 MB
[+] Allocating 0.0 MB for 4096 aMP Points
[+] Precalculating 4096 aMP points
[+] Allocating 3276.00 MB for 214748365 bP Points
[+] Reading 4294967296 bP points from file ./bPfile.bin
[+] processing 4294967296/4294967296 bP points : 100 %
[+] Sorting 214748365 elements
Total 157238958864990208 keys in 30 seconds: 5241298628833006 keys/s

Estoy por liberar una versión que funcionara de 3 a 5 veces mas rápido
También estoy probando utilizar el bloomfilter directamente en disco NVMe utilizando de 1 a 2 TB solo para ver que velocidad obtengo.
Y por ultimo estoy haciendo una versión POOL para poder compartir poder de computo y dividir el trabajo entre varios clientes esto obviamente dividiendo el balance en caso de encontrar los puzzles.


Saludos!
3  Seguridad Informática / Criptografía / Paridad de un punto en Curvas Elipticas Criptograficas en: 27 Febrero 2021, 09:08 am
Quisiera abrir el siguiente hilo para saber si es posible determinar la paridad de un punto en una curva Eliptica utilizada en criptografía.

Encontré un video en youtube donde un programador de C# afirma tener la formula para determinar si un punto dado es par o impar para una curva en especifico.

Tiene una pagina

:http://remon78eg.tk/curve/mod2/

Utiliza un valor P custom: 115792089237316195423570985008687907853269984665640564039457584007908834675927

El cual afirma que es un valor débil o vulnerable.

El usuario no revela mucho de su método o test de paridad de un punto o publickey.

Las preguntas aquí son las siguientes:
¿Qué tiene de débil o vulnerable su orden de la curva?
¿Cuál seria el test de paridad que se pueda implementar para determinar si un punto (X,Y) pertenece a una privatekey par o impar?

Saludos!
4  Seguridad Informática / Criptografía / Rompecabezas de Bitcoin, Medio millón USD en premios en: 8 Febrero 2021, 19:28 pm
Muy buen día a todos últimamente hablando con Kub0x sobre curvas elípticas me sugirió publicar aquí los rompecabezas existentes de bitcoin, hay aproximadamente 12 bitcoin en premios. Para los rompecabezas Importantes y algunos otros bitcoin para rompecabezas pequeños.

Los rompecabezas se puede abordar de varias formas, pero abordarlos por fuerza bruta es casi imposible a no ser que tengan mucha mucha mucha suerte (El tema de Fuerza bruta exclusiva no va a ser tratado aqui).

Estos rompecabezas fueron hechos con el propósito explicito de ser crackeados desde el 2015 y en caso de conseguirlo pueden tomar el bitcoin de premio que se encuentra ahi, ya que el autor para eso los creo, fueron creados cuando el bitcoin se cambiaba por  160 Dolares cada uno, hoy en dia cuesta cada uno mas de 40 Mil dólares

A continuación los rompecabezas en el siguiente formato:
Código:
#Numero de Bits ( Dirección public de bitcoin ) Monto actual de la cartera
Inicio del rango del privatekey
Fin del rango del privatekey
Llave publica en formato comprimido

Puzzles:

Código:

#120 bits ( 17s2b9ksz5y7abUm92cHwG8jEPCzK3dLnT ) 1.20000000 BTC
800000000000000000000000000000
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
02CEB6CBBCDBDF5EF7150682150F4CE2C6F4807B349827DCDBDD1F2EFA885A2630

#125 bits ( 1PXAyUB8ZoH3WD8n5zoAthYjN15yN5CVq5 ) 1.25000000 BTC

10000000000000000000000000000000
1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
0233709EB11E0D4439A729F21C2C443DEDB727528229713F0065721BA8FA46F00E

#130 bits ( 1Fo65aKq8s8iquMt6weF1rku1moWVEd5Ua ) 1.30000000 BTC
200000000000000000000000000000000
3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
03633CBE3EC02B9401C5EFFA144C5B4D22F87940259634858FC7E59B1C09937852

#135 bits ( 16RGFo6hjq9ym6Pj7N5H7L1NR1rVPJyw2v ) 1.35000000 BTC
4000000000000000000000000000000000
7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
02145D2611C823A396EF6712CE0F712F09B9B4F3135E3E0AA3230FB9B6D08D1E16

#140 bits ( 1QKBaU6WAeycb3DbKbLBkX7vJiaS8r42Xo ) 1.40000000 BTC
80000000000000000000000000000000000
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
031F6A332D3C5C4F2DE2378C012F429CD109BA07D69690C6C701B6BB87860D6640

#145 bits ( 19GpszRNUej5yYqxXoLnbZWKew3KdVLkXg ) 1.45000000 BTC
1000000000000000000000000000000000000
1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
03AFDDA497369E219A2C1C369954A930E4D3740968E5E4352475BCFFCE3140DAE5

#150 bits ( 1MUJSJYtGPVGkBCTqGspnxyHahpt5Te8jy ) 1.50000000 BTC
20000000000000000000000000000000000000
3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
03137807790EA7DC6E97901C2BC87411F45ED74A5629315C4E4B03A0A102250C49

#155 bits ( 1AoeP37TmHdFh8uN72fu9AqgtLrUwcv2wJ ) 1.55000000 BTC
400000000000000000000000000000000000000
7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
035CD1854CAE45391CA4EC428CC7E6C7D9984424B954209A8EEA197B9E364C05F6

#160 bits ( 1NBC8uXJy1GiJ6drkiZa1WuKn51ps7EPTv )  1.60000793 Bitcoin
8000000000000000000000000000000000000000
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
02E0A8B039282FAF6FE0FD769CFBC4B6B4CF8758BA68220EAC420E32B91DDFA673


Para quienes piensen  abordar el puzzle por fuerza bruta, estos son mas o menos los tiempos estimados para escanear el rango completo de acuerdo a la velocidad conseguida:

Código:
Puzzle 120 @ 1 Terakeys/s :     21074771622667996 años
Puzzle 120 @ 1 Petakeys/s :     21074771622667 años
Puzzle 120 @ 1 Exakeys/s :      21074771622 años
Puzzle 120 @ 1 Zettakeys/s :    21074771 años
Puzzle 120 @ 1 Yottakeys/s :    21074 años
Puzzle 125 @ 1 Terakeys/s :     674392691925375886 años
Puzzle 125 @ 1 Petakeys/s :     674392691925375 años
Puzzle 125 @ 1 Exakeys/s :      674392691925 años
Puzzle 125 @ 1 Zettakeys/s :    674392691 años
Puzzle 125 @ 1 Yottakeys/s :    674392 años
Puzzle 130 @ 1 Terakeys/s :     21580566141612028377 años
Puzzle 130 @ 1 Petakeys/s :     21580566141612028 años
Puzzle 130 @ 1 Exakeys/s :      21580566141612 años
Puzzle 130 @ 1 Zettakeys/s :    21580566141 años
Puzzle 130 @ 1 Yottakeys/s :    21580566 años
Puzzle 135 @ 1 Terakeys/s :     690578116531584908094 años
Puzzle 135 @ 1 Petakeys/s :     690578116531584908 años
Puzzle 135 @ 1 Exakeys/s :      690578116531584 años
Puzzle 135 @ 1 Zettakeys/s :    690578116531 años
Puzzle 135 @ 1 Yottakeys/s :    690578116 años
Puzzle 140 @ 1 Terakeys/s :     22098499729010717059011 años
Puzzle 140 @ 1 Petakeys/s :     22098499729010717059 años
Puzzle 140 @ 1 Exakeys/s :      22098499729010717 años
Puzzle 140 @ 1 Zettakeys/s :    22098499729010 años
Puzzle 140 @ 1 Yottakeys/s :    22098499729 años
Puzzle 145 @ 1 Terakeys/s :     707151991328342945888372 años
Puzzle 145 @ 1 Petakeys/s :     707151991328342945888 años
Puzzle 145 @ 1 Exakeys/s :      707151991328342945 años
Puzzle 145 @ 1 Zettakeys/s :    707151991328342 años
Puzzle 145 @ 1 Yottakeys/s :    707151991328 años
Puzzle 150 @ 1 Terakeys/s :     22628863722506974268427923 años
Puzzle 150 @ 1 Petakeys/s :     22628863722506974268427 años
Puzzle 150 @ 1 Exakeys/s :      22628863722506974268 años
Puzzle 150 @ 1 Zettakeys/s :    22628863722506974 años
Puzzle 150 @ 1 Yottakeys/s :    22628863722506 años
Puzzle 155 @ 1 Terakeys/s :     724123639120223176589693541 años
Puzzle 155 @ 1 Petakeys/s :     724123639120223176589693 años
Puzzle 155 @ 1 Exakeys/s :      724123639120223176589 años
Puzzle 155 @ 1 Zettakeys/s :    724123639120223176 años
Puzzle 155 @ 1 Yottakeys/s :    724123639120223 años
Puzzle 160 @ 1 Terakeys/s :     23171956451847141650870193314 años
Puzzle 160 @ 1 Petakeys/s :     23171956451847141650870193 años
Puzzle 160 @ 1 Exakeys/s :      23171956451847141650870 años
Puzzle 160 @ 1 Zettakeys/s :    23171956451847141650 años
Puzzle 160 @ 1 Yottakeys/s :    23171956451847141 años

Si tienen alguna duda favor de comentarla en este hilo.

He creado un canal privado de Telegram, si alguno gusta discutir el tema ahí, favor de enviarme mensaje privado a https://t.me/albertobsd y si lo considero oportuno los agregare al grupo.

Saludos!
5  Programación / Programación General / Ordenar archivo binario de 100GB en: 21 Enero 2021, 05:02 am
Ok, veamos necesito una forma eficiente de ordenar un archivo de de 100 GB, Cada registro del archivo son 36 Bytes en binario.

Usualmente lo hacia con archivos pequeños 10 o 5 GB pero en RAM. Esto con el algoritmo Introsort y es bastante eficiente, pero ahora estoy utilizando el mismo método pero en Disco duro ya que el archivo es muy grande, Lo que estoy haciendo es leer los registros del disco, cargarlos en memoria, compararlos y escribir en disco en caso de que necesiten ser ordenados. Este proceso es muy lento directo en el disco duro.

Podría tratar de dividir el proceso he ir cargando de 10 en 10 GB en RAM u otra cantidad ordenarlos en memoria y seguir con los demás pedazos, sin embargo el problema es ordenar entre pedazos separados.

El proceso de generación de registros es aleatorio y no se en que orden se generaran los registros, quiero hacer este proceso lo mas eficiente y rápido posible, ya que si funciona este archivo tendré que generar un archivo similar de 500 o 1000 GB. No tengo problemas de Espacio en disco.

¿Alguna idea adicional a hacerlo directo desde el disco duro?


Edit:

Ayer miestras publicaba este teme tambien pense en la solucion, pero no queria publicarla hasta implementarla.

Dado que la generación de los registros es aleatoria y es uniforme entre el rango de A a B entonces se me ocurre que una vez generado el archivo de 100 GB, dividir el rango de A a B en subrangos manejables en RAM
por decil algo tengo los siguientes rangos para registros de 32 bytes:

Código:
From 0000000000000000000000000000000000000000000000000000000000000000 to 0ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
From 0ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc to 1999999999999999999999999999999999999999999999999999999999999998
From 1999999999999999999999999999999999999999999999999999999999999998 to 2666666666666666666666666666666666666666666666666666666666666664
From 2666666666666666666666666666666666666666666666666666666666666664 to 3333333333333333333333333333333333333333333333333333333333333330
From 3333333333333333333333333333333333333333333333333333333333333330 to 3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
From 3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc to 4cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc8
From 4cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc8 to 5999999999999999999999999999999999999999999999999999999999999994
From 5999999999999999999999999999999999999999999999999999999999999994 to 6666666666666666666666666666666666666666666666666666666666666660
From 6666666666666666666666666666666666666666666666666666666666666660 to 733333333333333333333333333333333333333333333333333333333333332c
From 733333333333333333333333333333333333333333333333333333333333332c to 7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8
From 7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8 to 8cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc4
From 8cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc4 to 9999999999999999999999999999999999999999999999999999999999999990
From 9999999999999999999999999999999999999999999999999999999999999990 to a66666666666666666666666666666666666666666666666666666666666665c
From a66666666666666666666666666666666666666666666666666666666666665c to b333333333333333333333333333333333333333333333333333333333333328
From b333333333333333333333333333333333333333333333333333333333333328 to bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4
From bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4 to ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc0
From ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc0 to d99999999999999999999999999999999999999999999999999999999999998c
From d99999999999999999999999999999999999999999999999999999999999998c to e666666666666666666666666666666666666666666666666666666666666658
From e666666666666666666666666666666666666666666666666666666666666658 to f333333333333333333333333333333333333333333333333333333333333324
From f333333333333333333333333333333333333333333333333333333333333324 to ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Entonces buscamos en el archivo los valores que entren en alguno de los rango anteriores, se ordenan en RAM y se escriben en un archivo aparte. Una vez completado el proceso para todos los sub-rangos se unen los archivos en uno solo y se borra el archivo desordenado.

Esto se puede hacer así debido a que la distribución de los registros es uniforme en el rango original de A a B, en caso de que la data este sesgada y existan mas valores en un sub-rango dado es conveniente poner un limite de cantidad de registros leídos para que el mismo no sobrepase la cantidad de RAM.

Saludos!
6  Foros Generales / Foro Libre / 15 Años en el foro, muchas gracias a todos :) en: 20 Noviembre 2020, 18:35 pm
Pues nada compañeros esta próxima semana cumplo 15 años registrado en el foro.

Yo se que tengo mas años viendo el foro, sin embargo hasta ese momento abrí mi cuenta.

Quiero agradecer a todos los miembros de este foro, a los que ya no están y a los que aun siguen. En este foro he aprendido mucho, de muchos temas distintos, aunque sea un poco de todo, estoy muy agradecido.

Desde ya muchas GRACIAS

Saludos!
7  Seguridad Informática / Criptografía / Implementacion practica Padding Oracle Attack en: 20 Noviembre 2020, 05:29 am
Recientemente me interesa ese tipo de temas otra vez, he aprendido mucho y me gustaría compartirlo con ustedes.

Si no saben de que va el tema aquí dejo unos links.

Block cipher mode of operation
https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

Wikipedia Padding oracle attack
https://en.wikipedia.org/wiki/Padding_oracle_attack

Padding oracle attack
https://robertheaton.com/2013/07/29/padding-oracle-attack/

Este tipo de Ataque tiene ciertas condiciones iniciales para ser llevado acabo.

  • El cliente solo puede saber si su paquete fue aceptado o no.
Esto es debido al check que hace el servidor sobre el mensaje recibido

  • El servidor no Cambia de KEY utilizada durante el proceso de cifrado y descifrado.
Esto es debido a una mala implementación, ya que el servidor debería de renovar el KEY cada X tiempo y con cada cliente distinto.

  • El servidor tiene algún leak de información ya sea por error o mediante otro tipo de ataque.
  • El cliente solo podrá descifrar Una parte de la información, excepto por el Bloque inicial


Dejo a continuación una imagen de prueba y el código, proximamente subire un video hablando del tema.






Codigo, este codigo ejemplifica el cliente y servidor mediante un hilo distinto, lo hice de esta manera para no complicarme con el protocolo en RED de los mismo, se puede hacer sin hilos, y solo con llamadas a funcion, pero la idea es garantizar que el cliente no tiene acceso al servidor.



Código
  1. /*
  2. Desarollado por AlbertoBSD
  3. email alberto.bsd@gmail.com
  4. g++ -O3 -o opk_example opk_example.c -Wint-to-pointer-cast  -pthread
  5. */
  6.  
  7. #include <time.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include<pthread.h>
  12. #include<unistd.h>
  13. #include"ctaes/ctaes.c"
  14.  
  15. #define AES_BLOCKSIZE 16
  16.  
  17. struct timespec tim, tim2,sim,sim2;
  18.  
  19. void crear_server();
  20. char *tohex(char *ptr,int length);
  21. void *process_server(void *vargp);
  22.  
  23. int MyCBCEncrypt(AES256_ctx *ctx, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out);
  24. int MyCBCDecrypt(AES256_ctx *ctx, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out);
  25.  
  26. /* Values between Server and client */
  27. int values_do;
  28. int values_pad;
  29. int values_length;
  30. int values_leaked;
  31. char *values_enc;
  32. char *values_leak;
  33.  
  34. pthread_mutex_t mtx_values;  //Mutex for those values
  35.  
  36. int main(){
  37.  /*
  38.     Set global values;
  39.   */
  40.  tim.tv_sec = 0;
  41.  tim.tv_nsec = 50000;
  42.  
  43.  sim.tv_sec = 0;
  44.  sim.tv_nsec = 50000;
  45.  values_do = 0;
  46.  values_pad = 0;
  47.  values_length = 0;
  48.  values_leaked = 0;
  49.  values_enc = (char*) malloc(48);
  50.  values_leak = (char*) malloc(48);
  51.  crear_server();  //create child "server"
  52.  
  53.  //This main process is the client
  54.  int i,j,k,entrar;
  55.  char *secret,*temp,*try_enc;
  56.  char *decrypted;
  57.  unsigned char GUESS;
  58.  secret = (char*) malloc(48);
  59.  try_enc = (char*) malloc(48);
  60.  decrypted = (char*) malloc(16);
  61.  memset(decrypted,0,16);
  62.  do  {  
  63.    sleep(1);
  64.  }while(values_leaked==0); //We need to wait to the leaked data
  65.  
  66.  memcpy(secret,values_leak,48);
  67.  
  68.  temp = tohex(secret,48);
  69.  printf("process_client: leaked is %s\n",temp);
  70.  free(temp);
  71.  i = 0;
  72.  j = 0;
  73.  while(i < 16)  {
  74.    memcpy(try_enc,secret,32);
  75.  
  76.    pthread_mutex_lock(&mtx_values);
  77.    switch(values_do)  {
  78.      case 0:
  79.        GUESS = j;
  80.        decrypted[15-i] = GUESS;
  81.        for(k = 0; k <= i;k++)  {
  82.          try_enc[15-k] = try_enc[15-k] ^ decrypted[15-k] ^ (unsigned char)(i+1);
  83.        }
  84.  
  85.        values_do = 1;
  86.        values_length = 32;
  87.        memcpy(values_enc,try_enc,32);
  88.      break;
  89.      case 1:
  90.      break;
  91.      case 2:
  92.        if(values_pad)  {
  93.          i++;
  94.          printf("Encontrado valor: %c : %.2x\n",GUESS,GUESS);
  95.          j = 0;
  96.        }
  97.        else  {
  98.          j++;
  99.        }
  100.        values_do = 0;
  101.      break;
  102.    }
  103.    pthread_mutex_unlock(&mtx_values);
  104.    nanosleep(&tim , &tim2);
  105.  }
  106.  printf("Decrypted data: %s\n",decrypted);
  107.  
  108. }
  109.  
  110. void *process_server(void *vargp)  {
  111.  AES256_ctx ctx;
  112.  FILE *urandom;
  113.  const char *secret = "The password is: Ywgo/@g:2$0Qsz<";
  114.  char *key,*dec,*enc,*iv,*temp;
  115.  int length,i,pad_valid,outlen;
  116.  unsigned char pad;
  117.  key = (char*) malloc(32);
  118.  dec = (char*) malloc(48);
  119.  enc = (char*) malloc(48);
  120.  iv  = (char*) malloc(16);
  121.  urandom = fopen("/dev/urandom","rb");
  122.  fread(key,1,32,urandom);
  123.  fread(iv,1,16,urandom);
  124.  fclose(urandom);
  125.  
  126.  AES256_init(&ctx,(const unsigned char*) key);
  127.  
  128.  /* LEAK THE secret */
  129.  pthread_mutex_lock(&mtx_values);
  130.  memset(enc,0,48);
  131.  
  132.  
  133.  outlen = MyCBCEncrypt(&ctx, (const unsigned char*) iv, (const unsigned char*) secret, strlen(secret), true, (unsigned char*) enc);
  134.  
  135.  memcpy(values_leak,enc,outlen);
  136.  values_leaked = 1;
  137.  pthread_mutex_unlock(&mtx_values);
  138.  /*END LEAK*/
  139.  
  140.  do  {
  141.    nanosleep(&sim , &sim2);
  142.    pthread_mutex_lock(&mtx_values);
  143.    if(values_do == 1)  {
  144.      length = values_length;
  145.      pad_valid = 0;
  146.      if(length <= 48)  {
  147.        memcpy(enc,values_enc,length);
  148.  
  149.        outlen = MyCBCDecrypt(&ctx,( const unsigned char*) iv, (const unsigned char*) enc, length, true, (unsigned char*) dec);
  150.        if(outlen > 0)  {
  151.          pad_valid =  1;
  152.          printf("Decrypted data seems legit : %i bytes\n",outlen);
  153.          temp = tohex(dec,length);
  154.          printf("Decrypted data %s\n",temp);
  155.          free(temp);
  156.        }
  157.        else  {
  158.          printf("Decrypted data doesnt seems legit\n",outlen);
  159.          temp = tohex(dec,length);
  160.          printf("Decrypted data %s\n",temp);
  161.          free(temp);
  162.        }
  163.      }
  164.      values_do = 2;
  165.      values_pad = pad_valid;
  166.    }
  167.    pthread_mutex_unlock(&mtx_values);
  168.  }while(1);
  169.  pthread_exit(NULL);
  170. }
  171.  
  172. void crear_server()  {
  173.  int s;
  174.  pthread_t tid;
  175.  pthread_attr_t attr;
  176.  s = pthread_attr_init(&attr);
  177.  if (s != 0)  {
  178.    perror("pthread_attr_init");
  179.    exit(6);
  180.  }
  181.  s = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
  182.  if(s != 0)  {
  183.    perror("pthread_attr_setstacksize");
  184.    exit(8);
  185.  }
  186.  s = pthread_create(&tid,&attr,process_server,NULL);
  187.  if(s != 0)  {
  188.    perror("pthread_create");
  189.  }
  190.  pthread_attr_destroy(&attr);
  191. }
  192.  
  193. char *tohex(char *ptr,int length){
  194.  char *buffer;
  195.  int offset = 0;
  196.  unsigned char c;
  197.  buffer = (char *) malloc((length * 2)+1);
  198.  for (int i = 0; i <length; i++) {
  199.  c = ptr[i];
  200.  sprintf((char*) (buffer + offset),"%.2x",c);
  201.  offset+=2;
  202.  }
  203.  buffer[length*2] = 0;
  204.  return buffer;
  205. }
  206.  
  207.  
  208. int MyCBCDecrypt(AES256_ctx *ctx, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
  209. {
  210.  int written = 0;
  211.  bool fail = false;
  212.  const unsigned char* prev = iv;
  213.  if (!data || !size || !out)
  214.    return 0;
  215.  if (size % AES_BLOCKSIZE != 0)
  216.    return 0;
  217.  while (written != size) {
  218.    AES256_decrypt(ctx, 1, out, data + written);
  219.    for (int i = 0; i != AES_BLOCKSIZE; i++)
  220.      *out++ ^= prev[i];
  221.    prev = data + written;
  222.    written += AES_BLOCKSIZE;
  223.  }
  224.  if (pad) {
  225.    unsigned char padsize = *--out;
  226.    fail = !padsize | (padsize > AES_BLOCKSIZE);
  227.    padsize *= !fail;
  228.    for (int i = AES_BLOCKSIZE; i != 0; i--)
  229.      fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
  230.    written -= padsize;
  231.  }
  232.  return written * !fail;
  233. }
  234.  
  235. int MyCBCEncrypt(AES256_ctx *ctx, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
  236. {
  237.  int written = 0;
  238.  int padsize = size % AES_BLOCKSIZE;
  239.  unsigned char mixed[AES_BLOCKSIZE];
  240.  
  241.  if (!data || !size || !out)
  242.    return 0;
  243.  
  244.  if (!pad && padsize != 0)
  245.    return 0;
  246.  
  247.  memcpy(mixed, iv, AES_BLOCKSIZE);
  248.  
  249.  // Write all but the last block
  250.  while (written + AES_BLOCKSIZE <= size) {
  251.    for (int i = 0; i != AES_BLOCKSIZE; i++)
  252.      mixed[i] ^= *data++;
  253.    AES256_encrypt(ctx, 1, out + written, mixed);
  254.    memcpy(mixed, out + written, AES_BLOCKSIZE);
  255.    written += AES_BLOCKSIZE;
  256.  }
  257.  if (pad) {
  258.    // For all that remains, pad each byte with the value of the remaining
  259.    // space. If there is none, pad by a full block.
  260.    for (int i = 0; i != padsize; i++)
  261.      mixed[i] ^= *data++;
  262.    for (int i = padsize; i != AES_BLOCKSIZE; i++)
  263.      mixed[i] ^= AES_BLOCKSIZE - padsize;
  264.    AES256_encrypt(ctx, 1, out + written, mixed);
  265.    written += AES_BLOCKSIZE;
  266.  }
  267.  return written;
  268. }
  269.  


Saludos!
8  Seguridad Informática / Seguridad / Como proteger una cartera Bitcoin en: 18 Noviembre 2020, 01:45 am
Como proteger una cartera Bitcoin

No sabemos qué pasará en el futuro, es decir no sabemos si nos robaran la cartera o la perderemos en algún USB y alguien la encontrara. Tampoco sabemos la cantidad de poder de computo que existira.

Pero además de tener cifrada nuestra cartera con un buen passphrase de más de 40 caracteres, se puede lograr una mejor seguridad, para en el caso de que sea robada sea inviable que por medio de fuerza bruta directo contra el passphrase.

Nuestra Cartera está protegida con el resultado de un hash sha512 derivado N veces a partir de nuestro Passphrase y un salt.

Es decir:

Código:
(key,IV) = PBKDF2_algo("sha512",passphrase+salt,N);

Normalmente el cliente bitcoin-core calcula ese N de tal forma que la Operación en total no lleve más de 1 Segundo

¿Por que? ¿Por que ponérsela fácil a los crackers de wallets?

Se puede editar el código fuente del bitcoin-core de tal forma que cuando nosotros cambiemos el passphrase este utilice un número N tal que N el proceso completo de PBKDF2_algo lleve al menos uno o dos minutos por passphare, es un pequeño precio de espera. Y el resultado será sumamente desalentador para quien se robe o encuentre la cartera.

¿Como hacer esta modificacion?

Si revisamos la versión estable y actual al dia de hoy, el bitcoin core 0.20 el archivo wallet.cpp tiene la solución:

https://github.com/bitcoin/bitcoin/blob/0.20/src/wallet/wallet.cpp En la linea 322 tenemos lo siguiente:

Código
  1. bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
  2. {
  3.    bool fWasLocked = IsLocked();
  4.  
  5.    {
  6.        LOCK(cs_wallet);
  7.        Lock();
  8.  
  9.        CCrypter crypter;
  10.        CKeyingMaterial _vMasterKey;
  11.        for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
  12.        {
  13.            if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  14.                return false;
  15.            if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
  16.                return false;
  17.            if (Unlock(_vMasterKey))
  18.            {
  19.                int64_t nStartTime = GetTimeMillis();
  20.                crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
  21.                pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))));
  22.  
  23.                nStartTime = GetTimeMillis();
  24.                crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
  25.                pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
  26.  
  27.                if (pMasterKey.second.nDeriveIterations < 25000)
  28.                    pMasterKey.second.nDeriveIterations = 25000;
  29.  
  30.                WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
  31.  
  32.                if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  33.                    return false;
  34.                if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
  35.                    return false;
  36.                WalletBatch(*database).WriteMasterKey(pMasterKey.first, pMasterKey.second);
  37.                if (fWasLocked)
  38.                    Lock();
  39.                return true;
  40.            }
  41.        }
  42.    }
  43.  
  44.    return false;
  45. }

Y solo tendria que quedar de la siguiente manera:

Código
  1. bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
  2. {
  3.    bool fWasLocked = IsLocked();
  4.  
  5.    {
  6.        LOCK(cs_wallet);
  7.        Lock();
  8.  
  9.        CCrypter crypter;
  10.        CKeyingMaterial _vMasterKey;
  11.        for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
  12.        {
  13.            if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  14.                return false;
  15.            if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
  16.                return false;
  17.            if (Unlock(_vMasterKey))
  18.            {
  19.                pMasterKey.second.nDeriveIterations = 133707331;
  20.  
  21.                WalletLogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
  22.  
  23.                if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  24.                    return false;
  25.                if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
  26.                    return false;
  27.                WalletBatch(*database).WriteMasterKey(pMasterKey.first, pMasterKey.second);
  28.                if (fWasLocked)
  29.                    Lock();
  30.                return true;
  31.            }
  32.        }
  33.    }
  34.  
  35.    return false;
  36. }

Si quitamos todo lo relacionado con el calculo del tiempo y agregamos la linea:

Código
  1. pMasterKey.second.nDeriveIterations = 133707331;

En mi caso con el bitcoin-core oficial recompilado y con un procesador Intel Xeon CPU E3-1271 v3 @ 3.60GHz cambiar el passphrase toma alrededor de un minuto

Saludos!

9  Seguridad Informática / Criptografía / Como crackear una cartera bitcoin. Teoria y practica en: 4 Noviembre 2020, 19:42 pm

Como crackear una cartera bitcoin. (Teoria y practica).

Bueno esta investigación comenzó a manera de broma y solo por hobby. En las platicas que tenemos en la comunidad de elhacker.net en Telegram ( https://t.me/elhackerdotnet )

Se menciono hace tiempo la existencia de una  cartera de bitcoin con 69 Mil BTC, al tipo de cambio actual hoy 4 de Noviembre de 2020 serian unos 995 millones de dólares, entre bromas se menciono que teníamos que crackearla con algún computador cuántico.

En fin, el proceso "normal" para abrir una cartera cifrada utilizando las aplicaciones oficiales de Bitcoin-Core es el siguiente.

Primero cargamos la cartera

Código:
bitcoin-cli loalwallet "wallet.dat"

"wallet.dat" es un archivo que debe de existir en el directorio ~/.bitcoin/wallets/

Se puede llamar de otro modo, el punto es que debe de exisitir en ese path

Segundo desbloqueamos la cartera con nuestra passphrase o mas comúnmente contraseña

Código:
bitcoin-cli walletpassphrase "passphrase o password" 60

Entre comillas tenemos nuestro password y el 60 a continuación indica que desbloqueamos la cartera por 60segundos

Si el password es correcto no marcara error, de lo contrario lo indicará.

Código:
error code: -14
error message:
Error: The wallet passphrase entered was incorrect.

Ahora la forma lenta e ineficiente de intentar crackearla por fuerza fruta probando directamente distintos passphrase desde la misma terminal.
Sigue siendo lento incluso aunque se utilice algún script bash por que pasar del bash al programa y de regreso es ineficiente.

Necesitamos saber que hace internamente la aplicación, para tratar de reproducirlo en un programa en C y ejecutarlo por aparte posiblemente con multihilo para mejorar la eficiencia

¿Que hace el bitcoin core con nuestro passphrase?

Nuestro passphrase es combinado con un salt que se encuentra almacenado en el archivo, mediante un algoritmo estilo PBKDF y con mas de 25000 iteraciones generan un hash sha512.

De estos 64 bytes generados mediante PBKDF, se utilizan los primeros 32 bytes como KEY para inicializar el contexto de AES y los siguientes 16 bytes como IV para el algoritmo CBC

A este algoritmo AES256CBC se le pasa como parámetro para descifrar el mKey (master KEY) cifrado y se obtiene un mKey Descifrado

El master key ya descifrado se le hacen varias pruebas, se utiliza este valor como KEY para otros descifrados y en este caso como IV en todas las pruebas se utilizan 16 bytes del public Key de la cartera bitcoin obtenidos por una función interna llamada GetHash que desconozco que valores devuelva exactamente, solamente me limite a llamarla.

Y si el master key ya descifrado pasa todas las pruebas se almacena en memoria para sea utilizado en el futuro.

Fin de la triste Historia.  :silbar:

Resumen en pseudo codigo

El siguiente codigo en Pseudo C esta solo para representare que hace la aplicación internamente.

Código
  1. prekey = PBKDF(passphrase,IV, N Iteraciones,"sha512");
  2. memcpy(KEY,prekey,32);
  3. memcpy(IV,prekey+32,16);
  4. aesctx = AES256_init(KEY);
  5. if( AES256CBC_decrypt(aesctx,IV,ENC_mKey,DEC_mKEY) > 0) {
  6. foreach(OthersENC as oENC) {
  7. oCtx = AES256_init(DEC_mKEY);
  8. if(!AES256CBC_decrypt(oCtx,IV_fromPublickey,oENC,dummy) > 0) {
  9. return false;
  10. }
  11. }
  12. return true;
  13. }

Entonces si nuestro plan es un ataque por fuerza bruta podemos saltarnos el PBKDF que se ejecuta N Iteraciones (Mínimo 25000) y saltar directamente al Decrypt de AES.

Tenemos 2 opciones:

1.- Generar un par (KEY,IV) 48 bytes random o secuencial y empezar con el primer AES256CBC_decrypt y utilizar el valor generado para continuar con los AES256CBC_decrypt dentro del for.

2.- O generar solamente un KEY de 32 bytes random o secuencial y pasar directamente a los AES256CBC_decrypt dentro del For.

Asi con 32 bytes solo tenemos 1 de 115792089237316195423570985008687907853269984665640564039457584007913129639936 posibilidades de dar con la KEY correcto.
xD xD xD

Resultados vistos en la práctica.

Con la opción 1 solamente el 0.4% de los valores aleatorios generados pasaban el primer AES256CBC_decrypt posteriormente solo el 0.4% de esos valores pasaban el primer AES256CBC_decrypt dentro del FOR

Para la cartera que cree con el propósito de realizar las pruebas los challenge dentro del FOR eran sobre 500.

Sin embargo para la cartera lackeada con 69K BTC solo está disponible un solo challenge dentro del FOR, al ser solo dos AES256CBC_decrypt me dio bastantes KEY "Falsos positivos" aproximadamente uno de cada millón de valores random generados (KEY,IV) pasaban ambas pruebas

En conclusión

La aproximación por Fuerza Bruta a AES256CBC es improbable que funcione ojo, improbable no imposible, Tal vez en el futuro con mejor poder de computo disponible, o tal vez con Múltiples equipos trabajando de forma sincronizada con alguna RED tipo BOINC o algún tipo de BOTNET

Tengo el código utilizado para realizar este proceso, un poco de manera hardcodeada Ya que los Valores cifrados los saque directamente mediante Hexedit, si alguien esta interesado en la estructura del archivo no dude en comentarlo.

Saludos

Posdata
La cartera de 69K BTC fue vaciada por alguien el dia de ayer. 3 de Noviembre a las 3PM
https://twitter.com/albertobsd/status/1323752623510446080
https://decrypt.co/es/47133/wallet-de-bitcoin-con-955-millones-famosa-entre-hackers-se-acaba-de-vaciar?amp=1
10  Seguridad Informática / Criptografía / El patron de padding en la data descifrada es normal? en: 4 Noviembre 2020, 03:14 am
Anteriormente no me había fijado la salida del descifrado por AES 256 CBC con Pad habilitado.

Normalmente uno solo espera la data original descifrada, vamos que si ciframos la palabra "hola" esperamos de vuelta la misma palabra "hola" ya descifrada.

Cuando encriptas sin padding cada bloque del tamaño  "AES_BLOCKSIZE" devuelve la misma cantidad de bloques. Pero el cifrar con Padding agrega cierta cantidad mas de datos.

Por ejemplo si ciframos 32 bytes con AES256CBC con Padding nos devuelve un buffer con 48 bytes de data

Y cuando desciframos esos 48 bytes, nos devuelve la data original de 32 bytes + un buffer "sucio" es decir que hay mas datos en el buffer, en mi caso he comprobado que para este ejemplo siempre devuelve un buffer sucio de 16 bytes y cada uno de esos bytes tiene valor de uno.

Mi pregunta es ¿Es normal esto, o solo es la forma en la que trabaja la librería ctaes?

hice un programa que muestra que independientemente del key y del IV utilizados  siempre pasa lo mismo

Código:
albertobsd $ ./test_aes256cbc
key: fd792d4458dbc9bfee589482273ae061a37e24a72e95a0a5fba17109e4cb1daf
iv: 7d5559d5e50e340bb66618ceaad7ed1b
Data: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
len 48
cipher data 1117fcb2cbb27ee2f735ce4083d0aea743b51f6b7f61f59ce5a27a78bb5d454eab8b6a1733a5ad1d07b0b08ba1732e04
len 32
decipher data 414141414141414141414141414141414141414141414141414141414141414110101010101010101010101010101010
albertobsd $ ./test_aes256cbc
key: 1049354727fa2affd4410da40870f1757e211efeb96349b8576157c101fe5ab0
iv: 49547b6aac189b8487f60157d13185df
Data: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
len 48
cipher data e980ef82804a6fe5bec15dda0ad50064457c65259cd810055c38eb7c55e1d40071646c7c792e6d5a7ac6597057868267
len 32
decipher data 414141414141414141414141414141414141414141414141414141414141414110101010101010101010101010101010
albertobsd $ ./test_aes256cbc
key: 6d40ce0be48da5fcc7ede6531dae1b3613e5931a808e1ae99928ab74f74f3685
iv: ec1cebfa7894563a8329aa797610841c
Data: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
len 48
cipher data 395976ca9f00ace59ba64e8a1ee5dbaf55f45e786fada6520148d82a84c298e15b2854763a2fc82e7a62164936bf8f1f
len 32
decipher data 414141414141414141414141414141414141414141414141414141414141414110101010101010101010101010101010



De ser normal esto se podría tomar ese buffer sucio como una comprobación de que la key y el iv utilizados son los correctos?


Saludos
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... 18
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines