Descargar contenido multimedia de ciertas webs

Hoy en día, la descarga de contenido multimedia de ciertas webs es imposible o muy difícil. En ciertos casos lo entiendo, exponer el contenido supone una pérdida de ingresos y eso es inaceptable. Las cadenas de TV son tema aparte, emiten contenido por varios medios y les gusta que lo veas y que lo compartas, eso sí, que lo compartas desde su plataforma, ya que lo que estás compartiendo es un enlace, no el vídeo.
Este caso es un caso intermedio entre una plataforma de pago que codifica sus contenidos y una web que nos permita descargar su contenido directamente.
Imaginemos que vemos un vídeo y queremos mandarlo por Whatsapp a nuestros amigos. Lo primero es echar un vistazo al código fuente de la web y localizar el código del reproductor web (player). Para esta tarea podemos ayudarnos de una extensión muy conocida para navegadores como es Firebug. Una vez instalada, la activamos con F12 y mediante el botón Inspect localizamos el player.
...
<p itemprop="keywords" itemscope="itemscope" itemtype="http://schema.org/Text" class="antetitulo" lang="es">EL INTERMEDIO LE PILLA EN "EL TRONO"</p>
<h1 class="title-new" itemprop="headline">Joaquín Reyes se mete en la piel de Juan Carlos I: "Soy tan campechano que podéis llamarme Juan Carlos Palote"</h1>
<sumary class="entradilla" itemprop="description">
<p><p class="MsoNormal">Los reyes eméritos han celebrado sus bodas de esmeralda y
con motivo de tan señalada fecha, Juan Carlos I ha hecho un hueco en su
apretada agenda para concederle unos minutos a <a title="<b>El Intermedio</b>" href="http://www.lasexta.com/temas/el_intermedio-1" target="_blank"><b>El Intermedio</b></a>. Eso sí, en su
versión de <a title="<b>Joaquín Reyes</b>" href="http://www.lasexta.com/temas/joaquin_reyes-1" target="_blank"><b>Joaquín Reyes</b></a>. <o:p></o:p></p> </sumary>
<div class="great-element-multimedia">
<section class="modVideo a3mod_player" data-mod="a3mod_player" data-model="/json/video/7/2017/05/15/591a08c1986b2810b31577c1.json">
<a itemprop="url" href="#" class="icon link-content" title="" data-mod-elem="icon">
<div class="wrap-img" role="banner">
<div itemprop="video" itemscope itemtype="http://schema.org/VideoObject">
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source media="(max-width:520px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/64.jpg" />
<source media="(max-width:1023px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/60.jpg" />
<source media="(min-width:1024px)" srcset="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" />
<!--[if IE 9]></video><![endif]-->
<img src="http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/58.jpg" alt="Joaquín Reyes, como el rey Juan Carlos I" title="Joaquín Reyes, como el rey Juan Carlos I" />
</picture>
<meta itemprop="description" content=""/>
<meta itemprop="name" content=""/>
<meta itemprop="thumbnailUrl" content="" />
<meta itemprop="uploadDate" content=""/>
<meta itemprop="url" content=""/>
<meta itemprop="width" content=""/>
<meta itemprop="height" content=""/>
</div>
</div>
</a>
</section>
</div>
...
Si os fijáis bien, el reproductor hace referencia a un archivo json (591a08c1986b2810b31577c1.json), reconstruimos la url y miramos su contenido
{"id":"591a08c1986b2810b31577c1","type":"video","tipo":"video","subtipo":"video","imgThumb":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/29.jpg","imgPoster":"http://fotografias.lasexta.com/clipping/cmsimages02/2017/05/15/14069ECA-B0E4-4F09-A5B7-04B600C016AD/31.jpg","live":false,"autoplay":true,"sources":[{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/manifest_mvlist.mpd","type":"application/dash+xml"},{"src":"http://vclip.atresmedia.com/vclip/_definst_/smil:assets10/2017/05/15/01229E28-A57E-4AC9-AFE7-EF1C27B5AA2A/es.smil/playlist.m3u8","type":"application/vnd.apple.mpegurl"}],"omniture":{"section":"Joaquín Reyes","category":"El Intermedio","channel":"lasexta","type":"short","name":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","embeddedMode":false},"comscore":{"comscoreTag":"LASEXTA.COM","channel":"lasexta","kantar":{"programID":"1019","firstBroadcastDate":"*null","firstBroadcastTime":"*null","typeTvStream":"0002","kantarGenre":"0","channelId":"240"},"content_form":"short_form"},"urlHits":"http://hits.lasexta.com/l6//591a08c1986b2810b31577c1/3/348128,351435,351827,351865/","duration":"211.797333","embeddedUrl":"<iframe src=\"http://www.lasexta.com/embed/el-intermedio-le-pilla-en-el-trono/video/7/2017/05/15/591a08c1986b2810b31577c1\" width=\"560\" height=\"315\" frameborder=\"0\" allowfullscreen></iframe>","playondraw":true,"nextRelated":{"service_url":"http://www.lasexta.com/json/video/7/2017/05/15/591a08c1986b2810b31577c1_related.json"},"subtitle":[],"titulo":"Joaquín Reyes se mete en la piel de Juan Carlos I: \"Soy tan campechano que podéis llamarme Juan Carlos Palote\"","descripcion":"","sociales":{"hasTwitter":true,"hasFacebook":true,"hasGooglePlus":true,"hasWhatsapp":true,"twitter":"EL INTERMEDIO LE PILLA EN “EL TRONO”","facebook":"EL INTERMEDIO LE PILLA EN “EL TRONO”","googlePlus":"EL INTERMEDIO LE PILLA EN “EL TRONO”","whatsapp":"","hashtag":"","via":"sextaNoticias","urlPage":"https://goo.gl/cu98f0"},"vp_data":{"vp_category":"Atresmedia/Lasexta/programas/el-intermedio*","vp_tags":"","vp_content_form":"short_form"}}
Se puede ver a simple vista una lista de reproducción playlist.m3u8, cuyo contenido contiene más listas de reproducción con diferentes calidades.
#EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:BANDWIDTH=796400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360 chunklist_b724000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1159400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=640x360 chunklist_b1054000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1643400,CODECS="avc1.77.30,mp4a.40.5",RESOLUTION=720x404 chunklist_b1494000.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2248400,CODECS="avc1.77.31,mp4a.40.5",RESOLUTION=1280x720 chunklist_b2044000.m3u8
Reconstruimos la URL para la lista de reproducción de mayor calidad e inspeccionamos su contenido.
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, media_b2044000_0.ts #EXTINF:10.0, media_b2044000_1.ts #EXTINF:10.0, media_b2044000_2.ts #EXTINF:10.0, media_b2044000_3.ts #EXTINF:10.0, media_b2044000_4.ts #EXTINF:10.0, media_b2044000_5.ts #EXTINF:10.0, media_b2044000_6.ts #EXTINF:10.0, media_b2044000_7.ts #EXTINF:10.0, media_b2044000_8.ts #EXTINF:10.0, media_b2044000_9.ts #EXTINF:10.0, media_b2044000_10.ts #EXTINF:10.0, media_b2044000_11.ts #EXTINF:10.0, media_b2044000_12.ts #EXTINF:10.0, media_b2044000_13.ts #EXTINF:10.0, media_b2044000_14.ts #EXTINF:10.0, media_b2044000_15.ts #EXTINF:10.0, media_b2044000_16.ts #EXTINF:10.0, media_b2044000_17.ts #EXTINF:10.0, media_b2044000_18.ts #EXTINF:10.0, media_b2044000_19.ts #EXTINF:10.0, media_b2044000_20.ts #EXTINF:1.92, media_b2044000_21.ts #EXT-X-ENDLIST
Se pueden ver 21 archivos con extensión TS de 10 segundos cada uno a excepción del último que dura 1.92 segundos. Los archivos TS no son más que archivos MP4 por lo que una vez descargados, los podemos unir con MP4Tools por ejemplo.
La tarea es costosa, pero si os apetece enviar un vídeo en vez de un enlace, ya sabéis que en determinados casos se puede hacer.
Blooper Tech Movie IV – La Jungla 4.0 (Live Free or Die Hard)

La esperada cuarta entrega de La Jungla de Cristal se metió de lleno en el mundo de los Hackers. Cuando la vi en su época he de reconocer que el detalle que explicaremos a continuación me pasó desapercibido.
Hablemos de mineralismo.. digo de IPs privadas
Digamos que a día de hoy, quien más y quien menos, sabe lo que es una IP y para que sirve. Si no lo sabes, digamos resumidamente que es un número que nos identifica dentro de una red. En el protocolo IPv4 son 4 grupos de números entre 0 y 255. Como todo protocolo que se precie, tiene ciertos rangos de direcciones reservados para redes privadas y el resto digamos que son públicas. El rango de direcciones privadas para IPv4 es el siguiente:
- De 10.0.0.0 a 10.255.255.255
- 172.16.0.0 a 172.31.255.255
- 192.168.0.0 a 192.168.255.255
- 169.254.0.0 a 169.254.255.255
BTM
Como hemos hablado en otras ocasiones, en el cine se exagera todo lo relacionado con el mundo tecnológico y en especial el mundo «Hacking«, y es normal encontrarnos elaborados entornos gráficos que quedan muy bien pero que no existen en el mundo real.
En la Jungla 4.0 usaron IPs privadas como públicas sin ton ni son y perdón si me repito pero, ¿nadie contrata consultores?, es decir, vas a realizar una película sobre hackers y ¿no contratas a alguien que tenga unos conocimientos mínimos?, pues al parecer es mucho pedir, las imágenes hablan por si solas.
En la imagen superior se puede ver como están conectados al sistema de ventilación del NDA. Podría pasar si estuvieran físicamente en las instalaciones del NDA y se conectaran desde un equipo de allí, pero al hacerlo de forma remota crean un enorme gazapo.
Esto es una pequeña muestra de lo que muestra la película. También hay escenas en las que se usan IPs públicas correctamente pero en general cometen el error de forma recurrente.
Enlaces
- ¿Qué es una IP? [Wikipedia]
- Redes privadas [Wikipedia]
- La Jungla 4.0 [IMDB]
Algoritmo de HEdit 2.1.11

Rebuscando entre todo el caos que puede llegar a ser mi disco duro, he encontrado una serie de programas que utilizaba antiguamente cuando empezó a interesarme el Cracking. Ya sabéis que no soy partidario de crackear programas comerciales pero hoy voy a hacer una excepción ya que la versión del programa es muy vieja (1997) e incluso podría considerarse abandonware.
Este ejercicio es ideal para los que están empezando ya que es fácil localizar donde está el algoritmo y éste es sumamente sencillo.
Algoritmo
Address Hex dump Command Comments
00402213 E8 78170000 CALL HEdit.00403990
........
004039C0 8BC1 MOV EAX,ECX
004039C2 99 CDQ
004039C3 33C2 XOR EAX,EDX
004039C5 2BC2 SUB EAX,EDX
004039C7 83E0 03 AND EAX,00000003
004039CA 33C2 XOR EAX,EDX
004039CC 2BC2 SUB EAX,EDX
004039CE 8A540C 04 MOV DL,BYTE PTR SS:[ECX+ESP+4] ;Coge el dígito i*3
004039D2 8A5C04 04 MOV BL,BYTE PTR SS:[EAX+ESP+4] ;Coge el dígito i
004039D6 8D4404 04 LEA EAX,[EAX+ESP+4] ;Guarda en memoria 12EE90
004039DA 32DA XOR BL,DL
004039DC 41 INC ECX ; i +=1
004039DD 81F9 00010000 CMP ECX,100 ;El bucle se repite 256 veces (0x100)
004039E3 8818 MOV BYTE PTR DS:[EAX],BL
004039E5 ^ 7C D9 JL SHORT HEdit.004039C0
004039E7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
004039EB 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039ED 7D 02 JGE SHORT HEdit.004039F1 ;Si es 0 se acabó
004039EF F7D8 NEG EAX
004039F1 3B8424 0C010000 CMP EAX,DWORD PTR SS:[ESP+10C] ;Comprobación de serial válido
004039F8 75 13 JNE SHORT HEdit.00403A0D ;Si no es igual bad boy
004039FA 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039FC 74 0F JE SHORT HEdit.00403A0D ;Si es 0 se acabó
004039FE B8 01000000 MOV EAX,1
00403A03 5B POP EBX
00403A04 81C4 00010000 ADD ESP,100
00403A0A C2 0800 RETN 8
En resumen hace esto:
- Nombre introducido: deurus
- Convierte el nombre a mayúsculas
D E U R U S
44 45 55 52 55 53 (En Hexadecimal)
1) 55 xor 44 = 11
2) 53 xor 45 = 16
3) 00 xor 55 = 55
4) 00 xor 52 = 52
--------------- solo vale hasta aquí EAX(32 bits)
5) 00 xor 55 = 55
6) 00 xor 53 = 53
7) 00 xor 00 = 00
8) ...
HEX DEC
Serial = 52551611 = 1381307921
Como veis, realiza un bucle 256 veces pero como al final utiliza el registro EAX para hacer la comparación, solamente nos sirven las cuatro primeras operaciones. De hecho, no comprueba ni la longitud del nombre por lo que si introducimos un solo dígito como nombre, el serial será el valor ascii de ese dígito en decimal. La única comprobación que realiza es que el serial no sea 0.
Keygen
Os dejo una prueba de concepto en Javascript.
var nombre = "deurus";
nombre = nombre.toUpperCase();
var serial = "";
serial = serial + nombre.charCodeAt(3).toString(16) + nombre.charCodeAt(2).toString(16);
serial = serial + (nombre.charCodeAt(5) ^ nombre.charCodeAt(1)).toString(16);
serial = serial + (nombre.charCodeAt(2) ^ nombre.charCodeAt(0)).toString(16);
serial = "Nº Serie: " + parseInt(serial,16);
document.write(serial);
Enlaces
Solución al CrackMe DAE 430

- Introducción
- Herramientas utilizadas
- Desempacado con Ollydbg 2 (Videotutorial)
- Desempacado con Ollydbg 1 (Videotutorial)
- Análisis de la rutina del número de serie
- Links
Introducción
Este Crackme está basado en la protección de DVD Audio Extractor 4.3. Afrontaremos dos partes, una primera donde desempacaremos PECompact 2.x y otra donde analizaremos la rutina de comprobación del número de serie. Os adelante que la única dificultad reside en desempacar ya que la rutina del serial es bastante floja.
El motivo que me ha llevado a realizar un apartado para Ollydbg 1 y otro para Ollydbg 2 es principalmente por que con Ollydbg 2 lo haremos desde Windows 7 x64 y con Ollydbg 1 desde Windos 7 x32.
Herramientas utilizadas
- Ollydbg2 con los plugins OllyDumEX y CmdBar.
- Ollydbg1 con plugin OllyDump.
- Import Reconstructor 1.6.
Desempacado con Ollydbg 2
Videotutorial disponible: http://youtu.be/-63yEUTqP-c.
Resumen de pasos:
- Cargar Crackme en Ollydbg.
- Pulsar F9.
- Poner breakpoint «bp VirtualFree»
- Pulsamos F9 dos veces.
- Pulsamos Ctrl+F9.
- Pulsamos F8 hasta salir del RETN.
- Ponemos breakpoint a JMP EAX.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el Crackme en Olly y aparecemos aquí.
2. Pulsamos una vez F9 y veremos esto:
3. Ponemos un breakpoint de la siguiente manera «bp VirtualFree» con la ayuda del plugin CmdBar.
4. Pulsamos F9 dos veces y aparecemos aquí.
5. A continuación pulsamos Ctrl+F9 y veremos esto.
6. Pulsamos F8 hasta salir del RETN anterior y veremos esto.
7. Al final vemos lo que estábamos buscando. El JMP EAX es el salto que nos lleva al punto de entrada original (OEP). Ponemos un breakpoint en JMP EAX y pulsamos F9, cuando se detenga Ollydbg, pulsamos F8 y aparecemos aquí.
8. Ya tenemos a PECompact contra las cuerdas, ahora mismo tenemos el Crackme desempacado en memoria.
Hacemos click en Plugins > OllyDumpEx > Dump process y veremos esto.
Pulsamos en Dump y esto nos generará un archivo que se llama DAE430_CrackMe_dump.
9. A continuación con Import Reconstructor seleccionamos el crackme y pulsamos IAT AutoSearch y Get Imports.
Veremos unas importaciones NO válidas, pulsamos en Show Invalid y las clickamos con el botón derecho > Delete thunks.
Finalmente pulsamos Fix Dump y elegimos el crackme dumpeado anteriormente. Con esto ya hemos finalizado el desempacado.
Desempacado con Ollydbg 1
Videotutorial disponible: http://youtu.be/mm42HRlPXOE
Resumen de pasos:
- Cargamos el crackme en Ollydbg.
- Pulsamos F8 hasta el segundo Call y en éste entramos con F7.
- Seguimos con F8.
- Buscamos JMP EAX, le ponemos un breakpoint y ejecutamos hast que pare en el.
- Situados en JMP EAX, pulsamos F8 y llegamos al OEP.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el crackme en Ollydbg y vemos esto.
2. Pulsamos F8 hasta que veamos dos Calls. Pulsamos F8 hasta el segundo Call y cuando estemos situados encima de él pulsamos F7 para entrar en el.
Dentro del segundo call veremos esto.
3. Seguimos con F8 y llegamos aquí.
4. Sin tracear, nos desplazamos por el código hasta encontrar un poco más abajo JMP EAX. Le ponemos un breakpoint y pulsamos F9.
5. Cuando estemos situados en JMP EAX pulsamos F8 y llegamos al punto de entrada original (OEP).
6. Ahora con el plugin OllyDump vamos a dumpear el ejecutable que tenemos desempacado en memoria.
Dumpeamos.
7. Finalmente con Import reconstructor arreglamos las importaciones.
Análisis de la rutina del número de serie
Cargamos en Ollydbg el crackme desempacado y en las referencias de texto encontramos el mensaje «Gracias por registrarte». Pulsamos en él y llegamos a la rutina de comprobación del serial que desgranamos a continuación.
00401B89 . 83F9 03 CMP ECX,3 ; Len(nombre) >=3 00401B8C . 0F8E 46010000 JLE DAE430_C.00401CD8 00401B92 . B2 44 MOV DL,44 ; Dl=44(Letra D) 00401B94 . 31C0 XOR EAX,EAX 00401B96 . 31FF XOR EDI,EDI 00401B98 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 1er digito con la letra D 00401B9B . 74 05 JE SHORT DAE430_C.00401BA2 00401B9D > BF 01000000 MOV EDI,1 00401BA2 > 40 INC EAX 00401BA3 . 83F8 04 CMP EAX,4 00401BA6 . 74 0C JE SHORT DAE430_C.00401BB4 00401BA8 . 8A5404 45 MOV DL,BYTE PTR SS:[ESP+EAX+45] ; Memoria 22FAF5 a 22FAF | Lee los digitos A1X 00401BAC . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Los compara 00401BAF .^ 75 EC JNZ SHORT DAE430_C.00401B9D 00401BB1 .^ EB EF JMP SHORT DAE430_C.00401BA2 00401BB3 90 NOP 00401BB4 > 66:0FBE4424 53 MOVSX AX,BYTE PTR SS:[ESP+53] ; EAX = 5ºdígito 00401BBA . 8D1480 LEA EDX,DWORD PTR DS:[EAX+EAX*4] ; EAX*4+EAX = A 00401BBD . 8D04D0 LEA EAX,DWORD PTR DS:[EAX+EDX*8] ; A*8 + 5ºdigito=B 00401BC0 . 66:C1E8 08 SHR AX,8 ; B/100=C 00401BC4 . C0F8 02 SAR AL,2 ; C/4=D 00401BC7 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BCB . C0FA 07 SAR DL,7 ; 5ºdígito/80=E 00401BCE . 29D0 SUB EAX,EDX ; E-D=F 00401BD0 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; F*4*F=G 00401BD3 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; G*4+G=H 00401BD6 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BDA . 29C2 SUB EDX,EAX ; 5ºdigito - H = I 00401BDC . 83C2 41 ADD EDX,41 ; I+41 = J 00401BDF . 885424 4A MOV BYTE PTR SS:[ESP+4A],DL ; GUARDA J EN LA MEMORIA 22FAFA 00401BE3 . 66:0FBE4424 54 MOVSX AX,BYTE PTR SS:[ESP+54] 00401BE9 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401BEC . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401BEF . 66:C1E8 08 SHR AX,8 00401BF3 . C0F8 02 SAR AL,2 00401BF6 . 8A4C24 54 MOV CL,BYTE PTR SS:[ESP+54] 00401BFA . C0F9 07 SAR CL,7 00401BFD . 29C8 SUB EAX,ECX 00401BFF . 89C6 MOV ESI,EAX 00401C01 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C04 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C07 . 8A4424 54 MOV AL,BYTE PTR SS:[ESP+54] 00401C0B . 89F1 MOV ECX,ESI 00401C0D . 29C8 SUB EAX,ECX 00401C0F . 89C6 MOV ESI,EAX 00401C11 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C14 . 884424 4B MOV BYTE PTR SS:[ESP+4B],AL ; GUARDA J2 EN LA MEMORIA 22FAFB para el 6ºdígito 00401C18 . 66:0FBE4424 55 MOVSX AX,BYTE PTR SS:[ESP+55] 00401C1E . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C21 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C24 . 66:C1E8 08 SHR AX,8 00401C28 . C0F8 02 SAR AL,2 00401C2B . 8A4C24 55 MOV CL,BYTE PTR SS:[ESP+55] 00401C2F . C0F9 07 SAR CL,7 00401C32 . 29C8 SUB EAX,ECX 00401C34 . 89C6 MOV ESI,EAX 00401C36 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C39 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C3C . 8A4424 55 MOV AL,BYTE PTR SS:[ESP+55] 00401C40 . 89F1 MOV ECX,ESI 00401C42 . 29C8 SUB EAX,ECX 00401C44 . 89C6 MOV ESI,EAX 00401C46 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C49 . 884424 4C MOV BYTE PTR SS:[ESP+4C],AL ; GUARDA J3 EN LA MEMORIA 22FAFC para el 7ºdígito 00401C4D . 66:0FBE4424 56 MOVSX AX,BYTE PTR SS:[ESP+56] 00401C53 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C56 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C59 . 66:C1E8 08 SHR AX,8 00401C5D . C0F8 02 SAR AL,2 00401C60 . 8A4C24 56 MOV CL,BYTE PTR SS:[ESP+56] 00401C64 . C0F9 07 SAR CL,7 00401C67 . 29C8 SUB EAX,ECX 00401C69 . 89C6 MOV ESI,EAX 00401C6B . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C6E . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C71 . 8A4424 56 MOV AL,BYTE PTR SS:[ESP+56] 00401C75 . 89F1 MOV ECX,ESI 00401C77 . 29C8 SUB EAX,ECX 00401C79 . 89C6 MOV ESI,EAX 00401C7B . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C7E . 884424 4D MOV BYTE PTR SS:[ESP+4D],AL ; GUARDA J4 EN LA MEMORIA 22FAFD para el 8ºdígito 00401C82 . B8 08000000 MOV EAX,8 00401C87 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL 00401C8A . 74 05 JE SHORT DAE430_C.00401C91 00401C8C > BF 01000000 MOV EDI,1 00401C91 > 40 INC EAX 00401C92 . 83F8 0C CMP EAX,0C 00401C95 . 74 0D JE SHORT DAE430_C.00401CA4 00401C97 . 8A5404 42 MOV DL,BYTE PTR SS:[ESP+EAX+42] 00401C9B . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 22FAFA y siguientes con 9, 10, 11 y 12avo digito 00401C9E .^ 75 EC JNZ SHORT DAE430_C.00401C8C 00401CA0 .^ EB EF JMP SHORT DAE430_C.00401C91 00401CA2 . 66:90 NOP 00401CA4 > 89F8 MOV EAX,EDI ; | 00401CA6 . FEC8 DEC AL ; | 00401CA8 . 74 5C JE SHORT DAE430_C.00401D06 ; | 00401CAA . C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CB2 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CBA . C74424 04 51004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041005>; |ASCII "Gracias por registrarte." 00401CC2 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CC9 . E8 EE000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CCE . 83EC 10 SUB ESP,10 00401CD1 . 31C0 XOR EAX,EAX 00401CD3 .^ E9 F2FBFFFF JMP DAE430_C.004018CA 00401CD8 > C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CE0 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CE8 . C74424 04 6A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041006>; |ASCII "Nombre mínimo 4 caracteres." 00401CF0 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CF7 . E8 C0000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CFC . 83EC 10 SUB ESP,10 00401CFF . 31C0 XOR EAX,EAX 00401D01 .^ E9 C4FBFFFF JMP DAE430_C.004018CA 00401D06 > C74424 0C 10000000 MOV DWORD PTR SS:[ESP+C],10 ; | 00401D0E . C74424 08 34004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041003>; |ASCII "Error" 00401D16 . C74424 04 3A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041003>; |ASCII "Registro fallido." 00401D1E . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401D25 . E8 92000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
Resumen
- El nombre debe tener más de 3 dígitos aunque no lo usa para el número de serie. - El serial tiene 12 dígitos dividiendose en tres partes, 111122223333. - La primera parte 1111 es comparada directamente con DA1X. - Segunda parte (2222), para los dígitos 5º, 6º, 7º y 8º hace lo siguiente: dígito *4 + dígito = A A*8 + dígito=B B/100 = C C/4 = D dígito/80 = E E-D = F F*4*F = G G*4+G = H digito - H = I I+41 = J GUARDA J EN LA MEMORIA 22FAFA **Todo esto se puede resumir en dígito mod 19 + 41 - Tercera parte (3333). Finalmente compara el resultado del 5º, 6º, 7º y 8º dígitos con el 9º, 10º, 11º y 12º dígitos.
Ejemplo:
Serial = DA1X12345678 1 - (31h mod 19h) + 41h = 48h(Y) 2 - (32h mod 19h) + 41h = 41h(A) 3 - (33h mod 19h) + 41h = 42h(B) 4 - (34h mod 19h) + 41h = 43h(C) Compara Y con 5 Compara A con 6 Compara B con 7 Compara C con 8 Luego el serial correcto sería DA1X1234YABC
Links
Algoritmo de HEdit 2.1.11

Rebuscando entre todo el caos que puede llegar a ser mi disco duro, he encontrado una serie de programas que utilizaba antiguamente cuando empezó a interesarme el Cracking. Ya sabéis que no soy partidario de crackear programas comerciales pero hoy voy a hacer una excepción ya que la versión del programa es muy vieja (1997) e incluso podría considerarse abandonware.
Este ejercicio es ideal para los que están empezando ya que es fácil localizar donde está el algoritmo y éste es sumamente sencillo.
Algoritmo
Address Hex dump Command Comments
00402213 E8 78170000 CALL HEdit.00403990
........
004039C0 8BC1 MOV EAX,ECX
004039C2 99 CDQ
004039C3 33C2 XOR EAX,EDX
004039C5 2BC2 SUB EAX,EDX
004039C7 83E0 03 AND EAX,00000003
004039CA 33C2 XOR EAX,EDX
004039CC 2BC2 SUB EAX,EDX
004039CE 8A540C 04 MOV DL,BYTE PTR SS:[ECX+ESP+4] ;Coge el dígito i*3
004039D2 8A5C04 04 MOV BL,BYTE PTR SS:[EAX+ESP+4] ;Coge el dígito i
004039D6 8D4404 04 LEA EAX,[EAX+ESP+4] ;Guarda en memoria 12EE90
004039DA 32DA XOR BL,DL
004039DC 41 INC ECX ; i +=1
004039DD 81F9 00010000 CMP ECX,100 ;El bucle se repite 256 veces (0x100)
004039E3 8818 MOV BYTE PTR DS:[EAX],BL
004039E5 ^ 7C D9 JL SHORT HEdit.004039C0
004039E7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
004039EB 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039ED 7D 02 JGE SHORT HEdit.004039F1 ;Si es 0 se acabó
004039EF F7D8 NEG EAX
004039F1 3B8424 0C010000 CMP EAX,DWORD PTR SS:[ESP+10C] ;Comprobación de serial válido
004039F8 75 13 JNE SHORT HEdit.00403A0D ;Si no es igual bad boy
004039FA 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039FC 74 0F JE SHORT HEdit.00403A0D ;Si es 0 se acabó
004039FE B8 01000000 MOV EAX,1
00403A03 5B POP EBX
00403A04 81C4 00010000 ADD ESP,100
00403A0A C2 0800 RETN 8
En resumen hace esto:
- Nombre introducido: deurus
- Convierte el nombre a mayúsculas
D E U R U S
44 45 55 52 55 53 (En Hexadecimal)
1) 55 xor 44 = 11
2) 53 xor 45 = 16
3) 00 xor 55 = 55
4) 00 xor 52 = 52
--------------- solo vale hasta aquí EAX(32 bits)
5) 00 xor 55 = 55
6) 00 xor 53 = 53
7) 00 xor 00 = 00
8) ...
HEX DEC
Serial = 52551611 = 1381307921
Como veis, realiza un bucle 256 veces pero como al final utiliza el registro EAX para hacer la comparación, solamente nos sirven las cuatro primeras operaciones. De hecho, no comprueba ni la longitud del nombre por lo que si introducimos un solo dígito como nombre, el serial será el valor ascii de ese dígito en decimal. La única comprobación que realiza es que el serial no sea 0.
Keygen
Os dejo una prueba de concepto en Javascript.
var nombre = "deurus";
nombre = nombre.toUpperCase();
var serial = "";
serial = serial + nombre.charCodeAt(3).toString(16) + nombre.charCodeAt(2).toString(16);
serial = serial + (nombre.charCodeAt(5) ^ nombre.charCodeAt(1)).toString(16);
serial = serial + (nombre.charCodeAt(2) ^ nombre.charCodeAt(0)).toString(16);
serial = "Nº Serie: " + parseInt(serial,16);
document.write(serial);
Enlaces
AperiSolve en tu Raspi

Acabo de montar AperiSolve en una Raspi que tenía por casa pensando que sería coser y cantar, pero me he encontrado con que el repositorio no estaba preparado para todas las distros Linux de forma estándar. El resultado lo he colgado en Github, de modo que para montarlo en vuestra propia Raspi solo tenéis que seguir estos pasos:
1. Clonar el repositorio git clone https://github.com/deurus/AperiSolve-Raspi3.git cd AperiSolve-Raspi3/AperiSolve 2. Construir los contenedores docker compose build docker compose up -d 3. Abrir la web http://<IP_RASPI>:5000
Si tenéis curiosidad de la adaptación que he tenido que hacer aquí están los pasos que he seguido:
1. Preparar el sistema
sudo apt update
sudo apt install -y git docker.io docker-compose
sudo usermod -aG docker $USER
newgrp docker
2. Clonar AperiSolve
git clone https://github.com/Zeecka/AperiSolve.git
cd AperiSolve
3. Crear la estructura de build para la imagen ARM/x86
nano docker-compose.yml
y pega este contenido:
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
zip \
p7zip-full \
binwalk \
foremost \
exiftool \
steghide \
ruby \
binutils \
pngcheck \
&& rm -rf /var/lib/apt/lists/*
COPY aperisolve/ /aperisolve/
RUN pip install --no-cache-dir -r /aperisolve/requirements.txt
WORKDIR /aperisolve
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "wsgi:app"]
4. Arreglar docker-compose.yml para ser válido y compatible
services:
web:
image: aperisolve-local
build: .
container_name: aperisolve-web
ports:
- "5000:5000"
depends_on:
- redis
- postgres
environment:
DB_URI: "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
worker:
image: aperisolve-local
container_name: aperisolve-worker
depends_on:
- redis
- postgres
environment:
DB_URI: "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
redis:
image: redis:7
container_name: aperisolve-redis
postgres:
image: postgres:16
container_name: aperisolve-postgres
environment:
POSTGRES_USER: aperiuser
POSTGRES_PASSWORD: aperipass
POSTGRES_DB: aperisolve
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
5. Modificar aperisolve/config.py
nano config.py
y pega este contenido:
from pathlib import Path
IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".tiff"]
WORKER_FILES = ["binwalk", "foremost", "steghide", "zsteg"]
RESULT_FOLDER = Path(__file__).parent.resolve() / "results"
RESULT_FOLDER.mkdir(parents=True, exist_ok=True)
6. Modificación de aperisolve/app.py
Sustituir la línea: app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI")
por:
default_db = "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI", default_db)
7. Construir la imagen
docker build -t aperisolve-local .
8. Levantar los contenedores
docker compose down
docker compose up -d
9. Comprobar logs
docker logs aperisolve-web --tail=50
docker logs aperisolve-worker --tail=50
10. Acceder a la web
- Desde cualquier máquina de la red local: http://IP-DE-LA-MAQUINA:5000
- Desde la Raspi: http://localhost:5000
11. Limpieza (cuando necesites)
- Reiniciar contenedores:
docker compose restart
- Borrar resultados antiguos:
sudo rm -r aperisolve/results/*
Blooper Tech Movie IV – La Jungla 4.0 (Live Free or Die Hard)

La esperada cuarta entrega de La Jungla de Cristal se metió de lleno en el mundo de los Hackers. Cuando la vi en su época he de reconocer que el detalle que explicaremos a continuación me pasó desapercibido.
Hablemos de mineralismo.. digo de IPs privadas
Digamos que a día de hoy, quien más y quien menos, sabe lo que es una IP y para que sirve. Si no lo sabes, digamos resumidamente que es un número que nos identifica dentro de una red. En el protocolo IPv4 son 4 grupos de números entre 0 y 255. Como todo protocolo que se precie, tiene ciertos rangos de direcciones reservados para redes privadas y el resto digamos que son públicas. El rango de direcciones privadas para IPv4 es el siguiente:
- De 10.0.0.0 a 10.255.255.255
- 172.16.0.0 a 172.31.255.255
- 192.168.0.0 a 192.168.255.255
- 169.254.0.0 a 169.254.255.255
BTM
Como hemos hablado en otras ocasiones, en el cine se exagera todo lo relacionado con el mundo tecnológico y en especial el mundo «Hacking«, y es normal encontrarnos elaborados entornos gráficos que quedan muy bien pero que no existen en el mundo real.
En la Jungla 4.0 usaron IPs privadas como públicas sin ton ni son y perdón si me repito pero, ¿nadie contrata consultores?, es decir, vas a realizar una película sobre hackers y ¿no contratas a alguien que tenga unos conocimientos mínimos?, pues al parecer es mucho pedir, las imágenes hablan por si solas.
En la imagen superior se puede ver como están conectados al sistema de ventilación del NDA. Podría pasar si estuvieran físicamente en las instalaciones del NDA y se conectaran desde un equipo de allí, pero al hacerlo de forma remota crean un enorme gazapo.
Esto es una pequeña muestra de lo que muestra la película. También hay escenas en las que se usan IPs públicas correctamente pero en general cometen el error de forma recurrente.
Enlaces
- ¿Qué es una IP? [Wikipedia]
- Redes privadas [Wikipedia]
- La Jungla 4.0 [IMDB]
Wechall Stegano Attachment (Esteganografía)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
En los retos de esteganografía ya uno se espera de todo, y cuantos más haces más enrevesados encuentras. Hoy no, hoy vamos a tratar un clásico dentro de este tipo de retos, ocultar un archivo dentro de otro.
Buscando la solución
Prácticamente lo primero que hago cuando me descargo una imágen en éste tipo de retos es abrirla con un editor hexadecimal, y en este caso hemos dado en el clavo. La abrimos con un editor cualquiera y al final del archivo encontramos que estamos tratando con un archivo ZIP (cabecera PK).
La abrimos con 7zip y vemos el prometido archivo txt, dentro ¿qué abrá?
Links
Solución a los retos criptográficos de Rogerfm.net

- Introducción
- Cripto 1
- Cripto 2
- Cripto 3
- Cripto 4
- Cripto 5
- Cripto 6
- Cripto 7
- Cripto 8
- Cripto 9
- Cripto 10
- Enlaces
Introducción
Los retos de encriptación son muy variados como hemos comentado anteriormente. Aquí tenemos unos buenos ejemplos de ello.
Cripto 1
En este primer nivel nos encontramos con un método de encriptación muy antíguo. Sólo diré como pista, que es de los más antiguos que se conocen.
ozhlofxrlmvhxzorulimrz
Lo primero que suelo hacer en este tipo de retos cuando son solamente letras, es comprobar las dos opciones más típicas, que son el cifrado César y Vigenere. En este caso necesitamos ahondar un poco más, aunque enseguida llegamos a la conclusión de que el cifrado usado es el afín. Un ataque por fuerza bruta nos devuelve la solución y los coeficientes utilizados.
Solución: A=25,B=25 – LASOLUCIONESCALIFORNIA
Fuente: http://www.dcode.fr/chiffre-affine
Cripto 2
En este segundo nivel recordaremos a un general romano muy conocido. Lo complicaremos un poco, sólo lo justo para que cueste algo más de cinco minutos encontrar la clave 🙂
oehoeahhjoexhkzqhfsvzhffhwrhotqk
Lo primero que nos viene a la cabeza es el cifrado César pero no va. Probando varios cifrados por sustitución al final damos con el correcto. De nuevo un ataque por fuerza bruta nos da frutos.
Solución: (3,4,5)/1 – LACLAVEDELASEGUNDAPRUEBAESMEKONG
Fuente: https://www.dcode.fr/chiffre-decalages
Cripto 3
Este nivel también va a ser sencillo. Estos caracteres, pertenecientes a un sistema bastante conocido de encriptado, esconden una palabra que, al introducirla (en minúsculas), nos permitirá superar el nivel.
Investigando un poco llegamos a la conclusión de que se trata del cifrado Francmasón o Pig Pen.
Solución: primates
Fuente: https://www.dcode.fr/chiffre-pig-pen-francs-macons
Cripto 4
Esta prueba es tan simple que la he dividido en dos partes que, aunque de apariencia similar, se resuelven de distinta manera. La clave es la unión de las dos palabras resultantes de descifrar las dos líneas de números y que, juntas, forman una tercera palabra.
0111001101110101011100000110010101110010
0001001110011000111110100100110010010001
La primera parte se puede convertir en bloque:
0111001101110101011100000110010101110010 = super
Fuente: https://www.rapidtables.com/convert/number/binary-to-ascii.html
Para la segunda debemos separar en grupos de 5 dígitos y listo:
00010 01110 01100 01111 10100 10011 00100 10001
C O M P U T E R
Fuente: www.lindau-nobel.org
Cripto 5
Para descubrir la palabra clave sólo se necesita una mínima capacidad de observación.
31 04 40 23 20 34 33 13 23 22
Se trata del cuadrado de Polibio.

Cripto 6
Aquí hay que hacer un poco de trabajo de investigación: Hay que descubrir la clave que empleó un escritor francés (Una pista: «Lagardère») en una de sus novelas, que es la empleada aquí para formar la palabra clave (en minúsculas) que, por cierto, es alemana.
RI3I2MIL2I2A3
POR RESOLVER
Cripto 7
Seguimos con cosas fáciles. Se trata de descifrar este texto escrito en inglés.
kgw qkoev ol 617 qthpreoz iwjpz sdkg kgw pdeyeplk rwqdjzwe ipezwq spbbdq sgo sgwz goqkdbdkdwq iwjpz spq rwkwecdzwr ko cpmw gdq uweqozpb yozkedihkdoz ko kgw spe wlloek
Una vez descifrado, nos será fácil descubrir la clave:
pzpyozrp
Se trata de un cifrado de sustitución mono alfabético.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ZLMIRVHUBGTFJKOASDWQPYEXCN
THE STORY OF 617 SQUADRON BEGAN WITH THE AIRCRAFT DESIGNER BARNES WALLIS WHO WHEN HOSTILITIES BEGAN WAS DETERMINED TO MAJE HIS PERSONAL CONTRIBUTION TO THE WAR EFFORT
Una vez descifrado el alfabeto la solución queda:
pzpyozrp = anaconda
Cripto 8
A veces, las cosas no son lo que parecen. Donde aparecen unos números, en realidad hay otros números distintos.
273664524572348321143738
853442616537643005319627
POR RESOLVER
Cripto 9
Para resolver algunos problemas, hay que tener una buena base. Este es un buen ejemplo de ello:
ZW50ZXJwcmlzZQ0K
¿Os suena base 64?
Solución: enterprise
Fuente: https://www.base64decode.org/
Cripto 10
Esto es más complicado. Para descifrar este texto que contiene la clave para superar el nivel, se necesita otra clave. Para que no sea demasiado difícil, he utilizado una palabra muy sencilla de sólo cuatro letras 🙂
myiemyuvbaeewcxweghkflxw
Mediante fuerza bruta matamos dos pájaros de un tiro.
lapalabraclaveesdiogenes
Fuente: https://www.guballa.de/vigenere-solver
Enlaces
Cruehead’s Crackme 3.0 Keygen [3/3]

Introducción
Esta es la tercera y última entrega de los crackmes de Cruehead. En esta ocasión nos enfrentamos a un «keyfile«, un archivo llave para que nos entendamos. Tiene un poco más de dificultad que los anteriores pero es ideal para los que empiezan.
El algoritmo
Si iniciamos el crackme no pasa nada, lo único que vemos es la palabra «UNCRACKED» en el título. Abrimos el crackme con Olly y empezamos. En las «string references» vemos el nombre del archivo llave «crackme3.key«. Lo creamos y escribimos el serial 12345678 y empezamos a tracear.
El CMP EAX,-1 significa que está comprobando que el archivo no esté vacio, como no es nuestro caso continuamos.
A continuación vemos que compara nuestra longitud de serial con 0x12 (18 en decimal). Nuestro serial tiene 8 dígitos así que nos tira fuera.
Escribimos en el archivo llave el serial «deurus123456789012» y volvemos a tracear. Vemos que ahora si pasa los filtros iniciales y llegamos a la primera zona interesante. En la imágen está explicado pero os hago un resumen. En el bucle lo que hace es un XOR a los primeros 14 dígitos de nuestro serial con los valores del 41 al 4E (4F finaliza). El bucle solo se rompe si llegamos a 4F o si el resultado del XOR da 0. Además en EAX acumula la suma del resultado del XOR.
Ejemplo:
d e u r u s 1 2 3 4 5 6 7 8 9 0 1 2
64 65 75 72 75 73 31 32 33 34 35 36 37 38
XOR
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E
-----------------------------------------
25 27 36 36 30 35 76 7A 7A 7E 7E 7A 7A 76 = 4ED (Suma)
A continuación hace XOR entre 12345678 y 4ED, coge los 4 últimos dígitos de nuestro serial y los compara.
Ejemplo:
12345678 XOR 4ED = 12345295 Compara 12345295 con 32313039 32313039 = 2109, nuestros 4 últimos dígitos al revés. Recordemos que nuestro serial era "deurus123456789012"
El serial bueno para el nombre deurus12345678 serían los bytes correspondientes de «12345295», es decir, nuestro serial bueno sería:
Ejemplo:
Necesitamos 12345295 para la comparación. 12 34 52 95 hexadecimal 18 52 82 149 decimal Tenemos que escribirlo al revés. Con Alt-Izq + 149 escribimos el primer caracter, el resto igual. Nuestro serial quedaría: deurus12345678òR4↕
Metemos el serial y vemos que lo acepta pero que nos muestra un nombre extraño. Esto es por que nos está mostrando los bytes del nombre xoreados, tendremos que hacer un XOR antes al nombre que queramos para que lo muestre correctamente.
Recapitulando
Con lo que sabemos ahora hay que empezar a coger el toro por los cuernos. Lo primero que queremos que muestre el nombre deurus y no deurus12345678. Para ello debemos cortar el bucle y eso solo lo podemos hacer forzando que el resultado del XOR sea 0. Ok pues para deurus el siguiente valor de BL, es decir el séptimo, en el bucle sería 47 lo que corresponde a la letra G. Pues si ponemos de serial deurusGxxxxxxxxxxx ya tendríamos la primera parte solucionada.
Pero recordemos que necesitamos XORear el nombre inicialmente, luego debemos escribir el resultado del XOR.
Ejemplo:
d e u r u s
64 65 75 72 75 73
XOR
41 42 43 44 45 46
-----------------
25 27 36 36 30 35
25 27 36 36 30 35 ----- debemos meter esto en el archivo llave.
XOR
41 42 43 44 45 46
-----------------
64 65 75 72 75 73 ----- Al desencriptarlo el bucle se verá nuestro nombre correctamente.
En el archivo llave escribiriamos: %'6605
Ahora nos faltaría calcular el nuevo SUM. Como el resultado del XOR ahora es nuestro nombre, basta con sumar sus valores ascii (64+65+75+72+75+73 == 0x298)
0x12345678 XOR 0x298 == 0x123454E0
Luego nuestros 4 últimos dígitos deben ser lo correspondiente a los bytes E0, 54, 34, 12. Los pasamos a decimal y los escribimos en el archivo llave con el truco del ALT-Izq que hemos comentado antes.
El contenido final del archivo llave para el nombre deurus sería:
%’6605GxxxxxxxÓT4↕
Aquí vemos el archivo llave normal.
Y aquí lo vemos con un editor hexadecimal. Como veis se ven claramente los bytes E0, 54, 34, 12.
Os dejo un keygen hecho en .Net para que probéis. Os genera el contenido del archivo y el archivo «crackme3.key».
Links
Solución al CrackMe DAE 430

- Introducción
- Herramientas utilizadas
- Desempacado con Ollydbg 2 (Videotutorial)
- Desempacado con Ollydbg 1 (Videotutorial)
- Análisis de la rutina del número de serie
- Links
Introducción
Este Crackme está basado en la protección de DVD Audio Extractor 4.3. Afrontaremos dos partes, una primera donde desempacaremos PECompact 2.x y otra donde analizaremos la rutina de comprobación del número de serie. Os adelante que la única dificultad reside en desempacar ya que la rutina del serial es bastante floja.
El motivo que me ha llevado a realizar un apartado para Ollydbg 1 y otro para Ollydbg 2 es principalmente por que con Ollydbg 2 lo haremos desde Windows 7 x64 y con Ollydbg 1 desde Windos 7 x32.
Herramientas utilizadas
- Ollydbg2 con los plugins OllyDumEX y CmdBar.
- Ollydbg1 con plugin OllyDump.
- Import Reconstructor 1.6.
Desempacado con Ollydbg 2
Videotutorial disponible: http://youtu.be/-63yEUTqP-c.
Resumen de pasos:
- Cargar Crackme en Ollydbg.
- Pulsar F9.
- Poner breakpoint «bp VirtualFree»
- Pulsamos F9 dos veces.
- Pulsamos Ctrl+F9.
- Pulsamos F8 hasta salir del RETN.
- Ponemos breakpoint a JMP EAX.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el Crackme en Olly y aparecemos aquí.
2. Pulsamos una vez F9 y veremos esto:
3. Ponemos un breakpoint de la siguiente manera «bp VirtualFree» con la ayuda del plugin CmdBar.
4. Pulsamos F9 dos veces y aparecemos aquí.
5. A continuación pulsamos Ctrl+F9 y veremos esto.
6. Pulsamos F8 hasta salir del RETN anterior y veremos esto.
7. Al final vemos lo que estábamos buscando. El JMP EAX es el salto que nos lleva al punto de entrada original (OEP). Ponemos un breakpoint en JMP EAX y pulsamos F9, cuando se detenga Ollydbg, pulsamos F8 y aparecemos aquí.
8. Ya tenemos a PECompact contra las cuerdas, ahora mismo tenemos el Crackme desempacado en memoria.
Hacemos click en Plugins > OllyDumpEx > Dump process y veremos esto.
Pulsamos en Dump y esto nos generará un archivo que se llama DAE430_CrackMe_dump.
9. A continuación con Import Reconstructor seleccionamos el crackme y pulsamos IAT AutoSearch y Get Imports.
Veremos unas importaciones NO válidas, pulsamos en Show Invalid y las clickamos con el botón derecho > Delete thunks.
Finalmente pulsamos Fix Dump y elegimos el crackme dumpeado anteriormente. Con esto ya hemos finalizado el desempacado.
Desempacado con Ollydbg 1
Videotutorial disponible: http://youtu.be/mm42HRlPXOE
Resumen de pasos:
- Cargamos el crackme en Ollydbg.
- Pulsamos F8 hasta el segundo Call y en éste entramos con F7.
- Seguimos con F8.
- Buscamos JMP EAX, le ponemos un breakpoint y ejecutamos hast que pare en el.
- Situados en JMP EAX, pulsamos F8 y llegamos al OEP.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el crackme en Ollydbg y vemos esto.
2. Pulsamos F8 hasta que veamos dos Calls. Pulsamos F8 hasta el segundo Call y cuando estemos situados encima de él pulsamos F7 para entrar en el.
Dentro del segundo call veremos esto.
3. Seguimos con F8 y llegamos aquí.
4. Sin tracear, nos desplazamos por el código hasta encontrar un poco más abajo JMP EAX. Le ponemos un breakpoint y pulsamos F9.
5. Cuando estemos situados en JMP EAX pulsamos F8 y llegamos al punto de entrada original (OEP).
6. Ahora con el plugin OllyDump vamos a dumpear el ejecutable que tenemos desempacado en memoria.
Dumpeamos.
7. Finalmente con Import reconstructor arreglamos las importaciones.
Análisis de la rutina del número de serie
Cargamos en Ollydbg el crackme desempacado y en las referencias de texto encontramos el mensaje «Gracias por registrarte». Pulsamos en él y llegamos a la rutina de comprobación del serial que desgranamos a continuación.
00401B89 . 83F9 03 CMP ECX,3 ; Len(nombre) >=3 00401B8C . 0F8E 46010000 JLE DAE430_C.00401CD8 00401B92 . B2 44 MOV DL,44 ; Dl=44(Letra D) 00401B94 . 31C0 XOR EAX,EAX 00401B96 . 31FF XOR EDI,EDI 00401B98 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 1er digito con la letra D 00401B9B . 74 05 JE SHORT DAE430_C.00401BA2 00401B9D > BF 01000000 MOV EDI,1 00401BA2 > 40 INC EAX 00401BA3 . 83F8 04 CMP EAX,4 00401BA6 . 74 0C JE SHORT DAE430_C.00401BB4 00401BA8 . 8A5404 45 MOV DL,BYTE PTR SS:[ESP+EAX+45] ; Memoria 22FAF5 a 22FAF | Lee los digitos A1X 00401BAC . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Los compara 00401BAF .^ 75 EC JNZ SHORT DAE430_C.00401B9D 00401BB1 .^ EB EF JMP SHORT DAE430_C.00401BA2 00401BB3 90 NOP 00401BB4 > 66:0FBE4424 53 MOVSX AX,BYTE PTR SS:[ESP+53] ; EAX = 5ºdígito 00401BBA . 8D1480 LEA EDX,DWORD PTR DS:[EAX+EAX*4] ; EAX*4+EAX = A 00401BBD . 8D04D0 LEA EAX,DWORD PTR DS:[EAX+EDX*8] ; A*8 + 5ºdigito=B 00401BC0 . 66:C1E8 08 SHR AX,8 ; B/100=C 00401BC4 . C0F8 02 SAR AL,2 ; C/4=D 00401BC7 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BCB . C0FA 07 SAR DL,7 ; 5ºdígito/80=E 00401BCE . 29D0 SUB EAX,EDX ; E-D=F 00401BD0 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; F*4*F=G 00401BD3 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; G*4+G=H 00401BD6 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BDA . 29C2 SUB EDX,EAX ; 5ºdigito - H = I 00401BDC . 83C2 41 ADD EDX,41 ; I+41 = J 00401BDF . 885424 4A MOV BYTE PTR SS:[ESP+4A],DL ; GUARDA J EN LA MEMORIA 22FAFA 00401BE3 . 66:0FBE4424 54 MOVSX AX,BYTE PTR SS:[ESP+54] 00401BE9 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401BEC . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401BEF . 66:C1E8 08 SHR AX,8 00401BF3 . C0F8 02 SAR AL,2 00401BF6 . 8A4C24 54 MOV CL,BYTE PTR SS:[ESP+54] 00401BFA . C0F9 07 SAR CL,7 00401BFD . 29C8 SUB EAX,ECX 00401BFF . 89C6 MOV ESI,EAX 00401C01 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C04 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C07 . 8A4424 54 MOV AL,BYTE PTR SS:[ESP+54] 00401C0B . 89F1 MOV ECX,ESI 00401C0D . 29C8 SUB EAX,ECX 00401C0F . 89C6 MOV ESI,EAX 00401C11 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C14 . 884424 4B MOV BYTE PTR SS:[ESP+4B],AL ; GUARDA J2 EN LA MEMORIA 22FAFB para el 6ºdígito 00401C18 . 66:0FBE4424 55 MOVSX AX,BYTE PTR SS:[ESP+55] 00401C1E . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C21 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C24 . 66:C1E8 08 SHR AX,8 00401C28 . C0F8 02 SAR AL,2 00401C2B . 8A4C24 55 MOV CL,BYTE PTR SS:[ESP+55] 00401C2F . C0F9 07 SAR CL,7 00401C32 . 29C8 SUB EAX,ECX 00401C34 . 89C6 MOV ESI,EAX 00401C36 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C39 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C3C . 8A4424 55 MOV AL,BYTE PTR SS:[ESP+55] 00401C40 . 89F1 MOV ECX,ESI 00401C42 . 29C8 SUB EAX,ECX 00401C44 . 89C6 MOV ESI,EAX 00401C46 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C49 . 884424 4C MOV BYTE PTR SS:[ESP+4C],AL ; GUARDA J3 EN LA MEMORIA 22FAFC para el 7ºdígito 00401C4D . 66:0FBE4424 56 MOVSX AX,BYTE PTR SS:[ESP+56] 00401C53 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C56 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C59 . 66:C1E8 08 SHR AX,8 00401C5D . C0F8 02 SAR AL,2 00401C60 . 8A4C24 56 MOV CL,BYTE PTR SS:[ESP+56] 00401C64 . C0F9 07 SAR CL,7 00401C67 . 29C8 SUB EAX,ECX 00401C69 . 89C6 MOV ESI,EAX 00401C6B . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C6E . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C71 . 8A4424 56 MOV AL,BYTE PTR SS:[ESP+56] 00401C75 . 89F1 MOV ECX,ESI 00401C77 . 29C8 SUB EAX,ECX 00401C79 . 89C6 MOV ESI,EAX 00401C7B . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C7E . 884424 4D MOV BYTE PTR SS:[ESP+4D],AL ; GUARDA J4 EN LA MEMORIA 22FAFD para el 8ºdígito 00401C82 . B8 08000000 MOV EAX,8 00401C87 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL 00401C8A . 74 05 JE SHORT DAE430_C.00401C91 00401C8C > BF 01000000 MOV EDI,1 00401C91 > 40 INC EAX 00401C92 . 83F8 0C CMP EAX,0C 00401C95 . 74 0D JE SHORT DAE430_C.00401CA4 00401C97 . 8A5404 42 MOV DL,BYTE PTR SS:[ESP+EAX+42] 00401C9B . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 22FAFA y siguientes con 9, 10, 11 y 12avo digito 00401C9E .^ 75 EC JNZ SHORT DAE430_C.00401C8C 00401CA0 .^ EB EF JMP SHORT DAE430_C.00401C91 00401CA2 . 66:90 NOP 00401CA4 > 89F8 MOV EAX,EDI ; | 00401CA6 . FEC8 DEC AL ; | 00401CA8 . 74 5C JE SHORT DAE430_C.00401D06 ; | 00401CAA . C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CB2 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CBA . C74424 04 51004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041005>; |ASCII "Gracias por registrarte." 00401CC2 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CC9 . E8 EE000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CCE . 83EC 10 SUB ESP,10 00401CD1 . 31C0 XOR EAX,EAX 00401CD3 .^ E9 F2FBFFFF JMP DAE430_C.004018CA 00401CD8 > C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CE0 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CE8 . C74424 04 6A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041006>; |ASCII "Nombre mínimo 4 caracteres." 00401CF0 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CF7 . E8 C0000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CFC . 83EC 10 SUB ESP,10 00401CFF . 31C0 XOR EAX,EAX 00401D01 .^ E9 C4FBFFFF JMP DAE430_C.004018CA 00401D06 > C74424 0C 10000000 MOV DWORD PTR SS:[ESP+C],10 ; | 00401D0E . C74424 08 34004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041003>; |ASCII "Error" 00401D16 . C74424 04 3A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041003>; |ASCII "Registro fallido." 00401D1E . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401D25 . E8 92000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
Resumen
- El nombre debe tener más de 3 dígitos aunque no lo usa para el número de serie. - El serial tiene 12 dígitos dividiendose en tres partes, 111122223333. - La primera parte 1111 es comparada directamente con DA1X. - Segunda parte (2222), para los dígitos 5º, 6º, 7º y 8º hace lo siguiente: dígito *4 + dígito = A A*8 + dígito=B B/100 = C C/4 = D dígito/80 = E E-D = F F*4*F = G G*4+G = H digito - H = I I+41 = J GUARDA J EN LA MEMORIA 22FAFA **Todo esto se puede resumir en dígito mod 19 + 41 - Tercera parte (3333). Finalmente compara el resultado del 5º, 6º, 7º y 8º dígitos con el 9º, 10º, 11º y 12º dígitos.
Ejemplo:
Serial = DA1X12345678 1 - (31h mod 19h) + 41h = 48h(Y) 2 - (32h mod 19h) + 41h = 41h(A) 3 - (33h mod 19h) + 41h = 42h(B) 4 - (34h mod 19h) + 41h = 43h(C) Compara Y con 5 Compara A con 6 Compara B con 7 Compara C con 8 Luego el serial correcto sería DA1X1234YABC
Links
VideoTutorial – RegisterMe de Shadow – Parcheando un NET

Solución al CrackMe DAE 430

- Introducción
- Herramientas utilizadas
- Desempacado con Ollydbg 2 (Videotutorial)
- Desempacado con Ollydbg 1 (Videotutorial)
- Análisis de la rutina del número de serie
- Links
Introducción
Este Crackme está basado en la protección de DVD Audio Extractor 4.3. Afrontaremos dos partes, una primera donde desempacaremos PECompact 2.x y otra donde analizaremos la rutina de comprobación del número de serie. Os adelante que la única dificultad reside en desempacar ya que la rutina del serial es bastante floja.
El motivo que me ha llevado a realizar un apartado para Ollydbg 1 y otro para Ollydbg 2 es principalmente por que con Ollydbg 2 lo haremos desde Windows 7 x64 y con Ollydbg 1 desde Windos 7 x32.
Herramientas utilizadas
- Ollydbg2 con los plugins OllyDumEX y CmdBar.
- Ollydbg1 con plugin OllyDump.
- Import Reconstructor 1.6.
Desempacado con Ollydbg 2
Videotutorial disponible: http://youtu.be/-63yEUTqP-c.
Resumen de pasos:
- Cargar Crackme en Ollydbg.
- Pulsar F9.
- Poner breakpoint «bp VirtualFree»
- Pulsamos F9 dos veces.
- Pulsamos Ctrl+F9.
- Pulsamos F8 hasta salir del RETN.
- Ponemos breakpoint a JMP EAX.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el Crackme en Olly y aparecemos aquí.
2. Pulsamos una vez F9 y veremos esto:
3. Ponemos un breakpoint de la siguiente manera «bp VirtualFree» con la ayuda del plugin CmdBar.
4. Pulsamos F9 dos veces y aparecemos aquí.
5. A continuación pulsamos Ctrl+F9 y veremos esto.
6. Pulsamos F8 hasta salir del RETN anterior y veremos esto.
7. Al final vemos lo que estábamos buscando. El JMP EAX es el salto que nos lleva al punto de entrada original (OEP). Ponemos un breakpoint en JMP EAX y pulsamos F9, cuando se detenga Ollydbg, pulsamos F8 y aparecemos aquí.
8. Ya tenemos a PECompact contra las cuerdas, ahora mismo tenemos el Crackme desempacado en memoria.
Hacemos click en Plugins > OllyDumpEx > Dump process y veremos esto.
Pulsamos en Dump y esto nos generará un archivo que se llama DAE430_CrackMe_dump.
9. A continuación con Import Reconstructor seleccionamos el crackme y pulsamos IAT AutoSearch y Get Imports.
Veremos unas importaciones NO válidas, pulsamos en Show Invalid y las clickamos con el botón derecho > Delete thunks.
Finalmente pulsamos Fix Dump y elegimos el crackme dumpeado anteriormente. Con esto ya hemos finalizado el desempacado.
Desempacado con Ollydbg 1
Videotutorial disponible: http://youtu.be/mm42HRlPXOE
Resumen de pasos:
- Cargamos el crackme en Ollydbg.
- Pulsamos F8 hasta el segundo Call y en éste entramos con F7.
- Seguimos con F8.
- Buscamos JMP EAX, le ponemos un breakpoint y ejecutamos hast que pare en el.
- Situados en JMP EAX, pulsamos F8 y llegamos al OEP.
- Dumpeamos.
- Reconstruimos las importaciones.
1. Cargamos el crackme en Ollydbg y vemos esto.
2. Pulsamos F8 hasta que veamos dos Calls. Pulsamos F8 hasta el segundo Call y cuando estemos situados encima de él pulsamos F7 para entrar en el.
Dentro del segundo call veremos esto.
3. Seguimos con F8 y llegamos aquí.
4. Sin tracear, nos desplazamos por el código hasta encontrar un poco más abajo JMP EAX. Le ponemos un breakpoint y pulsamos F9.
5. Cuando estemos situados en JMP EAX pulsamos F8 y llegamos al punto de entrada original (OEP).
6. Ahora con el plugin OllyDump vamos a dumpear el ejecutable que tenemos desempacado en memoria.
Dumpeamos.
7. Finalmente con Import reconstructor arreglamos las importaciones.
Análisis de la rutina del número de serie
Cargamos en Ollydbg el crackme desempacado y en las referencias de texto encontramos el mensaje «Gracias por registrarte». Pulsamos en él y llegamos a la rutina de comprobación del serial que desgranamos a continuación.
00401B89 . 83F9 03 CMP ECX,3 ; Len(nombre) >=3 00401B8C . 0F8E 46010000 JLE DAE430_C.00401CD8 00401B92 . B2 44 MOV DL,44 ; Dl=44(Letra D) 00401B94 . 31C0 XOR EAX,EAX 00401B96 . 31FF XOR EDI,EDI 00401B98 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 1er digito con la letra D 00401B9B . 74 05 JE SHORT DAE430_C.00401BA2 00401B9D > BF 01000000 MOV EDI,1 00401BA2 > 40 INC EAX 00401BA3 . 83F8 04 CMP EAX,4 00401BA6 . 74 0C JE SHORT DAE430_C.00401BB4 00401BA8 . 8A5404 45 MOV DL,BYTE PTR SS:[ESP+EAX+45] ; Memoria 22FAF5 a 22FAF | Lee los digitos A1X 00401BAC . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Los compara 00401BAF .^ 75 EC JNZ SHORT DAE430_C.00401B9D 00401BB1 .^ EB EF JMP SHORT DAE430_C.00401BA2 00401BB3 90 NOP 00401BB4 > 66:0FBE4424 53 MOVSX AX,BYTE PTR SS:[ESP+53] ; EAX = 5ºdígito 00401BBA . 8D1480 LEA EDX,DWORD PTR DS:[EAX+EAX*4] ; EAX*4+EAX = A 00401BBD . 8D04D0 LEA EAX,DWORD PTR DS:[EAX+EDX*8] ; A*8 + 5ºdigito=B 00401BC0 . 66:C1E8 08 SHR AX,8 ; B/100=C 00401BC4 . C0F8 02 SAR AL,2 ; C/4=D 00401BC7 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BCB . C0FA 07 SAR DL,7 ; 5ºdígito/80=E 00401BCE . 29D0 SUB EAX,EDX ; E-D=F 00401BD0 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; F*4*F=G 00401BD3 . 8D0480 LEA EAX,DWORD PTR DS:[EAX+EAX*4] ; G*4+G=H 00401BD6 . 8A5424 53 MOV DL,BYTE PTR SS:[ESP+53] ; DL = 5ºdígito 00401BDA . 29C2 SUB EDX,EAX ; 5ºdigito - H = I 00401BDC . 83C2 41 ADD EDX,41 ; I+41 = J 00401BDF . 885424 4A MOV BYTE PTR SS:[ESP+4A],DL ; GUARDA J EN LA MEMORIA 22FAFA 00401BE3 . 66:0FBE4424 54 MOVSX AX,BYTE PTR SS:[ESP+54] 00401BE9 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401BEC . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401BEF . 66:C1E8 08 SHR AX,8 00401BF3 . C0F8 02 SAR AL,2 00401BF6 . 8A4C24 54 MOV CL,BYTE PTR SS:[ESP+54] 00401BFA . C0F9 07 SAR CL,7 00401BFD . 29C8 SUB EAX,ECX 00401BFF . 89C6 MOV ESI,EAX 00401C01 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C04 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C07 . 8A4424 54 MOV AL,BYTE PTR SS:[ESP+54] 00401C0B . 89F1 MOV ECX,ESI 00401C0D . 29C8 SUB EAX,ECX 00401C0F . 89C6 MOV ESI,EAX 00401C11 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C14 . 884424 4B MOV BYTE PTR SS:[ESP+4B],AL ; GUARDA J2 EN LA MEMORIA 22FAFB para el 6ºdígito 00401C18 . 66:0FBE4424 55 MOVSX AX,BYTE PTR SS:[ESP+55] 00401C1E . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C21 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C24 . 66:C1E8 08 SHR AX,8 00401C28 . C0F8 02 SAR AL,2 00401C2B . 8A4C24 55 MOV CL,BYTE PTR SS:[ESP+55] 00401C2F . C0F9 07 SAR CL,7 00401C32 . 29C8 SUB EAX,ECX 00401C34 . 89C6 MOV ESI,EAX 00401C36 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C39 . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C3C . 8A4424 55 MOV AL,BYTE PTR SS:[ESP+55] 00401C40 . 89F1 MOV ECX,ESI 00401C42 . 29C8 SUB EAX,ECX 00401C44 . 89C6 MOV ESI,EAX 00401C46 . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C49 . 884424 4C MOV BYTE PTR SS:[ESP+4C],AL ; GUARDA J3 EN LA MEMORIA 22FAFC para el 7ºdígito 00401C4D . 66:0FBE4424 56 MOVSX AX,BYTE PTR SS:[ESP+56] 00401C53 . 8D3480 LEA ESI,DWORD PTR DS:[EAX+EAX*4] 00401C56 . 8D04F0 LEA EAX,DWORD PTR DS:[EAX+ESI*8] 00401C59 . 66:C1E8 08 SHR AX,8 00401C5D . C0F8 02 SAR AL,2 00401C60 . 8A4C24 56 MOV CL,BYTE PTR SS:[ESP+56] 00401C64 . C0F9 07 SAR CL,7 00401C67 . 29C8 SUB EAX,ECX 00401C69 . 89C6 MOV ESI,EAX 00401C6B . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C6E . 8D34B6 LEA ESI,DWORD PTR DS:[ESI+ESI*4] 00401C71 . 8A4424 56 MOV AL,BYTE PTR SS:[ESP+56] 00401C75 . 89F1 MOV ECX,ESI 00401C77 . 29C8 SUB EAX,ECX 00401C79 . 89C6 MOV ESI,EAX 00401C7B . 8D46 41 LEA EAX,DWORD PTR DS:[ESI+41] 00401C7E . 884424 4D MOV BYTE PTR SS:[ESP+4D],AL ; GUARDA J4 EN LA MEMORIA 22FAFD para el 8ºdígito 00401C82 . B8 08000000 MOV EAX,8 00401C87 . 381403 CMP BYTE PTR DS:[EBX+EAX],DL 00401C8A . 74 05 JE SHORT DAE430_C.00401C91 00401C8C > BF 01000000 MOV EDI,1 00401C91 > 40 INC EAX 00401C92 . 83F8 0C CMP EAX,0C 00401C95 . 74 0D JE SHORT DAE430_C.00401CA4 00401C97 . 8A5404 42 MOV DL,BYTE PTR SS:[ESP+EAX+42] 00401C9B . 381403 CMP BYTE PTR DS:[EBX+EAX],DL ; Compara 22FAFA y siguientes con 9, 10, 11 y 12avo digito 00401C9E .^ 75 EC JNZ SHORT DAE430_C.00401C8C 00401CA0 .^ EB EF JMP SHORT DAE430_C.00401C91 00401CA2 . 66:90 NOP 00401CA4 > 89F8 MOV EAX,EDI ; | 00401CA6 . FEC8 DEC AL ; | 00401CA8 . 74 5C JE SHORT DAE430_C.00401D06 ; | 00401CAA . C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CB2 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CBA . C74424 04 51004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041005>; |ASCII "Gracias por registrarte." 00401CC2 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CC9 . E8 EE000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CCE . 83EC 10 SUB ESP,10 00401CD1 . 31C0 XOR EAX,EAX 00401CD3 .^ E9 F2FBFFFF JMP DAE430_C.004018CA 00401CD8 > C74424 0C 40000000 MOV DWORD PTR SS:[ESP+C],40 ; | 00401CE0 . C74424 08 4C004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041004>; |ASCII "Info" 00401CE8 . C74424 04 6A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041006>; |ASCII "Nombre mínimo 4 caracteres." 00401CF0 . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401CF7 . E8 C0000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA 00401CFC . 83EC 10 SUB ESP,10 00401CFF . 31C0 XOR EAX,EAX 00401D01 .^ E9 C4FBFFFF JMP DAE430_C.004018CA 00401D06 > C74424 0C 10000000 MOV DWORD PTR SS:[ESP+C],10 ; | 00401D0E . C74424 08 34004100 MOV DWORD PTR SS:[ESP+8],DAE430_C.0041003>; |ASCII "Error" 00401D16 . C74424 04 3A004100 MOV DWORD PTR SS:[ESP+4],DAE430_C.0041003>; |ASCII "Registro fallido." 00401D1E . C70424 00000000 MOV DWORD PTR SS:[ESP],0 ; | 00401D25 . E8 92000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
Resumen
- El nombre debe tener más de 3 dígitos aunque no lo usa para el número de serie. - El serial tiene 12 dígitos dividiendose en tres partes, 111122223333. - La primera parte 1111 es comparada directamente con DA1X. - Segunda parte (2222), para los dígitos 5º, 6º, 7º y 8º hace lo siguiente: dígito *4 + dígito = A A*8 + dígito=B B/100 = C C/4 = D dígito/80 = E E-D = F F*4*F = G G*4+G = H digito - H = I I+41 = J GUARDA J EN LA MEMORIA 22FAFA **Todo esto se puede resumir en dígito mod 19 + 41 - Tercera parte (3333). Finalmente compara el resultado del 5º, 6º, 7º y 8º dígitos con el 9º, 10º, 11º y 12º dígitos.
Ejemplo:
Serial = DA1X12345678 1 - (31h mod 19h) + 41h = 48h(Y) 2 - (32h mod 19h) + 41h = 41h(A) 3 - (33h mod 19h) + 41h = 42h(B) 4 - (34h mod 19h) + 41h = 43h(C) Compara Y con 5 Compara A con 6 Compara B con 7 Compara C con 8 Luego el serial correcto sería DA1X1234YABC
Links
Blooper Tech Movie VI – Dexter 1×08 (S01E08)

Hace poco me puse a leer El oscuro pasajero de Jeff Lindsay, novela que inspiró la serie Dexter. La nostalgia me invadió y al final decidí volver a ver la primera temporada que tanto me gustó hace unos años. Para mi sorpresa, muchos de los detalles que recordaba de la serie eran incorrectos o incompletos. Bueno, el caso es que en esta ocasión me he fijado más en los detalles y he descubierto una pequeña perla en el capítulo 8 de la primera temporada.
ALERTA DE SPOILER: Aunque la serie tiene unos añitos no quisiera fastidiarsela a nadie. Si continuas leyendo puede que te enteres de algo que no quieras.
Missed connection
En un momento dado, a Dexter se le ocurre la feliz idea de contactar con el asesino en serie que le está dejando regalitos y no se le ocurre mejor idea que hacerlo en una web de contactos cualquiera. La web en cuestión es www.miamilist12.com/miami/main y Dexter decide escribir un mensaje en el hilo missed connections. A continuación la secuencia de imágenes.
mailto:frozenbarbie@hotmail.???
La simple idea de escribir en un tablón, foro, lista, etc y esperar que el asesino en serie lo lea ya es una locura. Pero señor@s, esto es ficción, y por supuesto el asesino no solo ve el mensaje si no que responde a Dexter creando un pequeño error con las direcciones de email. Y es que cuando el asesino ve el mensaje se puede apreciar que la dirección de email de Dexter es frozenbarbie@hotmail.web y cuando el asesino le responde, se ve claramente que lo hace a la dirección frozenbarbie@hotmail.com. A continuación las imágenes.
Además me ha llamado la atención que aunque es evidente que el asesino usa Windows XP, se puede apreciar que han retocado en post-producción el botón de inicio para que quede oculto.
Nos vemos en el siguiente BTM.
Solución a los CrackMes de CrkViZ 1-5

- Introducción
- Herramientas disponibles
- CrkViz-1 (Serial a la vista)
- CrkViz-2 (Parcheando rutina aleatoria)
- CrkViz-3 (Nag+Keygen)
- CrkViz-4 (Límite de ejecuciones+Keygen)
- CrkViz-5 (Serial a la vista)
- Notas finales
- Enlaces
Introducción
Esta vez vamos a analizar los CrackMes de un antiguo colaborador de Karpoff Spanish Tutor, CrkViZ. En estas cinco soluciones vamos a pelearnos con Visual Basic 5/6 nativo y Pcode, con el registro de Windows y tendremos que parchear algúna rutina antidebug. Los CrackMes son del año 2000 y aunque algunos estaban ya solucionados, los analizaremos igualmente para ver la diferencia que existe con los análisis realizados en aquellos años, sí, estamos hablando del Softice.
Herramientas disponibles
Cuando hablamos de Visual Basic 5/6, podemos destacar 3 herramientas que nos facilitan mucho la vida, VB Decompiler, VB Reformer y ExDec. Las dos primeras se defienden bien tanto con código nativo como pcode y ExDec solamente nos sirve para pcode. Aún así, si todo lo demás falla, Ollydbg nos sacará de apuros.
CrkViz-1
Este primer crackme está compilado en Pcode y hoy día, con las herramientas de que disponemos no supone ninguna dificultad. Tan solo debemos abrirlo con VB Decompiler y ya nos encontramos con el serial válido.
Los opcodes obtenidos con ExDec se ven de la siguiente manera.
...... 402F14: 04 FLdRfVar local_008C 402F17: 21 FLdPrThis 402F18: 0f VCallAd 7b3fc340 402F1B: 19 FStAdFunc local_0088 402F1E: 08 FLdPr local_0088 402F21: 0d VCallHresult 7b3fbe88 402F26: 6c ILdRf local_008C 402F29: 1b LitStr: 57230198 <-------------- 402F2C: Lead0/30 EqStr 402F2E: 2f FFree1Str local_008C 402F31: 1a FFree1Ad local_0088 402F34: 1c BranchF: 403012 402F37: 21 FLdPrThis 402F38: 0d VCallHresult 7b3fc2b0 402F3D: 3a LitVarStr: ( local_00AC ) Gracias por Registrar!! 402F42: Lead2/00 FStVarCopy 402F46: 27 LitVar_Missing 402F49: 27 LitVar_Missing 402F4C: 3a LitVarStr: ( local_00AC ) CrkViz 402F51: 4e FStVarCopyObj local_00BC 402F54: 04 FLdRfVar local_00BC 402F57: f5 LitI4: 0x40 64 (...@) 402F5C: 04 FLdRfVar local_009C 402F5F: 0a ImpAdCallFPR4: _rtcMsgBox 402F64: 36 FFreeVar 402F6D: 27 LitVar_Missing 402F70: 25 PopAdLdVar 402F71: 27 LitVar_Missing ......
CrkViz-2
Este segundo crackme también está compilado en pcode. La rutina del serial es muy sencilla pero al introducir un número aleatorio nos obliga a parchear. Cargamos el crackme en VB Decompiler y nos muestra esto:
Básicamente vemos que genera un número aleatorio entre 1 y 999999999 y luego le suma 1. La forma de afrontar esto es parcheando. Nos fijamos en el offset aproximado (4037F2) y abrimos el crackme en un editor hexadecimal. La forma de convertir el offset que nos muestra VB Decompiler a lo que nos muestra un editor hexadecimal es la siguiente.
VBdec_offset - Image Base - VirtualOffset + RawOffset = Offset_Editor.H 4037F2 - 400000 - 1000 + 400 = 2BF2
Una vez localizados los bytes, los cambiamos por ceros y guardamos.
Una vez parcheado, el serial correcto es 1.
CrkViz-3
En esta tercera entrega, CrkViz aumentó la dificultad. El crackme está compilado en código nativo y nos enfrentamos a un serial asociado a un nombre y a una rutina antidebug que en realidad es una Nag, ya que se muestra siempre.
Afrontar la nag es muy sencillo, basta con localizarla y parchear la llamada.
CPU Disasm Address Hex dump Command Comments 004058E2 8D4D DC LEA ECX,[EBP-24] 004058E5 C785 BCFDFFFF B MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.004033B8 ; UNICODE " Debugger detectado!!! " 004058EF C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8 004058F9 FFD7 CALL EDI 004058FB B9 04000280 MOV ECX,80020004 00405900 B8 0A000000 MOV EAX,0A 00405905 898D FCFDFFFF MOV DWORD PTR SS:[EBP-204],ECX 0040590B 898D 0CFEFFFF MOV DWORD PTR SS:[EBP-1F4],ECX 00405911 8D95 B4FDFFFF LEA EDX,[EBP-24C] 00405917 8D8D 14FEFFFF LEA ECX,[EBP-1EC] 0040591D 8985 F4FDFFFF MOV DWORD PTR SS:[EBP-20C],EAX 00405923 8985 04FEFFFF MOV DWORD PTR SS:[EBP-1FC],EAX 00405929 C785 BCFDFFFF 8 MOV DWORD PTR SS:[EBP-244],CrkMeViz-3.00403188 ; UNICODE "Error" 00405933 C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],8 0040593D FF15 C8914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDup>] 00405943 8D85 F4FDFFFF LEA EAX,[EBP-20C] 00405949 8D8D 04FEFFFF LEA ECX,[EBP-1FC] 0040594F 50 PUSH EAX 00405950 8D95 14FEFFFF LEA EDX,[EBP-1EC] 00405956 51 PUSH ECX 00405957 52 PUSH EDX 00405958 8D45 DC LEA EAX,[EBP-24] 0040595B 6A 10 PUSH 10 0040595D 50 PUSH EAX 0040595E FF15 50914000 CALL DWORD PTR DS:[<&MSVBVM50.#595>] ; rtcMsgBox - NOPear para evitar la NAG 00405964 8D8D F4FDFFFF LEA ECX,[EBP-20C]
Antes de llegar al keygen vemos que realiza unas llamadas al registro de Windows, ponemos un breakpoint «bp RegOpenKeyW» y ejecutamos.
CPU Disasm Address Hex dump Command Comments 00405677 |. 8B8D B8FDFFFF MOV ECX,DWORD PTR SS:[EBP-248] 0040567D |. B8 54334000 MOV EAX,CrkMeViz-3.00403354 ; UNICODE "<Unregister>" 00405682 |. 68 B4304000 PUSH CrkMeViz-3.004030B4 ; UNICODE "Serial number" 00405687 |. 894A 04 MOV DWORD PTR DS:[EDX+4],ECX 0040568A |. 8985 BCFDFFFF MOV DWORD PTR SS:[EBP-244],EAX 00405690 |. 68 84304000 PUSH CrkMeViz-3.00403084 ; UNICODE "Register" 00405695 |. 68 58304000 PUSH CrkMeViz-3.00403058 ; UNICODE "CrkMeViz3" 0040569A |. 8942 08 MOV DWORD PTR DS:[EDX+8],EAX 0040569D |. 8B85 C0FDFFFF MOV EAX,DWORD PTR SS:[EBP-240] 004056A3 |. 8942 0C MOV DWORD PTR DS:[EDX+0C],EAX 004056A6 |. FF15 C0914000 CALL DWORD PTR DS:[<&MSVBVM50.#689>] ; rtcGetSetting - Lee el numero de serie del registro ........ 0040574F |. 68 9C304000 PUSH CrkMeViz-3.0040309C ; UNICODE "User Name" 00405754 |. 68 84304000 PUSH CrkMeViz-3.00403084 ; UNICODE "Register" 00405759 |. 68 58304000 PUSH CrkMeViz-3.00403058 ; UNICODE "CrkMeViz3" 0040575E |. 8948 08 MOV DWORD PTR DS:[EAX+8],ECX 00405761 |. 8B8D C0FDFFFF MOV ECX,DWORD PTR SS:[EBP-240] 00405767 |. 8948 0C MOV DWORD PTR DS:[EAX+0C],ECX 0040576A |. FF15 C0914000 CALL DWORD PTR DS:[<&MSVBVM50.#689>] ; rtcGetSetting - Lee el Usuario del registro
Reconstruyendo la llamada al registro vemos que lee de esta ruta: HKEY_CURRENT_USER\Software\VB and VBA Program Settings\CrkMeViz3\Register el contenido de User Name y del Serial number.
Quizá uno de los fallos de éste crackme, es que no comprueba la autenticidad de estos parámetros y si los modificas parece que estás registrado. Un ejemplo:
La rutina de comprobación del serial no es para nada complicada pero recordemos que estamos tratando con VB y éste delega el trabajo duro en otras librerias de modo que tenemos que «meternos» a tracear las llamadas para ver los valores que multiplica y divide.
CPU Disasm Address Hex dump Command Comments 00405A86 FF15 3C914000 CALL DWORD PTR DS:[<&MSVBVM50.#518>] ;MSVBVM50.rtcLowerCaseVar 00405A8C 8D95 14FEFFFF LEA EDX,[EBP-1EC] 00405A92 8D8D ACFEFFFF LEA ECX,[EBP-154] 00405A98 FFD6 CALL ESI 00405A9A 8D95 ACFEFFFF LEA EDX,[EBP-154] 00405AA0 8D8D 4CFEFFFF LEA ECX,[EBP-1B4] 00405AA6 FFD7 CALL EDI 00405AA8 8D95 4CFEFFFF LEA EDX,[EBP-1B4] 00405AAE 8D8D 7CFFFFFF LEA ECX,[EBP-84] 00405AB4 FFD7 CALL EDI 00405AB6 8D85 14FEFFFF LEA EAX,[EBP-1EC] 00405ABC 8D8D 7CFFFFFF LEA ECX,[EBP-84] 00405AC2 50 PUSH EAX 00405AC3 6A 01 PUSH 1 00405AC5 8D95 04FEFFFF LEA EDX,[EBP-1FC] 00405ACB 51 PUSH ECX 00405ACC 52 PUSH EDX 00405ACD C785 1CFEFFFF 0 MOV DWORD PTR SS:[EBP-1E4],1 00405AD7 C785 14FEFFFF 0 MOV DWORD PTR SS:[EBP-1EC],2 00405AE1 FF15 68914000 CALL DWORD PTR DS:[<&MSVBVM50.#632>] ;MSVBVM50.rtcMidCharVar (Esto lo hace 6 veces, lo omito para abreviar.) ........ 00405CE1 FF15 34914000 CALL DWORD PTR DS:[<&MSVBVM50.#516>] ;MSVBVM50.rtcAnsiValueBstr (Lo mismo, otras 6) ........ 00405E7C C785 BCFDFFFF 2 MOV DWORD PTR SS:[EBP-244],52E 00405E86 C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2 00405E90 50 PUSH EAX 00405E91 FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] | ->MSVBVM50.__vbaVarMul ........ 741C19D3 0FB745 FE MOVZX EAX,WORD PTR SS:[EBP-2] ;Valor1 741C19D7 0FB74D F2 MOVZX ECX,WORD PTR SS:[EBP-0E] ;Valor2 741C19DB 6BC0 12 IMUL EAX,EAX,12 ;Valor1*Valor2 ........ 00405E97 8D8D 04FEFFFF LEA ECX,[EBP-1FC] 00405E9D 50 PUSH EAX 00405E9E 51 PUSH ECX 00405E9F FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EA5 8D95 F4FDFFFF LEA EDX,[EBP-20C] 00405EAB 50 PUSH EAX 00405EAC 52 PUSH EDX 00405EAD FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EB3 50 PUSH EAX 00405EB4 8D85 E4FDFFFF LEA EAX,[EBP-21C] 00405EBA 50 PUSH EAX 00405EBB FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405EC1 8D8D D4FDFFFF LEA ECX,[EBP-22C] 00405EC7 50 PUSH EAX 00405EC8 51 PUSH ECX 00405EC9 FF15 84914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>] 00405ECF 50 PUSH EAX 00405ED0 8D95 B4FDFFFF LEA EDX,[EBP-24C] 00405ED6 8D85 C4FDFFFF LEA EAX,[EBP-23C] 00405EDC 52 PUSH EDX 00405EDD 50 PUSH EAX 00405EDE FF15 94914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] | ->MSVBVM50.__vbaVarDiv ........ 741C8094 DD43 08 FLD QWORD PTR DS:[EBX+8] ;Recupera el resultado de las multiplicaciones anteriores 741C8097 0FBF47 08 MOVSX EAX,WORD PTR DS:[EDI+8] ;EAX = 1326 (52E) 741C809B 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX 741C809E DA75 F8 FIDIV DWORD PTR SS:[EBP-8] ;Divide los dos resultados 741C80A1 DD5E 08 FSTP QWORD PTR DS:[ESI+8] ........ 00405F44 FF15 24914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>] ;Len(nombre) ........ 00405F85 FF15 94914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] ;Resultado anterior / Len(nombre) ........
En resumen:
- Pasa nuestro nombre a minúsculas.
- Obtiene el valor ascii de los 6 primeros dígitos del nombre.
- Los multiplica entre sí y divide el resultado acumulado entre 1326 (52E).
- Divide el resultado anterior entre el tamaño del nombre.
Ejemplo para deurus
64*65*75*72*75*73 = 1A605D70EB8 1A605D70EB8 / 52E = 5179FBF4 5179FBF4 / 6 = D9454A9
Al estar correctamente registrados desaparece el botón de registrar.
CrkViz-4
El cuarto crackme es prácticamente igual que el tercero salvo que en vez de nag ahora contamos con limitación de ejecuciones. Del mismo modo utiliza el registro de Windows para guardar los datos de registro y las ejecuciones que llevamos.
Ponemos un breakpoint «bp RegOpenKeyW» y llegamos a la conclusión de que la ruta es HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register y los valores se guardan en Counter, User Name y Serial number respectivamente. Este crackme hereda el fallo del anterior y si alteramos los valores el crackme nos muestra como usuarios autorizados, aunque sabemos que no estamos registrados ya que seguimos limitados por ejecuciones. Ni que decir tiene que lo mismo que modificamos el nombre y número de serie, podemos modificar el contador a nuestro favor. Crear un archivo «Reiniciar_contador.reg» con el siguiente contenido sería suficiente.
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC] [HKEY_CURRENT_USER\Software\VB and VBA Program Settings\ODBC\Register] "Counter"="0" "User Name"="deurus" "Serial number"="12345"
El keygen es prácticamente igual que en el crackme anterior, solo cambia el divisor.
CPU Disasm
Address Hex dump Command Comments
........
00404BD2 C785 BCFDFFFF C MOV DWORD PTR SS:[EBP-244],6C1
00404BDC C785 B4FDFFFF 0 MOV DWORD PTR SS:[EBP-24C],2
00404BE6 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
|
->MSVBVM50.__vbaVarMul
741C19F9 0FBF4F 08 MOVSX ECX,WORD PTR DS:[EDI+8] ;Valor1
741C19FD 0FBF43 08 MOVSX EAX,WORD PTR DS:[EBX+8] ;Valor2
741C1A01 0FAFC8 IMUL ECX,EAX ;Valor1*Valor2
........
00404BEC 8D8D 04FEFFFF LEA ECX,[EBP-1FC]
00404BF2 50 PUSH EAX
00404BF3 51 PUSH ECX
00404BF4 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404BFA 8D95 F4FDFFFF LEA EDX,[EBP-20C]
00404C00 50 PUSH EAX
00404C01 52 PUSH EDX
00404C02 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C08 50 PUSH EAX
00404C09 8D85 E4FDFFFF LEA EAX,[EBP-21C]
00404C0F 50 PUSH EAX
00404C10 FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C16 8D8D D4FDFFFF LEA ECX,[EBP-22C]
00404C1C 50 PUSH EAX
00404C1D 51 PUSH ECX
00404C1E FF15 A0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarMul>]
00404C24 50 PUSH EAX
00404C25 8D95 B4FDFFFF LEA EDX,[EBP-24C]
00404C2B 8D85 C4FDFFFF LEA EAX,[EBP-23C]
00404C31 52 PUSH EDX
00404C32 50 PUSH EAX
00404C33 FF15 B0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>]
|
->MSVBVM50.__vbaVarDiv
741C8094 DD43 08 FLD QWORD PTR DS:[EBX+8] ; Recupera el resultado de las multiplicaciones anteriores
741C8097 0FBF47 08 MOVSX EAX,WORD PTR DS:[EDI+8] ; EAX = 1729 (6C1)
741C809B 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
741C809E DA75 F8 FIDIV DWORD PTR SS:[EBP-8]
00404C39 8BD0 MOV EDX,EAX
........
00404CA0 FF15 3C914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaLenBstr>] ;Len(nombre)
........
00404CF1 FF15 B0914000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVarDiv>] ;Resultado anterior / Len(nombre)
En resumen:
- Pasa nuestro nombre a minúsculas.
- Obtiene el valor ascii de los 6 primeros dígitos del nombre.
- Los multiplica entre sí y divide el resultado acumulado entre 1729 (6C1).
- Divide el resultado anterior entre el tamaño del nombre.
Ejemplo para deurus
64*65*75*72*75*73 = 1A605D70EB8 1A605D70EB8 / 6C1 = 3E7C594A 3E7C594A / 6 = A6A0EE2
CrkViz-5
Este último crackme está compilado en código nativo y simplemente se trata de una comparación lineal. La única diferencia reside en que no hay botón de registro, la comprobación la gestiona un evento «On Change«, de modo que está comprobando el tamaño del serial que introducimos y cuando éste tiene 8 dígitos llegamos aquí.
........ 0040A64F . C745 9C CDD4DD02 MOV DWORD PTR SS:[EBP-64],2DDD4CD ;2DDD4CD = 48092365 0040A656 . C745 94 03800000 MOV DWORD PTR SS:[EBP-6C],8003 0040A65D . FF15 08C14000 CALL DWORD PTR DS:[<&MSVBVM50.__vbaVa> ;MSVBVM50.__vbaVarTstEq 0040A663 . 66:85C0 TEST AX,AX 0040A666 . 0F84 BA000000 JE CrkMeViZ.0040A726 ;Si salta BAD BOY ........
Luego el serial correcto es 48092365.
Notas finales
¿Ha sido indoloro no?, claro que sí, Visual Basic es un coñazo de tracear pero hay que reconocer que con el tiempo las herramientas han mejorado mucho y nuestra vida es mucho más sencilla. Bueno, pués esto ha sido todo, como siempre os dejo todo el material utilizado y un Keygen.
Enlaces
Wechall Stegano Attachment (Esteganografía)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
En los retos de esteganografía ya uno se espera de todo, y cuantos más haces más enrevesados encuentras. Hoy no, hoy vamos a tratar un clásico dentro de este tipo de retos, ocultar un archivo dentro de otro.
Buscando la solución
Prácticamente lo primero que hago cuando me descargo una imágen en éste tipo de retos es abrirla con un editor hexadecimal, y en este caso hemos dado en el clavo. La abrimos con un editor cualquiera y al final del archivo encontramos que estamos tratando con un archivo ZIP (cabecera PK).
La abrimos con 7zip y vemos el prometido archivo txt, dentro ¿qué abrá?
Links
Blooper Tech Movie II – Hackers

En esta ocasión vamos a hablar de una película de culto de los años 90, Hackers – Piratas Informáticos. La verdad es que aunque puede ser entretenida, tecnológicamente es una pesadilla y es que esta película es un claro ejemplo de cuando Hollywood prefiere agradar visualmente a representar escenas realistas.
Tras cuatro minutos en los que se nos presenta a Dade (Jonny Lee Miller) y sus problemas con la ley a una temprana edad, saltamos unos años después hasta ver a Dade encerrado en su habitación volviendo a las andadas intentando acceder ilegítimamente a los servidores de una cadena de televisión. Para ello hace uso de algo muy conocido en el mundillo Hacker, la Ingeniería Social, y es que aunque ahora disponemos de «cierta» conciencia en seguridad informática, en los años 90 no había ninguna. Bien, el caso es que Dade llama a las oficinas de la citada cadena de televisión a una hora en la que no hay más que el vigilante de seguridad y éste le proporciona un número que debemos suponer que es la IP de un Módem y comienza la intrusión.
BTM
Para empezar, se le ve al protagonista escribir comandos cuando en la pantalla no hay más que una animación en algo parecido a una ventana de terminal al estilo «Commander», pero no vemos lo que escribe, algo irreal.
A continuación y como por arte de magia entra en el sistema y lo que se muestra es una animación parpadeante con el logo de la compañia y el nombre del sistema al que estamos accediendo, también irreal.
Finalmente nos muestra sus intenciones, y son nada más y nada menos que cambiar la programación actual simplemente cambiando de VHS, inmejorable. A continuación os muestro la secuencia.
Por lo menos nos queda el consuelo de que cambia la tertulia de un tipejo con ciertos prejuicios raciales por una programación más interesante como «The Outer limits«, aquí conocida como «Más allá del límite«.
El resto de escenas informáticas de la película carecen de veracidad, la única que se salva, puede ser cuando accede al servidor del Instituto para programar el sistema contra incendios y vengarse de Kate (Angelina Jolie), ya que las imágenes que aparecen son de los primeros entornos gráficos de Mac.
Es extraño que casi todas las intrusiones las realiza desde su propia casa, algo poco inteligente, ya que por muy bueno que seas, siempre dejas huellas. Solo cuando se enfrentan a un Super-Hacker se empiezan a tomar las cosas en serio y realizan los ataques desde cabinas telefónicas.
En la película También hacen mención al Phreaking y a algunos de los libros que eran famosos por aquella época pero poco más que destacar. Por todo esto y mucho más, y aunque me caen igual de bien tanto Angelina como Jonny, la película se merece un majestuoso sello de BTM.
Enlaces
JS Deobfuscator

Se nos entrega un html con un juego que consiste en hacer clic en un botón tantas veces como podamos para ganar al juego. Acompañando al html tenemos un código javascript ofuscado aparentemente con Obfuscator.io
El código javascript ofuscado tiene el siguiente aspecto.
(function(_0x144932, _0xfc69c5) { var _0x187428 = _0x588c,
_0x3064c6 = _0x144932(); while (!![]) { try { var _0xb96d19 = -parseInt(_0x187428(0x1bd)) / 0x1 + parseInt(_0x187428(0x137)) / 0x2 + -parseInt(_0x187428(0x140)) / 0x3 * (-parseInt(_0x187428(0x13b)) / 0x4) + parseInt(_0x187428(0x15e)) / 0x5 * (parseInt(_0x187428(0x18c)) / 0x6) + -parseInt(_0x187428(0x159)) / 0x7 * (parseInt(_0x187428(0x1c3)) / 0x8) + parseInt(_0x187428(0x129)) / 0x9 * (-parseInt(_0x187428(0x149)) / 0xa) + parseInt(_0x187428(0x16d)) / 0xb; if (_0xb96d19 === _0xfc69c5) break;
else _0x3064c6['push'](_0x3064c6['shift']()); } catch (_0x377a04) { _0x3064c6['push'](_0x3064c6['shift']()); } } }(_0x5be3, 0x6fe59));;
function _0x5be3() { var _0x5a2048 = ['Utf8', 'push', 'createDecryptor', 'Malformed\x20UTF-8\x20data', '_ENC_XFORM_MODE', 'string', '_prevBlock', 'extend', '_doReset', 'AnsiX923', 'error', 'fromCharCode', 'object', '130340XnpiqM', '#res', 'HmacSHA256', 'DES', '4FuuDzS', 'finalize', 'byteLength', 'salt', '_keyPriorReset', '372669TnxSTf', '_xformMode', 'HMAC', 'stringify', 'Latin1', 'cfg', 'start', 'padding', 'show', '47650FNyFfQ', 'parse', 'TripleDES', 'MD5', 'ZeroPadding', 'length', 'Rabbit', 'console', 'Base', 'HmacSHA3', 'kdf', '_doFinalize', 'drop', 'BufferedBlockAlgorithm', 'Cipher', 'HmacSHA1', '7PKTjbP', 'CTR', '_reverseMap', 'clone', 'Encryptor', '43750GcrrDy', 'SHA384', 'byteOffset', 'indexOf', 'Word', '#loader', 'algo', 'apply', 'bind', 'HmacMD5', 'Base64', '_key', 'createEncryptor', 'min', '_counter', '4232173VijiOj', '_lBlock', 'You\x20Lose', 'ECB', 'BlockCipherMode', 'ciphertext', 'floor', 'constructor', 'log', 'search', 'flush', 'Iso10126', 'update', 'NoPadding', 'max', 'HmacSHA384', 'SHA512', 'decrypt', '_des2', '(((.+)+)+)+$', 'high', 'U2FsdGVkX189ylLOlgNSxq/TLeSxBr7cYDcRBgMXXS9VmwusKZx1XFDNdpkwg24v98iYGnUATwQVyWwFnlyoCg==', 'charAt', 'return\x20(function()\x20', 'pow', 'prototype', 'compute', 'reset', 'warn', '_rBlock', 'HmacSHA512', '498WcTnbi', 'join', 'HmacSHA224', 'display', '#trim', 'StreamCipher', 'enc', 'click', '#statistic', 'random', 'keySize', 'SHA1', '_process', 'sigBytes', '$super', '#mybut', 'clamp', 'RC4', '_invSubKeys', 'loader', '_cipher', '#backstart', 'BlockCipher', 'formatter', 'WordArray', 'slice', 'decryptBlock', '_minBufferSize', 'execute', '_iv', '_hash', 'mixIn', '__proto__', 'text', 'concat', 'RabbitLegacy', 'ceil', 'splice', 'Utf16LE', 'array[0]', 'function', 'SHA3', 'charCodeAt', 'EvpKDF', 'toString', 'css', '_state', 'Decryptor', 'Hex', '82275HVLogQ', 'ivSize', 'encrypt', '_des1', '_mode', 'words', '5353976ERfqhe', 'init', '_hasher', '_createHmacHelper', '_oKey', 'lib', 'CipherParams', 'x64', '_keySchedule', 'RC4Drop', 'PBKDF2', '__creator', '_subKeys', '_nDataBytes', '_DEC_XFORM_MODE', 'format', 'substr', '_createHelper', '_data', '_parse', '#cssfilter', '_map', 'create', 'OpenSSL', 'hasher', 'table', 'key', 'hide', 'iterations', '#timecount', 'undefined', 'pad', '_iKey', 'CBC', 'OFB', '#apply', 'SHA224', '_keystream', 'mode', 'exception', 'call', 'hasOwnProperty', 'Utf16', 'encryptBlock', '_invKeySchedule', '#buttons', '_doCryptBlock', 'RIPEMD160', 'blockSize', 'low', '_des3', '{}.constructor(\x22return\x20this\x22)(\x20)', '_nRounds', 'Hasher', 'addClass', 'AES', 'CFB', 'sqrt', '171bibExj'];
_0x5be3 = function() { return _0x5a2048; }; return _0x5be3(); }
...
Deofuscado el código con la web Obfuscator.io llegamos a interpretar la estructura aunque sigue siendo un galimatías en gran parte. Aún así, si nos fijamos al final encontramos una parte interesante con una clave encriptada cuya desencriptación depende de una comparación (línea 13 resaltada). Invirtiendo esa comparación engañamos al código y obtenemos la flag.
$("#mybut").click(function () {
_0x4171cc++;
$("#cssfilter").text(_0x4171cc);
});
$("#statistic").addClass("hide");
_0x35a8b9 = setInterval(function () {
_0x97292c--;
$("#timecount").text(_0x97292c);
if (_0x97292c == 0x0) {
clearInterval(_0x35a8b9);
$("#mybut").hide();
$("#buttons").show(0x64);
if (_0x4171cc > _0x43eef3) {
$('#trim').text(CryptoJS.AES.decrypt("U2FsdGVkX189ylLOlgNSxq/TLeSxBr7cYDcRBgMXXS9VmwusKZx1XFDNdpkwg24v98iYGnUATwQVyWwFnlyoCg==", "array[0]").toString(CryptoJS.enc.Utf8));
} else {
$("#trim").text("You Lose");
}
}
}, 0x3e8);
intervalcomp = setInterval(function () {
_0x43eef3++;
$('#apply').text(_0x43eef3);
if (_0x97292c == 0x0) {
clearInterval(intervalcomp);
}
}, 0x32);
}
});
crackmes
Solución para el KeyGenMe#3 de T.0.R.N.A.D.0.

Intro
Hoy tenemos aquí un crackme del 2009 originario de crackmes.de. El Crackme está hecho en VB6, sin empacar y consta de 4 tareas a superar. Un anti-debugger, un parcheo, una sorpresa y finalmente un algoritmo sencillo.
Tarea#1 – Anti-Debugger
Nuestro primer incordio es el anti-debbuger. Este lo podemos afrontar de diferentes maneras, con un plugin desde Olly o de forma permanente parcheando. Si elegimos parchear debemos hacerlo en el offset 408328, cambiando el salto je por jmp.
00408328 /0F84 69030000 je T0RNAD0'.00408697
Tarea#2 – Parche
Si iniciamos el crackme nos encontramos con la siguiente nag que nos impide el arranque.
Las referencias de texto parecen encriptadas así que, ponemos un breakpoint a MSVBVM60.rtcMsgBox y vemos que la llamada se hace desde el offset 406897. Un poco más arriba encontramos un salto condicional muy interesante, concretamente en el offset 40677B. Lo cambiamos por un jmp y arrancamos el programa.
Tarea#3 – Encontrando el camino
A continuación arranca el crackme y vemos lo siguiente.
La sorpresa es que el formulario no se mueve y no hay rastro de las cajas de texto del keygenme. Por suerte para nosotros este crackme está hecho en vb6 y como tal podemos abrirlo con VB Reformer para ver que se nos ofrece.
Abrimos VB Reformer y cambiamos la propiedad «Moveable» del formulario a true.
Ahora ya podemos mover el formulario y por suerte para nosotros, si lo movemos hacia la esquina superior izquierda aparecen las cajas de texto por arte de magia.
Tarea#4 – El keygen
Como hemos dicho antes, las referencias de texto son inútiles, de modo que ponemos un breakpoint a MSVBVM60.__vbaStrCmp y enseguida obtenemos nuestro primer serial válido. También nos percatamos de que hasta que no metemos en el nombre 8 dígitos, no nos muestra un mensaje de error. De este mismo modo obtenemos que el nombre más grande puede tener 30 dígitos.
Username: deurusab (lenght 8)
0012F3F0 0040533A RETURN to T0RNAD0'.0040533A from MSVBVM60.__vbaStrCmp
0012F3F4 0015C954 UNICODE "L-8-deurus-0199F9CA"
Username: abcdefghijklmnopqrstuvwxyz1234 (lenght 30)
0012F3F0 0040533A RETURN to T0RNAD0'.0040533A from MSVBVM60.__vbaStrCmp
0012F3F4 0015F40C UNICODE "L-30-lmnopq-DD19F9CA"
Finalmente llegamos a la rutina de comprobación del serial. Usaremos como nombre: abcdefghijklmnopqrstuvwxyz1234.
00404E82 . 52 push edx 00404E83 . 56 push esi 00404E84 . C746 34 0DF0D1BA mov dword ptr ds:[esi+34],BAD1F00D |Variables cachondas 00404E8B . C746 38 01ADDE10 mov dword ptr ds:[esi+38],10DEAD01 |Variables cachondas 00404E92 . C746 3C EFBE1010 mov dword ptr ds:[esi+3C],1010BEEF |Variables cachondas 00404E99 . C746 40 D0BA0110 mov dword ptr ds:[esi+40],1001BAD0 |Variables cachondas 00404EA0 . FF91 2C070000 call ds:[ecx+72C] 00404EA6 . 3BC7 cmp eax,edi 00404EA8 . DBE2 fclex 00404EAA . 7D 12 jge short T0RNAD0'.00404EBE 00404EAC . 68 2C070000 push 72C 00404EB1 . 68 14404000 push T0RNAD0'.00404014 00404EB6 . 56 push esi 00404EB7 . 50 push eax 00404EB8 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00404EBE > 8B45 B4 mov eax,ss:[ebp-4C] 00404EC1 . 8D55 E0 lea edx,ss:[ebp-20] 00404EC4 . 52 push edx 00404EC5 . 50 push eax 00404EC6 . 8B08 mov ecx,ds:[eax] 00404EC8 . 8985 48FFFFFF mov ss:[ebp-B8],eax 00404ECE . FF91 A0000000 call ds:[ecx+A0] 00404ED4 . 3BC7 cmp eax,edi 00404ED6 . DBE2 fclex 00404ED8 . 7D 18 jge short T0RNAD0'.00404EF2 00404EDA . 8B8D 48FFFFFF mov ecx,ss:[ebp-B8] 00404EE0 . 68 A0000000 push 0A0 00404EE5 . 68 7C414000 push T0RNAD0'.0040417C 00404EEA . 51 push ecx 00404EEB . 50 push eax 00404EEC . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00404EF2 > 8B45 E0 mov eax,ss:[ebp-20] |Mueve el nombre a eax 00404EF5 . 8D55 A0 lea edx,ss:[ebp-60] 00404EF8 . 8945 A8 mov ss:[ebp-58],eax 00404EFB . 6A 01 push 1 00404EFD . 8D45 90 lea eax,ss:[ebp-70] 00404F00 . 52 push edx 00404F01 . 50 push eax 00404F02 . 897D E0 mov ss:[ebp-20],edi 00404F05 . C745 A0 08000000 mov dword ptr ss:[ebp-60],8 00404F0C . FF15 40114000 call ds:[<&MSVBVM60.#619>] ; MSVBVM60.rtcRightCharVar 00404F12 . 8B3D D0104000 mov edi,ds:[<&MSVBVM60.__vbaStrVarVal>] ; MSVBVM60.__vbaStrVarVal 00404F18 . 8D4D 90 lea ecx,ss:[ebp-70] 00404F1B . 8D55 DC lea edx,ss:[ebp-24] 00404F1E . 51 push ecx 00404F1F . 52 push edx 00404F20 . FFD7 call edi ; <&MSVBVM60.__vbaStrVarVal> 00404F22 . 50 push eax 00404F23 . FF15 30104000 call ds:[<&MSVBVM60.#516>] ; MSVBVM60.rtcAnsiValueBstr |Toma el último dígito en ascii (4 asc = 34) 00404F29 . 66:6BC0 7B imul ax,ax,7B |34 * 7B = 18FC 00404F2D . 8B4E 34 mov ecx,ds:[esi+34] |Mueve BAD1F00D a ecx 00404F30 . 0F80 05070000 jo T0RNAD0'.0040563B 00404F36 . 0FBFC0 movsx eax,ax 00404F39 . 33C8 xor ecx,eax |18FC xor BAD1F00D = BAD1E8F1 00404F3B . 894E 34 mov ds:[esi+34],ecx 00404F3E . 8D4D DC lea ecx,ss:[ebp-24] 00404F41 . FF15 5C114000 call ds:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr 00404F47 . 8D4D B4 lea ecx,ss:[ebp-4C] 00404F4A . FF15 60114000 call ds:[<&MSVBVM60.__vbaFreeObj>] ; MSVBVM60.__vbaFreeObj 00404F50 . 8D4D 90 lea ecx,ss:[ebp-70] 00404F53 . 8D55 A0 lea edx,ss:[ebp-60] 00404F56 . 51 push ecx 00404F57 . 52 push edx 00404F58 . 6A 02 push 2 00404F5A . FF15 20104000 call ds:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList 00404F60 . 8B06 mov eax,ds:[esi] 00404F62 . 83C4 0C add esp,0C 00404F65 . 8D4D B4 lea ecx,ss:[ebp-4C] 00404F68 . 51 push ecx 00404F69 . 56 push esi 00404F6A . FF90 2C070000 call ds:[eax+72C] 00404F70 . 85C0 test eax,eax 00404F72 . DBE2 fclex 00404F74 . 7D 12 jge short T0RNAD0'.00404F88 00404F76 . 68 2C070000 push 72C 00404F7B . 68 14404000 push T0RNAD0'.00404014 00404F80 . 56 push esi 00404F81 . 50 push eax 00404F82 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00404F88 > 8B45 B4 mov eax,ss:[ebp-4C] 00404F8B . 8D4D E0 lea ecx,ss:[ebp-20] 00404F8E . 51 push ecx 00404F8F . 50 push eax 00404F90 . 8B10 mov edx,ds:[eax] 00404F92 . 8985 48FFFFFF mov ss:[ebp-B8],eax 00404F98 . FF92 A0000000 call ds:[edx+A0] 00404F9E . 85C0 test eax,eax 00404FA0 . DBE2 fclex 00404FA2 . 7D 18 jge short T0RNAD0'.00404FBC 00404FA4 . 8B95 48FFFFFF mov edx,ss:[ebp-B8] 00404FAA . 68 A0000000 push 0A0 00404FAF . 68 7C414000 push T0RNAD0'.0040417C 00404FB4 . 52 push edx 00404FB5 . 50 push eax 00404FB6 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00404FBC > 8B45 E0 mov eax,ss:[ebp-20] 00404FBF . 6A 01 push 1 00404FC1 . 8945 A8 mov ss:[ebp-58],eax 00404FC4 . 8D45 A0 lea eax,ss:[ebp-60] 00404FC7 . 8D4D 90 lea ecx,ss:[ebp-70] 00404FCA . 50 push eax 00404FCB . 51 push ecx 00404FCC . C745 E0 00000000 mov dword ptr ss:[ebp-20],0 00404FD3 . C745 A0 08000000 mov dword ptr ss:[ebp-60],8 00404FDA . FF15 2C114000 call ds:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar 00404FE0 . 8D55 90 lea edx,ss:[ebp-70] 00404FE3 . 8D45 DC lea eax,ss:[ebp-24] 00404FE6 . 52 push edx 00404FE7 . 50 push eax 00404FE8 . FFD7 call edi 00404FEA . 50 push eax 00404FEB . FF15 30104000 call ds:[<&MSVBVM60.#516>] ; MSVBVM60.rtcAnsiValueBstr |Toma el primer dígito en ascii (a asc = 61) 00404FF1 . 66:6BC0 7B imul ax,ax,7B |61 * 7B = 2E9B 00404FF5 . 8B56 3C mov edx,ds:[esi+3C] |Mueve 1010BEEF a edx 00404FF8 . 0F80 3D060000 jo T0RNAD0'.0040563B 00404FFE . 0FBFC8 movsx ecx,ax 00405001 . 33D1 xor edx,ecx | 2E9B xor 1010BEEF = 10109074 00405003 . 8D4D DC lea ecx,ss:[ebp-24] 00405006 . 8956 3C mov ds:[esi+3C],edx 00405009 . FF15 5C114000 call ds:[<&MSVBVM60.__vbaFreeStr>] ; MSVBVM60.__vbaFreeStr 0040500F . 8D4D B4 lea ecx,ss:[ebp-4C] 00405012 . FF15 60114000 call ds:[<&MSVBVM60.__vbaFreeObj>] ; MSVBVM60.__vbaFreeObj 00405018 . 8D55 90 lea edx,ss:[ebp-70] 0040501B . 8D45 A0 lea eax,ss:[ebp-60] 0040501E . 52 push edx 0040501F . 50 push eax 00405020 . 6A 02 push 2 00405022 . FF15 20104000 call ds:[<&MSVBVM60.__vbaFreeVarList>] ; MSVBVM60.__vbaFreeVarList 00405028 . 66:8BCB mov cx,bx |Mueve a CX el tamaño del nombre 0040502B . 83C4 0C add esp,0C 0040502E . 66:69C9 4101 imul cx,cx,141 |Tamaño nombre(1E) * 141 = 259E 00405033 . 8B46 3C mov eax,ds:[esi+3C] 00405036 . 0F80 FF050000 jo T0RNAD0'.0040563B 0040503C . 0FBFD1 movsx edx,cx 0040503F . 8B4E 38 mov ecx,ds:[esi+38] |Mueve a ECX 10DEAD01 00405042 . 33D0 xor edx,eax |10109074 xor 259E = 1010B5BA 00405044 . 33CA xor ecx,edx |1010B5BA xor 10DEAD01 = 00CE18EB 00405046 . 66:8BD3 mov dx,bx 00405049 . 66:69D2 4101 imul dx,dx,141 |Tamaño nombre(1E) * 141 = 259E 0040504E . 0F80 E7050000 jo T0RNAD0'.0040563B 00405054 . 894E 38 mov ds:[esi+38],ecx 00405057 . 81F1 01010101 xor ecx,1010101 |00CE18EB xor 1010101 = 01CF19EA (Temp1) 0040505D . 0FBFD2 movsx edx,dx 00405060 . 3356 34 xor edx,ds:[esi+34] |BAD1E8F1 xor 259E = BAD1CD6F 00405063 . 894E 38 mov ds:[esi+38],ecx 00405066 . 35 10101010 xor eax,10101010 |10109074 xor 10101010 = 8064 0040506B . 8D4D B4 lea ecx,ss:[ebp-4C] 0040506E . 3156 40 xor ds:[esi+40],edx |BAD1CD6F xor 1001BAD0 = AAD077BF (Temp2) 00405071 . 8946 3C mov ds:[esi+3C],eax 00405074 . 8B06 mov eax,ds:[esi] 00405076 . 51 push ecx 00405077 . 56 push esi 00405078 . FF90 2C070000 call ds:[eax+72C] 0040507E . 85C0 test eax,eax 00405080 . DBE2 fclex 00405082 . 7D 12 jge short T0RNAD0'.00405096 00405084 . 68 2C070000 push 72C 00405089 . 68 14404000 push T0RNAD0'.00404014 0040508E . 56 push esi 0040508F . 50 push eax 00405090 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00405096 > 8B45 B4 mov eax,ss:[ebp-4C] 00405099 . 8D4D DC lea ecx,ss:[ebp-24] 0040509C . 51 push ecx 0040509D . 50 push eax 0040509E . 8B10 mov edx,ds:[eax] 004050A0 . 8985 48FFFFFF mov ss:[ebp-B8],eax 004050A6 . FF92 A0000000 call ds:[edx+A0] 004050AC . 85C0 test eax,eax 004050AE . DBE2 fclex 004050B0 . 7D 18 jge short T0RNAD0'.004050CA 004050B2 . 8B95 48FFFFFF mov edx,ss:[ebp-B8] 004050B8 . 68 A0000000 push 0A0 004050BD . 68 7C414000 push T0RNAD0'.0040417C 004050C2 . 52 push edx 004050C3 . 50 push eax 004050C4 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 004050CA > 8B06 mov eax,ds:[esi] 004050CC . 8D4D B0 lea ecx,ss:[ebp-50] 004050CF . 51 push ecx 004050D0 . 56 push esi 004050D1 . FF90 2C070000 call ds:[eax+72C] 004050D7 . 85C0 test eax,eax 004050D9 . DBE2 fclex 004050DB . 7D 12 jge short T0RNAD0'.004050EF 004050DD . 68 2C070000 push 72C 004050E2 . 68 14404000 push T0RNAD0'.00404014 004050E7 . 56 push esi 004050E8 . 50 push eax 004050E9 . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 004050EF > 8B45 B0 mov eax,ss:[ebp-50] 004050F2 . 8D4D D0 lea ecx,ss:[ebp-30] 004050F5 . 51 push ecx 004050F6 . 50 push eax 004050F7 . 8B10 mov edx,ds:[eax] 004050F9 . 8985 3CFFFFFF mov ss:[ebp-C4],eax 004050FF . FF92 A0000000 call ds:[edx+A0] 00405105 . 85C0 test eax,eax 00405107 . DBE2 fclex 00405109 . 7D 18 jge short T0RNAD0'.00405123 0040510B . 8B95 3CFFFFFF mov edx,ss:[ebp-C4] 00405111 . 68 A0000000 push 0A0 00405116 . 68 7C414000 push T0RNAD0'.0040417C 0040511B . 52 push edx 0040511C . 50 push eax 0040511D . FF15 40104000 call ds:[<&MSVBVM60.__vbaHresultCheckObj>] ; MSVBVM60.__vbaHresultCheckObj 00405123 > 8B45 D0 mov eax,ss:[ebp-30] 00405126 . 6A 01 push 1 00405128 . 8945 98 mov ss:[ebp-68],eax 0040512B . 8D45 90 lea eax,ss:[ebp-70] 0040512E . 8D4D 80 lea ecx,ss:[ebp-80] 00405131 . 50 push eax 00405132 . 51 push ecx 00405133 . C745 A8 06000000 mov dword ptr ss:[ebp-58],6 0040513A . C745 A0 02000000 mov dword ptr ss:[ebp-60],2 00405141 . C745 D0 00000000 mov dword ptr ss:[ebp-30],0 00405148 . C745 90 08000000 mov dword ptr ss:[ebp-70],8 0040514F . FF15 40114000 call ds:[<&MSVBVM60.#619>] ; MSVBVM60.rtcRightCharVar 00405155 . 8D55 80 lea edx,ss:[ebp-80] 00405158 . 8D45 CC lea eax,ss:[ebp-34] 0040515B . 52 push edx 0040515C . 50 push eax 0040515D . FFD7 call edi 0040515F . 50 push eax 00405160 . FF15 30104000 call ds:[<&MSVBVM60.#516>] ; MSVBVM60.rtcAnsiValueBstr 00405166 . 8B56 40 mov edx,ds:[esi+40] |Mueve a EDX AAD077BF (Temp2) 00405169 . 68 90414000 push T0RNAD0'.00404190 ; UNICODE "L-" |Comienza el serial 0040516E . 0FBFC8 movsx ecx,ax |Mueve a ECX último dígito en ascii (34) 00405171 . 8B46 38 mov eax,ds:[esi+38] |Mueve a EAX 01CF19EA (Temp1) 00405174 . 53 push ebx 00405175 . 03D0 add edx,eax |AAD077BF + 01CF19EA = AC9F91A9 00405177 . C785 70FFFFFF 0300000>mov dword ptr ss:[ebp-90],3 00405181 . 0F80 B4040000 jo T0RNAD0'.0040563B 00405187 . 03CA add ecx,edx |AC9F91A9 + 34 = AC9F91DD (Nuestro serial) 00405189 . 0F80 AC040000 jo T0RNAD0'.0040563B 0040518F . 898D 78FFFFFF mov ss:[ebp-88],ecx 00405195 . FF15 04104000 call ds:[<&MSVBVM60.__vbaStrI2>] ; MSVBVM60.__vbaStrI2 0040519B . 8B3D 38114000 mov edi,ds:[<&MSVBVM60.__vbaStrMove>] ; MSVBVM60.__vbaStrMove 004051A1 . 8BD0 mov edx,eax 004051A3 . 8D4D E0 lea ecx,ss:[ebp-20] 004051A6 . FFD7 call edi ; <&MSVBVM60.__vbaStrMove> 004051A8 . 50 push eax |EAX = tamaño del nombre 004051A9 . FF15 38104000 call ds:[<&MSVBVM60.__vbaStrCat>] ; MSVBVM60.__vbaStrCat |Concatena con "L-" 004051AF . 8BD0 mov edx,eax 004051B1 . 8D4D BC lea ecx,ss:[ebp-44] 004051B4 . FFD7 call edi 004051B6 . 66:83EB 06 sub bx,6 |Tamaño nombre - 6 = 18 004051BA . 50 push eax 004051BB . 0F80 7A040000 jo T0RNAD0'.0040563B 004051C1 . 0FBFCB movsx ecx,bx 004051C4 . 898D 08FFFFFF mov ss:[ebp-F8],ecx 004051CA . 8D45 A0 lea eax,ss:[ebp-60] 004051CD . DB85 08FFFFFF fild dword ptr ss:[ebp-F8] 004051D3 . 68 9C414000 push T0RNAD0'.0040419C 004051D8 . 50 push eax 004051D9 . DD9D 00FFFFFF fstp qword ptr ss:[ebp-100] 004051DF . DD85 00FFFFFF fld qword ptr ss:[ebp-100] 004051E5 . 833D 00A04000 00 cmp dword ptr ds:[40A000],0 004051EC . 75 08 jnz short T0RNAD0'.004051F6 004051EE . DC35 78114000 fdiv qword ptr ds:[401178] |18 / 2 = C (C es la posición para cojer dígitos del nombre, coje 6) 004051F4 . EB 11 jmp short T0RNAD0'.00405207 004051F6 > FF35 7C114000 push dword ptr ds:[40117C] 004051FC . FF35 78114000 push dword ptr ds:[401178] 00405202 . E8 3DC0FFFF call <jmp.&MSVBVM60._adj_fdiv_m64> 00405207 > DFE0 fstsw ax 00405209 . A8 0D test al,0D 0040520B . 0F85 25040000 jnz T0RNAD0'.00405636 00405211 . FF15 44114000 call ds:[<&MSVBVM60.__vbaR8IntI4>] ; MSVBVM60.__vbaR8IntI4 00405217 . 8B55 DC mov edx,ss:[ebp-24] |EDX = nombre 0040521A . 50 push eax |Eax = C 0040521B . 52 push edx 0040521C . FF15 6C104000 call ds:[<&MSVBVM60.#631>] ; MSVBVM60.rtcMidCharBstr |Mid(nombre,C,6) = "lmnopq" 00405222 . 8BD0 mov edx,eax 00405224 . 8D4D D8 lea ecx,ss:[ebp-28] 00405227 . FFD7 call edi 00405229 . 8B1D 38104000 mov ebx,ds:[<&MSVBVM60.__vbaStrCat>] ; MSVBVM60.__vbaStrCat 0040522F . 50 push eax 00405230 . FFD3 call ebx ; <&MSVBVM60.__vbaStrCat> |Concatena "-lmnopq" 00405232 . 8BD0 mov edx,eax 00405234 . 8D4D D4 lea ecx,ss:[ebp-2C] 00405237 . FFD7 call edi 00405239 . 50 push eax 0040523A . 68 9C414000 push T0RNAD0'.0040419C 0040523F . FFD3 call ebx |Concatena "-lmnopq-" 00405241 . 8BD0 mov edx,eax 00405243 . 8D4D C4 lea ecx,ss:[ebp-3C] 00405246 . FFD7 call edi 00405248 . 50 push eax 00405249 . 8D85 70FFFFFF lea eax,ss:[ebp-90] 0040524F . 50 push eax 00405250 . FF15 F0104000 call ds:[<&MSVBVM60.#572>] ; MSVBVM60.rtcHexBstrFromVar |serial "AC9F91DD" 00405256 . 8BD0 mov edx,eax 00405258 . 8D4D C8 lea ecx,ss:[ebp-38] 0040525B . FFD7 call edi 0040525D . 50 push eax 0040525E . FF15 B4104000 call ds:[<&MSVBVM60.#713>] ; MSVBVM60.rtcStrReverse |Invierte el serial "DD19F9CA" 00405264 . 8BD0 mov edx,eax 00405266 . 8D4D C0 lea ecx,ss:[ebp-40] 00405269 . FFD7 call edi 0040526B . 50 push eax 0040526C . FFD3 call ebx |Concatena "-lmnopq-DD19F9CA" 0040526E . 8BD0 mov edx,eax 00405270 . 8D4D B8 lea ecx,ss:[ebp-48] 00405273 . FFD7 call edi 00405275 . 50 push eax 00405276 . FFD3 call ebx |Concatena "L-30-lmnopq-DD19F9CA" ... 00405334 . FF15 80104000 call ds:[<&MSVBVM60.__vbaStrCmp>] ; MSVBVM60.__vbaStrCmp |Comparación final
Ejemplos:
Nombre: abcdefghijklmnopqrstuvwxyz1234 Serial: L-30-lmnopq-DD19F9CA Nombre: deurus2014 Serial: L-10-eurus2-84D8F9CA
Links
- Crackme y Keygen [crackmes.de]
Shadow’s Register Me – Parchear un .Net

Introducción
Este es un crackme hecho en .Net con dos Nags a parchear y un algoritmo muy sencillo pero que tendremos que parchear para poder resolverlo.
Las Nags
Se encuentran en los eventos de carga y cierre del formulario.
// RegisterMe.Form1
private void Form1_Load(object sender, EventArgs e)
{
Interaction.MsgBox("Register me pl0x!", MsgBoxStyle.OkOnly, "Nag!!!!");
}
// RegisterMe.Form1
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Interaction.MsgBox("Register me pl0x!", MsgBoxStyle.OkOnly, "Nag2!!!!");
}
Para parchear un ejecutable realizado en .Net primero necesitamos ubicarnos. Abrimos IL Dasm y vamos al evento «Form_Load«, nos fijamos en los bytes y los buscamos con un editor hexadecimal. Fijaros bien en los bytes ya que siguen un orden específico, en la imágen del editor hexadecimal se aprecia perfectamente. Para que quede parcheada la Nag basta con sustituir los valores por ceros. Se parchea todo excepto el «RET (2A)».
Para la otra Nag sería lo mismo.
El algoritmo
El algoritmo es muy sencillo, consiste en la concatenación de varias palabras y un número aleatorio. El problema viene con el número aleatorio ya que lo tendremos que parchear para poder registrar el programa.
// RegisterMe.Form1
private void Button1_Click(object sender, EventArgs e)
{
this.shadow = this.rand.Next(1, 99999999);
if (Operators.ConditionalCompareObjectEqual(this.TextBox2.Text, Operators.ConcatenateObject(this.TextBox1.Text + this.TextBox3.Text + this.TextBox4.Text + this.TextBox5.Text + this.TextBox6.Text + this.TextBox7.Text + this.TextBox8.Text + this.TextBox9.Text + this.TextBox1.Text, this.shadow), false))
{
this.Button2.Enabled = true;
this.Button1.Enabled = false;
this.Button1.Text = "Registered to Shadow";
this.Text = "Registered to Shadow!";
}
else
{
Interaction.MsgBox("Incorrect serial, noob.", MsgBoxStyle.OkOnly, null);
}
}
La concatenación quedaría así:
TextBox1.Text = Nuestro usuario + TextBox3.Text = «ur» + TextBox4.Text = «a» + TextBox5.Text = «stupid» + TextBox6.Text = «dumb» + TextBox7.Text = «idiotic» + TextBox8.Text = «crazy» + TextBox9.Text = «noob» + TextBox1.Text = Nuestro usuario + El número aleatorio
Ejemplo
- Nombre: deurus
- Clave: deurusurastupiddumbidioticcrazynoobdeurus98265385
Parcheando el número aleatorio
Buscamos el evento click en IL Dasm y nos fijamos que aparece el número «5F5E0FF» que en decimal equivale a «99999999«, buscamos los bytes en el editor hexadecimal y lo parcheamos a 1. De este modo anulamos la aletoriedad, ahora el número siempre es 1.
Ahora ya podemos registrarnos.
Links
AperiSolve (Zsteg)

AperiSolve es un conjunto de herramientas de análisis esteganográfico que nos ayuda a echar un primer vistazo cuando sospechamos que una imagen esconde algo.
Zsteg es una herramienta especializada en la detección y extracción de información oculta en imágenes, especialmente en formatos PNG y BMP. Está orientada a la esteganografía basada en bit-planes y es muy popular en entornos CTF y análisis forense, gracias a su capacidad para automatizar búsquedas exhaustivas de datos escondidos en los bits menos significativos (LSB) y en configuraciones de color poco habituales. Su principal fortaleza es que no se limita a examinar un único plano: prueba sistemáticamente combinaciones de canales (R, G, B, A), número de bits, orden de lectura y posicionamiento, detectando patrones que podrían pasar inadvertidos en una revisión manual.
Entre sus características más destacadas se encuentran la identificación automática de firmas de archivos (ZIP, PNG, texto ASCII, GZIP, etc.), la extracción directa de bitstreams reconstruidos y el soporte para diferentes rutas de exploración, como
b1,rgb,lsb,xy, que describen exactamente cómo se han recuperado los datos. Esta capacidad de correlacionar parámetros técnicos con resultados concretos convierte a zsteg en una herramienta muy eficiente tanto para localizar contenido oculto como para entender la técnica esteganográfica aplicada.
En AperiSolve se utiliza únicamente la parte de Zsteg encargada de ejecutar el análisis automático y devolver todas las detecciones posibles de esteganografía LSB en imágenes PNG y BMP. Concretamente, AperiSolve llama al comando zsteg <imagen> tal como está implementado en el módulo analyze_zsteg , y captura la salida completa línea por línea. Esta salida incluye todas las combinaciones probadas de bit-planes (b1, b2…), canales (r, g, b, a), orden de bits (lsb/msb) y métodos de recorrido (xy), junto con cualquier coincidencia que zsteg reconozca como firma de archivo o texto. Es decir, AperiSolve no aplica filtros ni interpretación adicional: muestra exactamente lo que zsteg detecta y lo organiza para que el usuario pueda identificar rápidamente si existe un archivo embebido, contenido ASCII, o algún patrón de interés.
En AperiSolve veremos algo como esto:
... b1,a,lsb,xy .. b1,a,msb,xy .. b1,rgb,lsb,xy .. file: Zip archive data, at least v1.0 to extract, compression method=store b1,rgb,msb,xy .. b1,bgr,lsb,xy .. b1,bgr,msb,xy .. b1,rgba,lsb,xy .. b1,rgba,msb,xy .. file: OpenPGP Public Key b1,abgr,lsb,xy .. b1,abgr,msb,xy .. file: OpenPGP Secret Key b2,r,lsb,xy .. b2,r,msb,xy .. text: "P@UPUUPAAUU@" b2,g,lsb,xy .. text: "(ahOFyIS!" ...
Para entender mejor a que se refiere todo esto vamos a repasar lo básico.
¿Qué es LSB y qué es MSB?
Cuando hablamos de esteganografía en imágenes PNG/BMP, nos referimos a manipular bits dentro de los canales de color (R, G, B, A). Cada canal tiene un valor de 0–255, es decir, 8 bits:
R = 11001010 G = 00110101 B = 11100001
LSB — Least Significant Bit (bit menos significativo). Es el bit más débil, el de la derecha:
1100101[0] ← LSB
Modificarlo cambia muy poco el color, por eso se usa en esteganografía.
Ejemplo: cambiar 11001010 ↦ 11001011 no cambia el color perceptible.
MSB — Most Significant Bit (bit más significativo). Es el bit más importante, el de la izquierda:
[1]1001010 ← MSB
Modificarlo sí altera mucho el color. A veces se usa pero suele ser detectable.
Cuando Zsteg muestra una línea del estilo b1,rgb,lsb,xy .. file: Zip archive data, está indicando que ha analizado la imagen extrayendo bits según la ruta especificada —en este caso, 1 bit por píxel (b1), combinando los canales rojo, verde y azul (rgb), utilizando el bit menos significativo (lsb) y recorriendo los píxeles en orden normal de lectura (xy)— y que, tras recomponer esos bits, el resultado coincide con la cabecera reconocible de un tipo de archivo real. Por eso aparece “file: Zip archive data”: significa que los bits ocultos forman un flujo válido cuya firma corresponde a un archivo ZIP. En otras ocasiones puede detectar texto ASCII, PNG, JPEG u otros formatos. En resumen, cuando Zsteg muestra esta línea no solo indica dónde se ocultan los datos, sino que confirma que lo recuperado es un archivo auténtico y probablemente extraíble, ya que la estructura binaria coincide con un formato conocido.
Si vemos que Zsteg nos ofrece algo interesante, podemos extraerlo mediante el comando:
zsteg -E b1,rgb,lsb,xy imagen.png > dump.bin
También es habitual usar herramientas como StegSolve. En este caso debemos dirigirnos a Analyse > Data extract para comprobar lo encontrado por zsteg y extraerlo mediante Save Bin.
| Zsteg | > Significado < | StegSolve |
|---|---|---|
| b1 | Extrae 1 bit por canal (bit plano 0, el menos significativo). | En Bit Planes, marca Red 0, Green 0, Blue 0. Solo esos. |
| rgb | Usa R + G + B en ese orden para reconstruir los bytes. | En Bit Plane Order, selecciona RGB. |
| lsb | Lee los bits empezando por el LSB (bit 0) antes que el MSB. | En Bit Order, selecciona LSB First. |
| xy | Recorre la imagen por filas (izquierda → derecha, arriba → abajo). | En Extract By, elige Row. |

Más allá de este caso concreto, conviene recordar que la esteganografía no se limita a los LSB: existen métodos basados en paletas, metadatos, manipulación de PNG chunks, secuencias alfa, audio incrustado o capas completas en formatos no comprimidos. Por ello, un análisis completo debería combinar la búsqueda clásica de LSB con herramientas complementarias como binwalk, foremost, exiftool, strings, o incluso análisis manual de cabeceras hexadecimales.
Keygen para el Crackme Sweeet Dream 1.0 de 2Sweeet

Intro
Hoy tenemos aquí un crackme del año 2000 empacado y con un algoritmo aunque no muy complicado largo de tracear. Está empacado varias veces, algo poco habitual pero recordemos que es un crackme antiguo. Tras el empacado se encuentra Delphi.
Herramientas
- PEiD o similar.
- OllyDbg con plugin OllyDumpEX.
- Import REConstructor.
- LordPE (Opcional).
Desempacado multicapa
VideoTutorial del desempacado disponible
Si lo pasamos por PEiD nos dice que Aspack 2.1, Exeinfo no está muy seguro y RDG packer detector en el escaneo avanzado nos encuentra Aspack, UPX y PE-Pack.
En principio nos enfrentamos a Aspack 2.1, abrimos el crackme con OllyDbg y vemos el típico PUSHAD.
Pulsamos F8 (Step Over) y a continuación click derecho sobre el registro ESP y Follow in DUMP.
Seleccionamos los primeros cuatro bytes útiles del dump y les ponemos un Breakpoint de Hardware, Access y Dword.
Pulsamos F9 y nos para aquí:
Ya tenemos a Aspack contra las cuerdas, pulsamos F8 hasta después del RETN para llegar al OEP (Original Entry Point).
Pero en el supuesto OEP vemos otro PUSHAD por lo que esto no ha terminado. Investigando un poco más vemos que la segunda capa se corresponde con PE-PACK 1.0. La estrategia a seguir es la misma, como ya tenemos el breakpoint puesto pulsamos F9 y nos para aquí:
Pulsamos F8 y nos llega a otro PUSHAD. Esta vez es UPX.
Pulsamos de nuevo F9 y paramos aquí:
Pulsamos F8 y esta vez si llegamos al OEP (4576EC).
A continuación vamos a dumpear el archivo en memoria. Vamos a plugins > OllyDumpEX, pulsamos sobre «Get EIP as OEP» y finalmente sobre «Dump«.
Minimizamos Olly (no cerrar), abrimos el programa ImportREC y seleccionamos el ejecutable «Sweeet1.exe».
Pegamos el OEP original (576EC), le damos a AutoSearch y a continuación a Get Imports.
Finalmente pulsamos Fix Dump y elegimos el ejecutable dumpeado anteriormente. Esto nos genera un ejecutable dumpeado que es el ejecutable válido.
Ahora PEiD nos dice que estamos tratando con un crackme hecho en Delphi.
Hemos pasado por tres capas de compresión casi idénticas, vamos a analizarlas.
El algoritmo
Cuando abrimos el crackme nos fijamos en que genera una key. Esta key se genera en función del disco duro desde el que se ejecuta.
Como la secuencia de generación del serial válido es larga os pongo lo más importante muy resumido y con ejemplos como siempre.
El serial es del siguiente tipo:
Serial = 1ªParte-2ªParte-3ªParte
Serial = 0000XXXXX-SerialCalculado-xxxx000Z8
Comprobación del tamaño del nombre ---------------------------------- ........ 00456EAA E8 01CCFAFF CALL sweeet1_Fix_dump_rebuilded.00403AB0 00456EAF 83F8 04 CMP EAX,4 ------------------------------------------------; Nombre >=4 00456EB2 7D 13 JGE SHORT sweeet1_Fix_dump_rebuilded.00456EC7 00456EB4 A1 08954500 MOV EAX,DWORD PTR DS:[sweeet1_Fix_dump_rebuilded.459508] 00456EB9 8B00 MOV EAX,DWORD PTR DS:[EAX] 00456EBB E8 0869FEFF CALL sweeet1_Fix_dump_rebuilded.0043D7C8 00456EC0 BB 01000000 MOV EBX,1 00456EC5 EB 15 JMP SHORT sweeet1_Fix_dump_rebuilded.00456EDC 00456EC7 83FB 25 CMP EBX,25 00456ECA 7D 0E JGE SHORT sweeet1_Fix_dump_rebuilded.00456EDA 00456ECC 83C3 32 ADD EBX,32 00456ECF 83C3 1E ADD EBX,1E 00456ED2 83EB 4F SUB EBX,4F 00456ED5 83FB 25 CMP EBX,25 -----------------------------------------------; Nombre <=25 00456ED8 ^ 7C F2 JL SHORT sweeet1_Fix_dump_rebuilded.00456ECC 00456EDA 33DB XOR EBX,EBX 00456EDC 33C0 XOR EAX,EAX ........ 1ºBucle - Nuestro nombre (A) ---------------------------- ........ 00456F55 BE 1B000000 MOV ESI,1B -------------------------------; ESI = 1B 00456F5A EB 21 JMP SHORT sweeet1_dump_.00456F7D 00456F5C 8D55 D4 LEA EDX,[EBP-2C] 00456F5F A1 34A84500 MOV EAX,DWORD PTR DS:[sweeet1_dump_.45A8 00456F64 8B80 C4020000 MOV EAX,DWORD PTR DS:[EAX+2C4] 00456F6A E8 B5DAFCFF CALL sweeet1_dump_.00424A24 00456F6F 8B45 D4 MOV EAX,DWORD PTR SS:[EBP-2C] 00456F72 0FB64418 FF MOVZX EAX,BYTE PTR DS:[EBX+EAX-1]---------; Coje digito 00456F77 03F0 ADD ESI,EAX ------------------------------; digito + ESI 00456F79 43 INC EBX 00456F7A 0FAFF3 IMUL ESI,EBX ----------------------------; multiplica por i (bucle) 00456F7D 8D55 D4 LEA EDX,[EBP-2C] ........ 2ºBucle - La key (B) -------------------- ........ 00456F9C |. BF 1A000000 MOV EDI,1A -------------------------;EDI = 1A 00456FA1 |. BB 01000000 MOV EBX,1 00456FA6 |. EB 1E JMP SHORT sweeet1_.00456FC6 00456FA8 |> 8D55 D4 /LEA EDX,[LOCAL.11] 00456FAB |. A1 34A84500 |MOV EAX,DWORD PTR DS:[45A834] 00456FB0 |. 8B80 D0020000 |MOV EAX,DWORD PTR DS:[EAX+2D0] 00456FB6 |. E8 69DAFCFF |CALL sweeet1_.00424A24 00456FBB |. 8B45 D4 |MOV EAX,[LOCAL.11] 00456FBE |. 0FB64418 FF |MOVZX EAX,BYTE PTR DS:[EAX+EBX-1]--;Coje dígito 00456FC3 |. 03F8 |ADD EDI,EAX -----------------------;Suma dígito a dígito 00456FC5 |. 43 |INC EBX 00456FC6 |> 8D55 D4 LEA EDX,[LOCAL.11] 00456FC9 |. A1 34A84500 |MOV EAX,DWORD PTR DS:[45A834] 00456FCE |. 8B80 D0020000 |MOV EAX,DWORD PTR DS:[EAX+2D0] 00456FD4 |. E8 4BDAFCFF |CALL sweeet1_.00424A24 00456FD9 |. 8B45 D4 |MOV EAX,[LOCAL.11] 00456FDC |. E8 CFCAFAFF |CALL sweeet1_.00403AB0 00456FE1 |. 3BD8 |CMP EBX,EAX 00456FE3 |.^ 7C C3 \JL SHORT sweeet1_.00456FA8 ........ Generación del serial central ----------------------------- ........ 00456FE5 |. B9 01000000 MOV ECX,1 00456FEA |. BB 01000000 MOV EBX,1 00456FEF |. 8BC7 MOV EAX,EDI 00456FF1 |. F7EE IMUL ESI ----------; C = A * B 00456FF3 |. 99 CDQ ........ 00456FFD |. 2345 E8 AND EAX,[LOCAL.6]--; D = A and C 00457000 |. 2355 EC AND EDX,[LOCAL.5] 00457003 |. 8945 E8 MOV [LOCAL.6],EAX 00457006 |. 8955 EC MOV [LOCAL.5],EDX ........ 00457032 |. 8BC7 MOV EAX,EDI 00457034 |. 99 CDQ 00457035 |. 0345 E8 ADD EAX,[LOCAL.6]--; E = D + B 00457038 |. 1355 EC ADC EDX,[LOCAL.5] 0045703B |. 8945 E0 MOV [LOCAL.8],EAX 0045703E |. 8955 E4 MOV [LOCAL.7],EDX ........ 00405732 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10] 00405736 F72424 MUL DWORD PTR SS:[ESP] 00405739 8BC8 MOV ECX,EAX 0040573B 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] 0040573F F76424 0C MUL DWORD PTR SS:[ESP+C]------; F = B * D 00405743 03C8 ADD ECX,EAX 00405745 8B0424 MOV EAX,DWORD PTR SS:[ESP] 00405748 F76424 0C MUL DWORD PTR SS:[ESP+C]------; G = A * F ........ 0045705E |. 0B0424 OR EAX,DWORD PTR SS:[ESP]-----; Serial central = G or A ........ 00457077 |. E8 FC07FBFF CALL sweeet1_.00407878 0045707C |. 8B45 F8 MOV EAX,[LOCAL.2]-------------; EAX = Serial central ........ 004570D1 |. E8 A207FBFF CALL sweeet1_.00407878 004570D6 |. 8B45 D0 MOV EAX,[LOCAL.12] 004570D9 |. E8 D2C9FAFF CALL sweeet1_.00403AB0--------; Obtiene longitud del serial central en hexa 004570DE |. 8BD8 MOV EBX,EAX ........ 004570D1 |. E8 A207FBFF CALL sweeet1_.00407878--------;*Nota
*Nota:
A partir de aquí genera la primera y tercera parte del serial de la siguiente manera:
Serial = 1ªParte-2ªParte-3ªParte
Serial = 0000XXXXX-SerialCalculado-xxxx000Z8
1ºParte = 3ºdigSerial+1ºdigSerial+2ºdigSerial+3ºdigSerial+4ºdigNombreMayu+2ºdigNombreMayu+5ºdigNombreMayu+1ºdigNombreMayu+3ºdigNombreMayu 3ºParte = 3ºdigNombreMin+1ºdigNombreMin+4ºdigNombreMin+2ºdigNombreMin+Tamaño Serial_2ªParte en Hex y de tres dígitos+Z8
Ejemplo:
Nombre: deurus Key: C0C0A000 Serial: 6906REUDU-906297047918-udre00CZ8 1) A = 23A2A (Con nuestro nombre empezando por 1B se lo suma a ESI y se lo multiplica por i (la que toque cada vez)) 2) B = 1A1 (Con nuestra Key empezando por 1A va sumando los digitos) 3) C = B * A = 3A0BE6A 4) D = A and C = 3A2A 5) E = D + B = 3BCB (Offset 457035) 6) F = B * D = 5EBE6A (Offset 48704A) 7) G = A * F = D303834164 8) Serial = G or A (Serial = D303834164 or 23A2A = D303837B6E (906297047918))
A tener en cuenta:
- 1ªParte del serial siempre mayúsculas.
- 2ªParte siempre numérico. Usa el registro de 64 bits (Qword) con signo.**Nota
- 3ªParte siempre minúsculas.
**Nota:
Nombre: deurus.info Key: E09FF000 Serial: 9169REUDU-16918236-udre008Z8 Fíjate que: -16918236 = FFFFFFFFFEFDD924 Nombre: deurus Key: C0C0A000 Serial: 6906REUDU-906297047918-udre00CZ8 906297047918 = 000000D303837B6E
Links
Reversing – Nosotros y ChatGPT contra un ELF desde Windows

Intro
Antes que nada, es importante saber que un archivo ELF en Linux es equivalente a un archivo EXE en Windows. Dicho esto, es bastante común encontrarnos con ejecutables ELF en diversos CTFs (Capture The Flag), y a menudo representan un desafío para aquellos no familiarizados con el uso cotidiano de Linux. Sin embargo, tengo una buena noticia si no eres aficionado de Linux: existen herramientas que permiten realizar un análisis preliminar para determinar si es necesario abordar el problema desde Linux o si podemos resolverlo directamente desde Windows. Estas herramientas facilitan una transición más cómoda para los usuarios de Windows, permitiéndoles interactuar eficazmente con archivos ELF.
ELF
Un archivo ELF (Executable and Linkable Format) es un formato común de archivo para archivos ejecutables, código objeto, bibliotecas compartidas y volcados de memoria en sistemas basados en Unix, como Linux. Es el estándar de formato de archivo para programas compilados y enlazados en este tipo de sistemas operativos.
La cabecera de un archivo ELF es una estructura de datos al comienzo del archivo que proporciona información esencial sobre el contenido y la forma de procesar el archivo. Esta cabecera es fundamental para que el sistema operativo y otros programas puedan interpretar correctamente el archivo ELF. Aquí están los componentes clave de la cabecera de un archivo ELF:
- Identificación (e_ident): Esta sección incluye la magia del archivo ELF, representada por los primeros cuatro bytes
0x7F 'E' 'L' 'F'. También incluye información como la clase del archivo (32 o 64 bits), la codificación de datos (endianness), y la versión del formato ELF. - Tipo (e_type): Indica el tipo de archivo ELF, como EXEC (ejecutable), DYN (biblioteca compartida), REL (relocalizable), entre otros.
- Máquina (e_machine): Especifica la arquitectura de hardware para la cual se diseñó el archivo, por ejemplo, x86, ARM.
- Versión (e_version): La versión del formato ELF, generalmente establecida en 1.
- Punto de Entrada (e_entry): La dirección de memoria virtual donde comienza la ejecución del proceso.
- Desplazamiento del Program Header (e_phoff): Indica dónde comienza el encabezado del programa en el archivo.
- Desplazamiento del Section Header (e_shoff): Indica dónde comienza el encabezado de la sección en el archivo.
- Flags (e_flags): Banderas específicas del procesador.
- Tamaño de esta cabecera (e_ehsize): El tamaño de la cabecera ELF.
- Tamaño del Program Header (e_phentsize): El tamaño de una entrada del encabezado del programa.
- Número de entradas del Program Header (e_phnum): El número total de entradas en el encabezado del programa.
- Tamaño del Section Header (e_shentsize): El tamaño de una entrada del encabezado de la sección.
- Número de entradas del Section Header (e_shnum): El número total de entradas en el encabezado de la sección.
- Índice del Section Header Table (e_shstrndx): El índice del encabezado de la sección que contiene los nombres de las secciones.
El reto
Se nos proporciona un fichero de 20KB que rápidamente catalogamos como ELF.

Para realizar un análisis preliminar siempre uso DogBolt, que no es más que un decompilador online con la ventaja de que usa varios motores y de esta forma casi siempre te da una decompilación aceptable. La versión actual tiene disponibles 11 motores y además es open source, ¿Qué más se puede pedir?

Echamos un vistazo y enseguida encontramos algo interesante.

La flag parece codificada de modo que vamos a indagar acerca de la función FUN_0010285d

Dentro de la función FUN_0010285d vemos que nuestra flag codificada la procesa la función FUN_00102752

Aquí os diría que depende de vuestra experiencia en programación veríais que se está procesando byte a byte la cadena de entrada (param_1) y haciendo a cada byte un XOR (^) con el param_3 (que es 1 según vemos en la llamada de la función FUN_00102752), pero en estos tiempos que corren vamos a preguntar a ChatGPT que opina.
ChatGPT
Le pido a ChapGPT que me analice el código y me responde:
Este código en C define una función llamada
FUN_00102752que realiza una operación de XOR (exclusivo OR) byte a byte sobre un bloque de memoria. La función toma tres parámetros:
long param_1: Este parámetro es tratado como una dirección de memoria. Se utiliza como la base de un bloque de memoria sobre el que se realizará la operación.ulong param_2: Este parámetro especifica el tamaño del bloque de memoria que será afectado por la operación.byte param_3: Este es el valor de un solo byte que se utilizará en la operación XOR.El cuerpo de la función consiste en un bucle
forque itera sobre el bloque de memoria:
int local_cse declara como una variable local y se inicializa en 0. Esta variable actúa como un contador para el bucle.- La condición del bucle
(ulong)(long)local_c < param_2asegura que el bucle se ejecute sobre el rango completo del bloque de memoria especificado porparam_2.- Dentro del bucle,
*(byte *)(param_1 + local_c) = *(byte *)(param_1 + local_c) ^ param_3;realiza la operación XOR. Aquí,*(byte *)(param_1 + local_c)accede al byte actual en el bloque de memoria. Este byte se modifica aplicándole un XOR conparam_3. La operación XOR se realiza entre el byte actual en la memoria y el valor deparam_3, y el resultado se escribe de nuevo en la misma ubicación de memoria.En resumen, la función
by ChatGPTFUN_00102752modifica un bloque de memoria aplicando una operación XOR con un valor dado (param_3) a cada byte dentro del rango de memoria especificado desdeparam_1hastaparam_1 + param_2. Este tipo de operación es común en tareas como la manipulación de datos para cifrado/descifrado o para la generación de patrones específicos en un bloque de datos.
Ahora imaginad que no sois muy dados a programar o simplemente estáis vagos de modo que volvemos a recurrir a ChatGPT con el promt «Haz un XOR 1 con javascript a la cadena: gmfzuihr^vr^o^drx^nod^shfiu|» a lo que responde:
function xorString(str) {
return Array.from(str).map(char => String.fromCharCode(char.charCodeAt(0) ^ 1)).join(»);
}console.log(xorString(‘gm
by ChatGPTfzuihr^vr^o^drx^nod^shfiu|’));
Copiamos el código y lo pegamos en un entorno online como por ejemplo playcode.io.

Este es un ejemplo simple, pero ¿percibís su potencial?
La imagen de portada de esta entrada ha sido generada con ChatGPT.
ThisIsLegal.com – Realistic Challenge 5

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
Analizando a la víctima
Echamos un vistazo a la web y lo único interesante que vemos es un buscador.
Miramos el código fuente y vemos una ruta interesante.
Ahora fijémonos en el menú productos. Pinchamos sobre cualquier producto y a continuación en la imagen para ampliarla, veremos el siguiente enlace.
Explotando la víctima
Vamos a ver si podemos explotar «i.php«. Probamos a obtener información sensible del servidor.
Probamos «http://www.thisislegal.com/nc/i.php?img=adm/login.pwd» y nos da error, seguramente por que está anexionando la extensión de la imagen, es decir, el script está interpretando esto:
Vamos a anularlo con un caracter nulo. Probamos y ahora si.
El password está en base64. Lo decodificamos online, nos logueamos y reto superado.
Links
¿El crackme de android más famoso del mundo?

Hace unos años cuando empecé a trastear con Android y animado por mi afición a la Ingeniería Inversa, decidí realizar una serie de crackmes. Los dos primeros pasaron algo desapercibidos, pero el Crackme nº3 tuvo una gran repercusión en el mundillo y, aunque no fue el primer crackme para Android ni mucho menos, si que fue uno de los más estudiados. Todos ellos fueron publicados a través de crackmes.de y el nº3 en cuestión el 6 de Noviembre de 2010. Os dejo una lista de unas cuantas webs donde aparece analizado para que veáis la repercusión que a mi parecer tuvo.
Soluciones al crackme
- http://securityxploded.com/android_reversing.php
- http://www.spageek.net/deuruss-android-crackme03/
- https://github.com/spageek/solutions-to-crackmes/commits/master
- https://www.mgp25.com/androidCrackme03/
- http://www.techpluto.com/how-to-crack-games-on-android/
- http://docslide.us/documents/club-hack-mag-dec-2010.html
- http://www.symbianize.com/archive/index.php/t-678834.html
- http://feeds.feedburner.com/nyoret
- http://crackmes.de/users/deurus/android_crackme03/solutions/diff/browse
- Android Reverse Engineering – A Kick Start (Indian First Digital Security Magazine)
- http://www.programlife.net/android-crackme3.html
- http://www.codexiu.cn/android/blog/36058/
- http://blog.btrisk.com/2014/04/AndroidReverseTersineMuhendislikSmali.html
Referencias al crackme
Links
ThisIsLegal.com – Realistic Challenge 2

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Introducción
Break into the site, find the file and remove it. Also leave no evidence that you was ever there so they wont realise until its too late!
Analizando la seguridad de la víctima
Pass: ‘ or 1=1–‘;
Solo nos queda borrar la lista de objetivos y nuestras huellas. Para ello borramos los siguientes archivos y reto superado.
Lista de objetivos: root/misc/targets
Logs: root/images/logs
Links
AperiSolve en tu Raspi

Acabo de montar AperiSolve en una Raspi que tenía por casa pensando que sería coser y cantar, pero me he encontrado con que el repositorio no estaba preparado para todas las distros Linux de forma estándar. El resultado lo he colgado en Github, de modo que para montarlo en vuestra propia Raspi solo tenéis que seguir estos pasos:
1. Clonar el repositorio git clone https://github.com/deurus/AperiSolve-Raspi3.git cd AperiSolve-Raspi3/AperiSolve 2. Construir los contenedores docker compose build docker compose up -d 3. Abrir la web http://<IP_RASPI>:5000
Si tenéis curiosidad de la adaptación que he tenido que hacer aquí están los pasos que he seguido:
1. Preparar el sistema
sudo apt update
sudo apt install -y git docker.io docker-compose
sudo usermod -aG docker $USER
newgrp docker
2. Clonar AperiSolve
git clone https://github.com/Zeecka/AperiSolve.git
cd AperiSolve
3. Crear la estructura de build para la imagen ARM/x86
nano docker-compose.yml
y pega este contenido:
FROM python:3.11-slim
RUN apt-get update && apt-get install -y \
zip \
p7zip-full \
binwalk \
foremost \
exiftool \
steghide \
ruby \
binutils \
pngcheck \
&& rm -rf /var/lib/apt/lists/*
COPY aperisolve/ /aperisolve/
RUN pip install --no-cache-dir -r /aperisolve/requirements.txt
WORKDIR /aperisolve
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "wsgi:app"]
4. Arreglar docker-compose.yml para ser válido y compatible
services:
web:
image: aperisolve-local
build: .
container_name: aperisolve-web
ports:
- "5000:5000"
depends_on:
- redis
- postgres
environment:
DB_URI: "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
worker:
image: aperisolve-local
container_name: aperisolve-worker
depends_on:
- redis
- postgres
environment:
DB_URI: "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
redis:
image: redis:7
container_name: aperisolve-redis
postgres:
image: postgres:16
container_name: aperisolve-postgres
environment:
POSTGRES_USER: aperiuser
POSTGRES_PASSWORD: aperipass
POSTGRES_DB: aperisolve
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
5. Modificar aperisolve/config.py
nano config.py
y pega este contenido:
from pathlib import Path
IMAGE_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".tiff"]
WORKER_FILES = ["binwalk", "foremost", "steghide", "zsteg"]
RESULT_FOLDER = Path(__file__).parent.resolve() / "results"
RESULT_FOLDER.mkdir(parents=True, exist_ok=True)
6. Modificación de aperisolve/app.py
Sustituir la línea: app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI")
por:
default_db = "postgresql://aperiuser:aperipass@postgres:5432/aperisolve"
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI", default_db)
7. Construir la imagen
docker build -t aperisolve-local .
8. Levantar los contenedores
docker compose down
docker compose up -d
9. Comprobar logs
docker logs aperisolve-web --tail=50
docker logs aperisolve-worker --tail=50
10. Acceder a la web
- Desde cualquier máquina de la red local: http://IP-DE-LA-MAQUINA:5000
- Desde la Raspi: http://localhost:5000
11. Limpieza (cuando necesites)
- Reiniciar contenedores:
docker compose restart
- Borrar resultados antiguos:
sudo rm -r aperisolve/results/*
Algoritmo de HEdit 2.1.11

Rebuscando entre todo el caos que puede llegar a ser mi disco duro, he encontrado una serie de programas que utilizaba antiguamente cuando empezó a interesarme el Cracking. Ya sabéis que no soy partidario de crackear programas comerciales pero hoy voy a hacer una excepción ya que la versión del programa es muy vieja (1997) e incluso podría considerarse abandonware.
Este ejercicio es ideal para los que están empezando ya que es fácil localizar donde está el algoritmo y éste es sumamente sencillo.
Algoritmo
Address Hex dump Command Comments
00402213 E8 78170000 CALL HEdit.00403990
........
004039C0 8BC1 MOV EAX,ECX
004039C2 99 CDQ
004039C3 33C2 XOR EAX,EDX
004039C5 2BC2 SUB EAX,EDX
004039C7 83E0 03 AND EAX,00000003
004039CA 33C2 XOR EAX,EDX
004039CC 2BC2 SUB EAX,EDX
004039CE 8A540C 04 MOV DL,BYTE PTR SS:[ECX+ESP+4] ;Coge el dígito i*3
004039D2 8A5C04 04 MOV BL,BYTE PTR SS:[EAX+ESP+4] ;Coge el dígito i
004039D6 8D4404 04 LEA EAX,[EAX+ESP+4] ;Guarda en memoria 12EE90
004039DA 32DA XOR BL,DL
004039DC 41 INC ECX ; i +=1
004039DD 81F9 00010000 CMP ECX,100 ;El bucle se repite 256 veces (0x100)
004039E3 8818 MOV BYTE PTR DS:[EAX],BL
004039E5 ^ 7C D9 JL SHORT HEdit.004039C0
004039E7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
004039EB 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039ED 7D 02 JGE SHORT HEdit.004039F1 ;Si es 0 se acabó
004039EF F7D8 NEG EAX
004039F1 3B8424 0C010000 CMP EAX,DWORD PTR SS:[ESP+10C] ;Comprobación de serial válido
004039F8 75 13 JNE SHORT HEdit.00403A0D ;Si no es igual bad boy
004039FA 85C0 TEST EAX,EAX ;Comprueba que el serial no sea 0
004039FC 74 0F JE SHORT HEdit.00403A0D ;Si es 0 se acabó
004039FE B8 01000000 MOV EAX,1
00403A03 5B POP EBX
00403A04 81C4 00010000 ADD ESP,100
00403A0A C2 0800 RETN 8
En resumen hace esto:
- Nombre introducido: deurus
- Convierte el nombre a mayúsculas
D E U R U S
44 45 55 52 55 53 (En Hexadecimal)
1) 55 xor 44 = 11
2) 53 xor 45 = 16
3) 00 xor 55 = 55
4) 00 xor 52 = 52
--------------- solo vale hasta aquí EAX(32 bits)
5) 00 xor 55 = 55
6) 00 xor 53 = 53
7) 00 xor 00 = 00
8) ...
HEX DEC
Serial = 52551611 = 1381307921
Como veis, realiza un bucle 256 veces pero como al final utiliza el registro EAX para hacer la comparación, solamente nos sirven las cuatro primeras operaciones. De hecho, no comprueba ni la longitud del nombre por lo que si introducimos un solo dígito como nombre, el serial será el valor ascii de ese dígito en decimal. La única comprobación que realiza es que el serial no sea 0.
Keygen
Os dejo una prueba de concepto en Javascript.
var nombre = "deurus";
nombre = nombre.toUpperCase();
var serial = "";
serial = serial + nombre.charCodeAt(3).toString(16) + nombre.charCodeAt(2).toString(16);
serial = serial + (nombre.charCodeAt(5) ^ nombre.charCodeAt(1)).toString(16);
serial = serial + (nombre.charCodeAt(2) ^ nombre.charCodeAt(0)).toString(16);
serial = "Nº Serie: " + parseInt(serial,16);
document.write(serial);
Enlaces
CanYouHack.it Mobile2 Challenge – Follow The Web (English)

Warning: This challenge is still active and therefore should not be resolved using this information.
Aviso: Este reto sigue en activo y por lo tanto no se debería resolver utilizando esta información.
Intro
Decompiling


http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=0
http://canyouhack.it/Content/Challenges/Mobile/2/submit.php?Token=68a571bcf7bc9f76d43bf931f413ab2c&&Attempts=1










































































































































