Blooper Tech Movie I – The Ring (La Señal)

Con The Ring inauguro una nueva sección llamada Blooper Tech Movie (BTM), algo así como pifias o tomas falsas tecnológicas en películas. Aunque no os lo creáis, los creadores del séptimo arte y sus asesores son humanos, y como tal se rigen por la ley del mínimo esfuerzo. En este BTM vamos a ver como una simple escena nos puede arruinar la excelente atmósfera de intriga que hasta ese momento se respiraba.

BTM

Transcurridos 70 minutos de película vemos que la protagonista está en una redacción buscando información sobre la maldita cinta de vídeo en un PC.

vlcsnap-2015-11-22-01h10m04s660

Hasta aquí todo correcto, pero instantes después vemos que realiza una búsqueda sobre «Moesko Islands» y cuando se abre el plano y podemos ver la barra de direcciones, en realidad vemos un archivo local situado en «C:\WIN98\Desktop\search.com\2_moesko_island_pt2.html«. A continuación la secuencia, se pueden ver los enlaces «locales» en el segundo 13 y 17.

vlcsnap-2015-11-22-01h10m52s727

Imagen 1 – «C:\WIN98\Desktop\search.com\2_moesko_island_pt2.html»

vlcsnap-2015-11-22-01h11m25s822

Imagen 2 – «C:\WIN98\Desktop\search.com\restoration.html»

Teniendo en cuenta que la película data del año 2002, me parece increíble que los productores no se lo curraran un poco más y registraran un dominio como «jdoesearch.com» y simularan que se realizan las búsquedas ONline y no OFFline como se están haciendo en realidad.

Quizá no tenían pensado mostrar la parte superior del navegador o simplemente pensaron que nadie se fijaría pero el caso es que para cualquiera que haya navegado por Internet más de 2 veces, si se fija en la barra de direcciones su expresión facial cambia a WTF!.

ring_sello

Enlaces


Introducción Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro
Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si
Cambio de extensión Imagen oculta Descifrando el mensaje Enlaces Cambio de extensión (paso opcional) Al descargar la imagen de la
Los retos de criptografía pueden ser muy variados como he dicho anteriormente. El secreto suele estar en saber a que

Retos reversing de Challengeland.co

Introducción

Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro uso y disfrute. Desgraciadamente ya no está en activo la web de retos de donde los saqué así que os los dejo en descargas.

Los cuatro primero están realizados en Dev-C++ 4.9.9.2 siendo de estilo consola de comandos. Los dos restantes compilados con MingWin32 GCC 3.x carecen de GUI y vamos, que no se han esmerado mucho en darles forma.

Level 1

No cuesta mucho dar con el código interesante mediante las referencias de texto. En Ollydbg clic derecho sobre el código y Search for > All referenced text strings.

004012E1   |.  8845 E8         MOV BYTE PTR SS:[EBP-18],AL                                    ; ||||
004012E4   |.  C70424 11304000 MOV DWORD PTR SS:[ESP],level1.00403011                         ; ||||ASCII "Input Serial: "
004012EB   |.  E8 C0050000     CALL <JMP.&msvcrt.printf>                                      ; |||\printf
004012F0   |.  8D45 C8         LEA EAX,[LOCAL.14]                                             ; |||
004012F3   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; |||
004012F7   |.  C70424 20304000 MOV DWORD PTR SS:[ESP],level1.00403020                         ; |||ASCII "%s"
004012FE   |.  E8 9D050000     CALL <JMP.&msvcrt.scanf>                                       ; ||\scanf
00401303   |.  8D45 D8         LEA EAX,[LOCAL.10]                                             ; ||
00401306   |.  8D55 C8         LEA EDX,[LOCAL.14]                                             ; ||
00401309   |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                                   ; ||
0040130D   |.  891424          MOV DWORD PTR SS:[ESP],EDX                                     ; ||level1.00403022
00401310   |.  E8 7B050000     CALL <JMP.&msvcrt.strcmp>                                      ; |\strcmp
00401315   |.  8945 C4         MOV [LOCAL.15],EAX                                             ; |
00401318   |.  837D C4 00      CMP [LOCAL.15],0                                               ; |
0040131C   |.  75 0E           JNZ SHORT level1.0040132C                                      ; |
0040131E   |.  C70424 23304000 MOV DWORD PTR SS:[ESP],level1.00403023                         ; |ASCII "Well done. \n"
00401325   |.  E8 86050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
0040132A   |.  EB 0C           JMP SHORT level1.00401338
0040132C   |>  C70424 30304000 MOV DWORD PTR SS:[ESP],level1.00403030                         ; |ASCII "Wrong. \n"
00401333   |.  E8 78050000     CALL <JMP.&msvcrt.printf>                                      ; \printf
00401338   |>  C70424 39304000 MOV DWORD PTR SS:[ESP],level1.00403039                         ; |ASCII "PAUSE"
0040133F   |.  E8 3C050000     CALL <JMP.&msvcrt.system>                                      ; \system
00401344   |.  B8 00000000     MOV EAX,0
00401349   |.  C9              LEAVE
0040134A   \.  C3              RETN

La madre del cordero está en la dirección 401310 que es donde se lleva a cabo la función de comparación strcmp.

756296A0 msvcrt.strcmp     8B5424 04         MOV EDX,DWORD PTR SS:[ESP+4]
756296A4                   8B4C24 08         MOV ECX,DWORD PTR SS:[ESP+8] 
756296A8                   F7C2 03000000     TEST EDX,3				; 0-3 = 4 bucles. Divide la comprobación en 4 bloques
756296AE                   75 3C             JNZ SHORT msvcrt.756296EC		; salta si hemos terminado los 4 bucles
756296B0                 > 8B02              MOV EAX,DWORD PTR DS:[EDX]		; coge 4 caracteres del serial (INICIO BUCLE)
756296B2                   3A01              CMP AL,BYTE PTR DS:[ECX]		; compara el 1º/5º/9º/13º dígito en función del bucle
756296B4                   75 2E             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296B6                   0AC0              OR AL,AL
756296B8                   74 26             JE SHORT msvcrt.756296E0
756296BA                   3A61 01           CMP AH,BYTE PTR DS:[ECX+1]		; compara el 2º/6º/10º/14º dígito en función del bucle
756296BD                   75 25             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296BF                   0AE4              OR AH,AH
756296C1                   74 1D             JE SHORT msvcrt.756296E0
756296C3                   C1E8 10           SHR EAX,10
756296C6                   3A41 02           CMP AL,BYTE PTR DS:[ECX+2]		; compara el 3º/7º/11º/15º dígito en función del bucle
756296C9                   75 19             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296CB                   0AC0              OR AL,AL
756296CD                   74 11             JE SHORT msvcrt.756296E0
756296CF                   3A61 03           CMP AH,BYTE PTR DS:[ECX+3]		; compara el 4º/8º/12º/16º dígito en función del bucle
756296D2                   75 10             JNZ SHORT msvcrt.756296E4		; salto a zona mala
756296D4                   83C1 04           ADD ECX,4
756296D7                   83C2 04           ADD EDX,4
756296DA                   0AE4              OR AH,AH
756296DC                 ^ 75 D2             JNZ SHORT msvcrt.756296B0		; Si no hemos terminado... 
756296DE                   8BFF              MOV EDI,EDI                         
756296E0                   33C0              XOR EAX,EAX			; EAX = 0 que es lo deseado
756296E2                   C3                RETN				; salimos de la función superando la comprobación
756296E3                   90                NOP							
756296E4                   1BC0              SBB EAX,EAX			; Zona mala
756296E6                   D1E0              SHL EAX,1
756296E8                   83C0 01           ADD EAX,1				; EAX = 1 implica bad boy
756296EB                   C3                RETN				; salimos de la función

Si atendemos al volcado vemos el serial bueno Kcgcv8LsmV3nizfJ.

0060FEF0  31 32 33 34 35 36 37 38 39 30 00 75 40 19 18 00  1234567890.u@.
0060FF00  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  Kcgcv8LsmV3nizfJ

Curiosamente, si introducimos el serial bueno el crackme no lo acepta. Fijándome en la comprobación veo que al introducir un serial de 16 caracteres inserta un carácter nulo (0x00) alterando el serial correcto y falseando la comprobación.

0060FEF0  4B 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  Kcgcv8LsmV3nizfJ
0060FF00  00 63 67 63 76 38 4C 73 6D 56 33 6E 69 7A 66 4A  .cgcv8LsmV3nizfJ

Ahora ya no podemos comprobarlo pero recuerdo que la web consideraba válido el serial Kcgcv8LsmV3nizfJ, por lo que considero lo anteriormente citado un bug o un intento de despiste del autor.

Level 2

Es exactamente igual que el anterior cambiando el serial por 6LPw3vDYja9KrT2V.

Level 3

La comprobación del serial es igual a las dos anteriores pero añade una función intermedia que suma 0xD a cada carácter de nuestro serial

00401355                 |.  A1 03304000     MOV EAX,DWORD PTR DS:[403003]                  ; ||
0040135A                 |.  8945 E8         MOV [LOCAL.6],EAX                              ; ||
0040135D                 |.  A1 07304000     MOV EAX,DWORD PTR DS:[403007]                  ; ||
00401362                 |.  8945 EC         MOV [LOCAL.5],EAX                              ; ||
00401365                 |.  A1 0B304000     MOV EAX,DWORD PTR DS:[40300B]                  ; ||
0040136A                 |.  8945 F0         MOV [LOCAL.4],EAX                              ; ||
0040136D                 |.  A1 0F304000     MOV EAX,DWORD PTR DS:[40300F]                  ; ||
00401372                 |.  8945 F4         MOV [LOCAL.3],EAX                              ; ||
00401375                 |.  C70424 13304000 MOV DWORD PTR SS:[ESP],level3.00403013         ; ||ASCII "Input Serial: "
0040137C                 |.  E8 CF050000     CALL <JMP.&msvcrt.printf>                      ; |\printf
00401381                 |.  8D45 D8         LEA EAX,[LOCAL.10]                             ; |
00401384                 |.  894424 04       MOV DWORD PTR SS:[ESP+4],EAX                   ; |
00401388                 |.  C70424 00304000 MOV DWORD PTR SS:[ESP],level3.00403000         ; |ASCII "%s"
0040138F                 |.  E8 AC050000     CALL <JMP.&msvcrt.scanf>                       ; \scanf
00401394                 |.  8D5D E8         LEA EBX,[LOCAL.6]
00401397                 |.  8D45 D8         LEA EAX,[LOCAL.10]
0040139A                 |.  890424          MOV DWORD PTR SS:[ESP],EAX
0040139D                 |.  E8 EEFEFFFF     CALL level3.00401290			    ; NUEVA FUNCIÓN SUMA
004013A2                 |.  895C24 04       MOV DWORD PTR SS:[ESP+4],EBX                   ; ||
004013A6                 |.  890424          MOV DWORD PTR SS:[ESP],EAX                     ; ||
004013A9                 |.  E8 82050000     CALL <JMP.&msvcrt.strcmp>                      ; |\strcmp
004013AE                 |.  8945 D4         MOV [LOCAL.11],EAX                             ; |
004013B1                 |.  837D D4 00      CMP [LOCAL.11],0                               ; |
004013B5                 |.  75 0E           JNZ SHORT level3.004013C5                      ; |
004013B7                 |.  C70424 22304000 MOV DWORD PTR SS:[ESP],level3.00403022         ; |ASCII "Well done."
004013BE                 |.  E8 8D050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013C3                 |.  EB 0C           JMP SHORT level3.004013D1
004013C5                 |>  C70424 2D304000 MOV DWORD PTR SS:[ESP],level3.0040302D         ; |ASCII "Wrong. \n"
004013CC                 |.  E8 7F050000     CALL <JMP.&msvcrt.printf>                      ; \printf
004013D1                 |>  C70424 36304000 MOV DWORD PTR SS:[ESP],level3.00403036         ; |ASCII "PAUSE"
004013D8                 |.  E8 43050000     CALL <JMP.&msvcrt.system>                      ; \system
004013DD                 |.  B8 00000000     MOV EAX,0
004013E2                 |.  8B5D FC         MOV EBX,[LOCAL.1]                              
004013E5                 |.  C9              LEAVE
004013E6                 \.  C3              RETN
--------
004012A4                 |> /8B45 08         /MOV EAX,[ARG.1]                               ; |
004012A7                 |. |890424          |MOV DWORD PTR SS:[ESP],EAX                    ; |
004012AA                 |. |E8 B1060000     |CALL <JMP.&msvcrt.strlen>                     ; \strlen
004012AF                 |. |3945 FC         |CMP [LOCAL.1],EAX
004012B2                 |. |73 1C           |JNB SHORT level3.004012D0
004012B4                 |. |8B45 08         |MOV EAX,[ARG.1]
004012B7                 |. |8B55 FC         |MOV EDX,[LOCAL.1]
004012BA                 |. |01C2            |ADD EDX,EAX
004012BC                 |. |8B45 08         |MOV EAX,[ARG.1]
004012BF                 |. |0345 FC         |ADD EAX,[LOCAL.1]
004012C2                 |. |0FB600          |MOVZX EAX,BYTE PTR DS:[EAX]
004012C5                 |. |04 0D           |ADD AL,0D					    ; char + 0xD
004012C7                 |. |8802            |MOV BYTE PTR DS:[EDX],AL
004012C9                 |. |8D45 FC         |LEA EAX,[LOCAL.1]
004012CC                 |. |FF00            |INC DWORD PTR DS:[EAX]
004012CE                 |.^\EB D4           \JMP SHORT level3.004012A4
--------
756296A0 msvcrt.strcmp     8B5424 04         MOV EDX,DWORD PTR SS:[ESP+4]
756296A4                   8B4C24 08         MOV ECX,DWORD PTR SS:[ESP+8]
756296A8                   F7C2 03000000     TEST EDX,3
756296AE                   75 3C             JNZ SHORT msvcrt.756296EC
756296B0                   8B02              MOV EAX,DWORD PTR DS:[EDX]
756296B2                   3A01              CMP AL,BYTE PTR DS:[ECX]
756296B4                   75 2E             JNZ SHORT msvcrt.756296E4
756296B6                   0AC0              OR AL,AL
756296B8                   74 26             JE SHORT msvcrt.756296E0
756296BA                   3A61 01           CMP AH,BYTE PTR DS:[ECX+1]
756296BD                   75 25             JNZ SHORT msvcrt.756296E4
756296BF                   0AE4              OR AH,AH
756296C1                   74 1D             JE SHORT msvcrt.756296E0
756296C3                   C1E8 10           SHR EAX,10
756296C6                   3A41 02           CMP AL,BYTE PTR DS:[ECX+2]
756296C9                   75 19             JNZ SHORT msvcrt.756296E4
756296CB                   0AC0              OR AL,AL
756296CD                   74 11             JE SHORT msvcrt.756296E0
756296CF                   3A61 03           CMP AH,BYTE PTR DS:[ECX+3]
756296D2                   75 10             JNZ SHORT msvcrt.756296E4
756296D4                   83C1 04           ADD ECX,4
756296D7                   83C2 04           ADD EDX,4
756296DA                   0AE4              OR AH,AH
756296DC                 ^ 75 D2             JNZ SHORT msvcrt.756296B0
756296DE                   8BFF              MOV EDI,EDI
756296E0                   33C0              XOR EAX,EAX
756296E2                   C3                RETN
756296E3                   90                NOP
756296E4                   1BC0              SBB EAX,EAX
756296E6                   D1E0              SHL EAX,1
756296E8                   83C0 01           ADD EAX,1
756296EB                   C3                RETN

En la comparación vemos que el serial bueno es AvrQQsXjDk25Jrh por lo que si restamos 0xD (13 en decimal) a cada carácter obtendremos el serial bueno.

0060FF10  41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68 00  AvrQQsXjDk25Jrh.

		  41 76 72 51 51 73 58 6A 44 6B 32 35 4A 72 68
	                                                      - D
		  34 69 65 44 44 66 4B 5D 37 5E 25 28 3D 65 5B
		  4  i  e  D  D  f  K  ]  7  ^  %  (  =  e  [
		  
		  Serial bueno: 4ieDDfK]7^%(=e[

Level 4

La comprobación del serial es igual que la anterior pero sustituyendo la función que sumaba un valor a cada dígito del serial por una que genera un hash con nuestro serial y después lo compara con otro hash almacenado en memoria. Si no nos viene a la mente el tipo de hash que puede ser PEiD ya nos avisaba de que efectivamente el crackme incorpora la función MD5.

La función MD5 hace tiempo que no se considera segura debido a la existencia de numerosos «diccionarios» de hashes que hacen que encontremos la solución en segundos. Yo he utilizado la web MD5 online pero existen muchas más.

0060FE5C   004013BF  RETURN to level4.004013BF from <JMP.&msvcrt.strcmp>
0060FE60   0060FEA0  ASCII "e807f1fcf82d132f9bb018ca6738a19f"
0060FE64   0060FEE0  ASCII "fe01d67a002dfa0f3ac084298142eccd"


e807f1fcf82d132f9bb018ca6738a19f == 1234567890
fe01d67a002dfa0f3ac084298142eccd == orange

Level 5

La carta de presentación de este crackme es la imagen que veis arriba. Al explorarlo unos minutos enseguida nos damos cuenta de que no realiza ninguna comprobación y que nos está haciendo perder el tiempo. Ahí es cuando empezamos a revisar el ejecutable más a fondo y enseguida encontramos la solución con nuestro amigo el editor hexadecimal.

the answer is AttachedString

Level 6

Misma carta de presentación que el anterior y misma ausencia de comprobación del serial. En esta ocasión echando un vistazo a los recursos encontramos la solución rápidamente.

Enlaces

Yoire PE Reversing Challenge (Crackme Very Hard)

Aviso: Este crackme forma parte de una serie de pruebas de Yoire.com que todavía está en activo. Lo ético si continuas leyendo este manual es que no utilices la respuesta para completar la prueba sin esfuerzo. 😉

Saltando el Anti-Debug

Abrimos el crackme con Ollydbg y nos salta una protección Anti-Debug.

Si nos fijamos en las «Text Strings» vemos que es la clásica isDebuggerPresent. Pinchamos en ella y vemos claramente el salto que debemos forzar, se encuentra en el offset 401015. Podemos invertir el salto o cambiarlo a JMP para que salte siempre.

Rutina de comprobación del serial

A simple vista vemos instrucciones como FILD y FIDIVR que trabajan con los registros FPU, por lo que tendremos que fijarnos en dichos registros.

Retomemos analizando la rutina de comprobación.

FLD DWORD PTR DS:[403080]    - Carga el entero "720300" en ST7
FSTP [LOCAL.1]               - Guarda "720300" en memoria (Local 1)
MOVSX EDX,BYTE PTR DS:[EAX]  - Coje nuestro primer dígito en ascii y lo carga en EDX
SUB EDX,30                   - Le resta 30 a EDX
PUSH EDX                     - Carga EDX en la pila
FILD DWORD PTR SS:[ESP]      - Carga el valor de EDX en ST0
POP EDX                      - Recupera el valor de la pila
FDIVR [LOCAL.1]              - Divide Local 1 entre nuestro dígito hex y lo guarda en ST0
FSTP [LOCAL.1]               - Guarda el resultado de ST0 en Local 1
INC EAX                      - Siguiente dígito
CMP BYTE PTR DS:[EAX],0      - Comprueba si quedan dígitos en nuestro serial
JNZ SHORT 05_crack.004010F4  - Bucle

Después de la rutina de comprobación simplemente comprueba el valor del resultado de la división con 1 y si es verdad serial válido.

Buscando un serial válido

Podríamos hacer fuerza bruta, pero en esta ocasión no es necesario ya que con la calculadora, boli y papel lo sacamos rápido.
720300 / 2 = 360150
360150 / 2 = 180075
180075 / 5 = 36015
36015  / 5 = 7203
7203   / 3 = 2401
2401   / 7 = 343
343    / 7 = 49
49     / 7 = 7
7      / 7 = 1

Por lo que un serial válido sería: 225537777

La rutina de comprobación del serial podría resumirse también así:

720300 MOD serial = 720300

Links


Warning: This challenge is still active and therefore should not be resolved using this information.  Aviso: Este reto sigue en
AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. En este pequeño CrackMe se nos
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Aquí tenemos un crackme fuera de lo común, más que nada por que está programado en Brainfuck, un lenguaje de

ThisIsLegal.com – Realistic Challenge 1

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

 Realistic Challenge 1: Your friend tried to purchase some software off a company. But after he paid they decided to increase it’s price by a large amount. They are now refusing to send it him. Get them back by getting their most expensive software a lot cheaper than they intended you to.
Lo que nos dice el enunciado del reto a groso modo es que debemos cambiar el precio del software antes de comprarlo.

Firebug

 Para resolver este reto basta con tener instalado el complemento para Firefox «Firebug«. Abrimos la web y echamos un vistazo con Firebug
Vemos un parámetro oculto que se llama «amount» y que tiene un valor de 100$. Basta con cambiarlo a 00,01$ y ya tenemos resuelto el reto.

Links

This little bunny CrackMe

AVISO: Debido a que este reto está en activo no publicaré a donde pertenece.

En este pequeño CrackMe se nos pide investigar como se genera la clave que resuelve el reto. No tiene formulario donde introducir usuario y clave, cuando lo ejecutamos simplemente aparece una NAG dándonos a entender que no lo conseguimos.

Lo primero que vemos es esto:

004010B8 | 53                       | push ebx                                |
004010B9 | 56                       | push esi                                |
004010BA | 57                       | push edi                                |
004010BB | 83 C4 F4                 | add esp,FFFFFFF4                        |
004010BE | C6 05 84 20 40 00 00     | mov byte ptr ds:[402084],0              | Dirección 402084 = 0
004010C5 | C7 44 24 08 28 00 00 00  | mov dword ptr ds:[esp+8],28             | 
004010CD | 54                       | push esp                                |
004010CE | 6A 01                    | push 1                                  |
004010D0 | 6A 00                    | push 0                                  |
004010D2 | 68 0C 20 40 00           | push exepuzz1.40200C                    | ;0040200C:"Software\\Caesum\\rev1"
004010D7 | 68 02 00 00 80           | push 80000002                           |
004010DC | E8 F4 00 00 00           | call <exepuzz1.RegOpenKeyExA>           | Distracción
004010E1 | 85 C0                    | test eax,eax                            |
004010E3 | 0F 85 C6 00 00 00        | jne exepuzz1.4011AF                     | Parchear este salto
004010E9 | 8D 44 24 08              | lea eax,dword ptr ds:[esp+8]            |
004010ED | 50                       | push eax                                |
004010EE | 68 84 20 40 00           | push exepuzz1.402084                    | Coge lo que haya en la dirección 402084
........

Lo primero que nos llama la atención es que en 4010BE pone el DUMP 402084 a cero. Lo corroboramos:

00402000: 04 20 40 00 63 6D 62 69 70 6F 66 00 53 6F 66 74 ; . @.cmbipof.Soft
00402010: 77 61 72 65 5C 43 61 65 73 75 6D 5C 72 65 76 31 ; ware\Caesum\rev1
00402020: 00 6B 65 79 00 74 65 6C 6C 20 6D 65 20 74 68 65 ; .key.tell me the
00402030: 20 61 6E 73 77 65 72 00 59 6F 75 72 20 70 61 73 ;  answer.Your pas
00402040: 73 20 69 73 20 00 42 6C 61 68 00 54 68 69 73 20 ; s is .Blah.This 
00402050: 6C 69 74 74 6C 65 20 62 75 6E 6E 79 20 77 65 6E ; little bunny wen
00402060: 74 20 68 6F 70 00 42 6C 61 68 00 42 6C 61 68 2C ; t hop.Blah.Blah,
00402070: 20 73 65 65 20 69 66 20 49 20 63 61 72 65 00 42 ;  see if I care.B
00402080: 6C 61 68 00 00 00 00 00 00 00 00 00 00 00 00 00 ; lah.............
                       ^
                       |
                       ----402084 (Ahora no hay nada)

Además para poder continuar la ejecución debemos parchear el salto JNE de la dirección 4010E3. Seguimos:

........
004010F3 | 8D 54 24 0C              | lea edx,dword ptr ds:[esp+C]            |
004010F7 | 52                       | push edx                                |
004010F8 | 6A 00                    | push 0                                  |
004010FA | 68 21 20 40 00           | push exepuzz1.402021                    | ;00402021:"key"
004010FF | 8B 4C 24 14              | mov ecx,dword ptr ds:[esp+14]           |
00401103 | 51                       | push ecx                                |
00401104 | E8 C6 00 00 00           | call <exepuzz1.RegQueryValueExA>        | Distracción
00401109 | 8B 04 24                 | mov eax,dword ptr ds:[esp]              |
0040110C | 50                       | push eax                                |
0040110D | E8 B7 00 00 00           | call <exepuzz1.RegCloseKey>             |
00401112 | 68 25 20 40 00           | push exepuzz1.402025                    | ;00402025:"tell me the answer"
00401117 | 68 84 20 40 00           | push exepuzz1.402084                    | Coge lo que haya en la dirección 402084
0040111C | E8 17 FF FF FF           | call exepuzz1.401038                    |
00401121 | 83 C4 08                 | add esp,8                               |
00401124 | 85 C0                    | test eax,eax                            |
00401126 | 74 72                    | je exepuzz1.40119A                      |
00401128 | 68 84 20 40 00           | push exepuzz1.402084                    |
0040112D | E8 CE FE FF FF           | call exepuzz1.401000                    |
00401132 | 59                       | pop ecx                                 |
00401133 | 8B F0                    | mov esi,eax                             |
00401135 | 33 DB                    | xor ebx,ebx                             |
00401137 | B9 84 20 40 00           | mov ecx,exepuzz1.402084                 |
0040113C | 3B F3                    | cmp esi,ebx                             |
0040113E | 7E 21                    | jle exepuzz1.401161                     |
00401140 | 0F BE 01                 | movsx eax,byte ptr ds:[ecx]             |>----BUCLE------
00401143 | 8B D0                    | mov edx,eax                             | EAX y EDX contienen el valor HEX del dígito que toque
00401145 | BF 1A 00 00 00           | mov edi,1A                              | EDI = 1A
0040114A | 43                       | inc ebx                                 | incremento el contador
0040114B | 8D 04 C2                 | lea eax,dword ptr ds:[edx+eax*8]        | EAX = Dígito+Dígito*8
0040114E | 8D 04 C2                 | lea eax,dword ptr ds:[edx+eax*8]        | EAX = Dígito+EAX*8
00401151 | 83 C0 3B                 | add eax,3B                              | EAX = EAX+3B
00401154 | 99                       | cdq                                     |
00401155 | F7 FF                    | idiv edi                                | EAX / EDI
00401157 | 80 C2 61                 | add dl,61                               | DL + 61
0040115A | 88 11                    | mov byte ptr ds:[ecx],dl                |
0040115C | 41                       | inc ecx                                 |
0040115D | 3B F3                    | cmp esi,ebx                             | ¿He terminado de recorrer la string?
0040115F | 7F DF                    | jg exepuzz1.401140                      |^-----BUCLE------
........

En 401117 vemos que intenta leer del DUMP en la dirección 402084 y a partir de ahí según lo que haya en el DUMP realiza una serie de operaciones con los datos y nos devuelve el resultado en forma de NAG.

Probamos varias cosas y nuestra teoría funciona pero, ¿cúal es la cadena de texto que debemos introducir?. A partir de aquí ya es un poco la intuición de cada uno, aunque la más lógica es «tell me the answer» que aparece justo antes del bucle.

El BUCLE

En resumen:

t 74  74*8+74 = 414*8+74 = 2114+3B = 214F MOD 1A = 19 + 61 = 72 (z)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
l 6C  6C*8+6C = 3CC*8+6C = 1ECC+3B = 1F07 MOD 1A =  D + 61 = 6E (n)
l 6C  6C*8+6C = 3CC*8+6C = 1ECC+3B = 1F07 MOD 1A =  D + 61 = 6E (n)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
m 6D  6D*8+6D = 3D5*8+6D = 1F15+3B = 1F50 MOD 1A =  8 + 61 = 69 (i)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
t 74  74*8+74 = 414*8+74 = 2114+3B = 214F MOD 1A = 19 + 61 = 72 (z)
h 68  68*8+68 = 3A8*8+68 = 1DA8+3B = 1DE3 MOD 1A =  7 + 61 = 68 (h)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w)
  20  20*8+20 = 120*8+20 = 0920+3B = 095B MOD 1A =  3 + 61 = 64 (d)
a 61  61*8+61 = 369*8+61 = 1BA9+3B = 1BE4 MOD 1A = 10 + 61 = 71 (q)
n 6E  6E*8+6E = 3DE*8+6E = 1F5E+3B = 1F9C MOD 1A =  6 + 61 = 67 (g)
s 73  73*8+73 = 40B*8+73 = 20CB+3B = 2106 MOD 1A =  4 + 61 = 65 (e)
w 77  77*8+77 = 42F*8+77 = 21EF+3B = 222A MOD 1A =  A + 61 = 6B (k)
e 65  65*8+65 = 38D*8+65 = 1CCD+3B = 1D08 MOD 1A = 16 + 61 = 77 (w) 
r 72  72*8+72 = 402*8+72 = 2082+3B = 20BD MOD 1A =  9 + 61 = 6A (j)

zwnndiwdzhwdqdekwj

La cadena de texto resultante ¿sera la correcta?

Retos de encriptación XOR de Yoire

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

El cifrado XOR es uno de los algoritmos más utilizados en el mundillo de la encriptación. Aunque por sí solo no es seguro, suele formar parte de cifrados más complejos e incluso si sois aficionados a los crackmes os habréis dado cuenta de que raro es el crackme que no lo utiliza.

Hoy vamos a hacer un recorrido sobre los retos de encriptación que nos propone yoire.com, que aunque son muy sencillos, nos proporcionan una estupenda base para iniciarnos en este tipo de retos.

/challenges/crypt/xor/0_chall_very_easy

En este primer reto, el autor te da directamente la solución, ya que, nos da un texto cifrado y nos dice que está cifrado con la clave 10. Lo que el autor no indica es que la clave es hexadecimal, mas adelante ya aprendereis a fijaros en esos detalles.

Texto cifrado: uqci0t~7d0ie0dxy~{

Clave: 10

challenges_crypt_xor_0_chall_very_easy

/challenges/crypt/xor/1_chall_easy

Esta vez disponemos de un texto cifrado pero sin pistas. Si nos fijamos en el código fuente veremos que la clave utilizada esta vez es 20 y decimal.

<?php
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Easy"));
print Challenges::header();
?>
Convierte la solución que está cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

$solution_xored="m{a4s{`4}`5";
$key           = sprintf("%2x",20);
$solution      = Crypt::XorData($solution_xored,$key);

print "La solución es: ".$solution_xored;

print "<br><br>";
print Challenges::solutionBox();
print Challenges::checkSolution(Crypt::XorData($solution_xored,$key));
?>

challenges_crypt_xor_1_chall_easy

/challenges/crypt/xor/2_chall_mid

En esta ocasión debemos ojear el código fuente para averiguar como solucionar el reto. En esta ocasión y como de lo que se trata es de aprender, este lo dejaré sin solucionar.

<?php 
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Mid"));
print Challenges::header();
?>
Convierte la solución que está codificada y cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

foreach (
        preg_split("/\./","2.4.10.71.3698") 
        as $something
        ) 

$value=pow($something,2);

$key            = dechex($value);
$solution_xored = base64_decode("ucSnos+lo8Oqtw==");
$solution       = Crypt::XorData($solution_xored,$key);

print Challenges::solutionBox();
print Challenges::checkSolution(Crypt::XorData($solution_xored,$key));
?>
<a href="<?=$_SERVER["PHP_SELF"]?>?showSource">Ver código fuente</a>

<?php
if(Common::getString("showSource")!==false) {
    print "<hr>";
    highlight_file(__FILE__);
}
print Website::footer();
?>
  • Lo primero es mediante un compilador online de PHP, obtener la variable $key.
  • Decodificar la clave xoreada «ucSnos+lo8Oqtw==«.
  • Solución = base64_decode(«ucSnos+lo8Oqtw==») XOR $key

Venga que casi lo tienes.

/challenges/crypt/xor/3_chall_average

En este reto nos indican que el código fuente está encriptado. Cuando nos enfrentamos a XOR en texto grandes y teniendo un indicio de lo que puede contener el código desencriptado es sencillo encontrar lo que buscamos. En este caso en concreto podemos intuir que seguramente el texto contenga la palabra «php«, una vez llegamos a esa conclusión la solución llega sola. Este método no deja de ser un ataque por fuerza bruta.

Código encriptado

lo 8 p]Z9>3<%45xr~~~~~~3?"5~ 8 ryk]Z "9>$p52#9$5jj85145"x1""1)xr$9

lt;5rmnr85pp81<$p81<<5>75#jj85145"xyk]Zon]Z1"535p!%5p5$5p81p#94?p396"14?~~~p%===~~~p$5>4"±#p!%5p1&5"97%1"p3£=?p 1"1p?2$5>5"p<1p"5# %5#$1p1p5#$5p"5$?j]Zl2"nl2"n]Zlo 8 ]Z]Zt;5)ppppppppppppmpre`rk]Zt=5pppppppppppppmp69<575$3?>$5>$#xyk]Zt=5(?"54pppppppmp") $jj?"1$1xt=5|t;5)yk]Z]Z "9>$p81<<5>75#jj#?<%$9?>?(xyk]Z "9>$p81<<5>75#jj3853;?<%$9?>xr3````aryk]Zon]Zl1p8"56mrlomtrr onolom%"<5>3?45x") $jj?"1$1xr#8?'?%"35r|t;5)yyonrn5"p3£497?p6%5>$5l1n]Z]Zlo 8 ]Z96x?==?>jj75$$"9>7x") $jj?"1$1xr#8?'?%"35r|t;5)yyqmm61<#5yp+]ZY "9>$prl8"nrk]ZY "9>$pt=5(?"54k]Z-]Z "9>$p52#9$5jj6??$5"xyk]Zon]Z

Código desencriptado

challenges_crypt_xor_3_chall_average

/challenges/crypt/xor/4_chall_hard

En este último reto nos aparece un mensaje que nos dice «La solución es: 7b1a4147100a155a0f45574e0f58«. Nos fijamos en el código fuente y vemos que en la encriptación interviene una cookie llamada «PHPSESSID«.

Código fuente

<?php 
include("../../../core.php");
print Website::header(array("title"=>"The XOR Chall - Hard"));
print Challenges::header();
?>
Convierte la solución que está codificada y cifrada con una clave XOR para obtener la respuesta a este reto:
<br><br>
<?php

$sessid             = isset($_COOKIE["PHPSESSID"])?$_COOKIE["PHPSESSID"]:">hi!|m¬_ö_Ó_;m'`ñ·$\"<";
$key                = Encoder::asc2hex($sessid);
$hiddenSolution     = file_get_contents(Config::$challsHiddenData."crypt_xor_average.solution");
$hex_xored_solution = Encoder::data2hex(Crypt::XorData($hiddenSolution,$key));

print "La solucion es: ".$hex_xored_solution;

print "<br><br>";

print Challenges::solutionBox();
print Challenges::checkSolution($hiddenSolution);
?>
<a href="<?=$_SERVER["PHP_SELF"]?>?showSource">Ver código fuente</a>

<?php
if(Common::getString("showSource")!==false) {
    print "<hr>";
    highlight_file(__FILE__);
}
print Website::footer();
?>

Desde Firefox vamos a usar una extensión muy interesante llamada Advanced Cookie Manager que nos permitirá visualizar y modificar dicha cookie.

challenges_crypt_xor_4_chall_hard_02

Una particularidad de la encriptación XOR es que si realizamos «algo XOR 0 == algo«, por lo que un ataque típico sería anular la cookie. La modificamos poniendo como valor 0 y guardamos. Recargamos la web con F5 y ahora nos fijamos que el valor de la solución ha cambiado a «7e5f4410435f1058514254100a19«. Finalmente y teniendo en cuenta que el texto que tenemos es hexadecimal, hacemos fuerza bruta marcando la opción Output First y clickamos en Search.

crypt_xor_4_chall_hard_2

En el mismo directorio donde tenemos el programa se genera un archivo llamado «XOR_enumeration.txt«, que contiene todos los resultados, echamos un vistazo y hemos tenido suerte.

crypt_xor_4_chall_hard_3

Enlaces

Canyouhack.it – Crack Challenge 4 (Brain Fuck Me)

Aquí tenemos un crackme fuera de lo común, más que nada por que está programado en Brainfuck, un lenguaje de programación esotérico bastante complejo.

[-]>[-]<>++++++++[<++++++++++>-]<.+++++++++++++++++.>+++[<++++++>-]<..++++.-
-------.+++.--------------.>++++++[<------>-]<-.>+++++[<------>-]<-.,>,>,>,>
>>>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++>>>>+++++++++++++++++++++++++++++++++++++++++
+++++++++++>>>>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++>>>>++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<<
<<<<<<<<<<<<<<<<[>>>>>>>-<<<<<<<-]>>>>>>><<+>>[[-]++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.<]<[>]<<<<<[>>>>>>>>>>-<<<<<<<<
<<-]>>>>>>>>>><<+>>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++.<]<[>]<<<<<<<<[>>>>>>>>>>>>>-<<<<<<<<<<<<<-]>>>>>>>>>>>>><<+>>[
[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.<]<[>]<<<<<<<<<<<[>>>>>>>>>>>>>>>>-<<<<<<<<<<<<<<<<-]>>>>>>>>>>>>>>>><<+>>[
[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++.<]<[>]>>>[-]>[-]<+++++++++++++.---.>+++++++[<++++++++++++>-]<.>+++++++[<
--------->-]<+.>+++++[<++++++++>-]<+.>++++[<+++++++>-]<+.>+++++++[<---------
->-]<.>++++++++[<+++++++++>-]<+.+++++++++++.>+++++++[<----------->-]<.>+++++
++[<+++++++++++>-]<-.>+++++++[<------------>-]<+.>++++++++[<+++++++++++>-]<-
.-----.---------.+++++++++++..---------------.+++++++++.>++++++[<-----------
-->-]<.+++++++.>+++++[<++++++>-]<+.-----.++++++++.+++.>++++++[<------>-]<-.-
------.>++++++++[<++++++++++>-]<-.+++.>+++++++++[<--------->-]<-.+++++++.>++
+++[<++++++>-]<+.-----.+++++++++++.>++++++[<------>-]<-.-------.>++++++++[<+
+++++++++>-]<-.+++.>+++++++++[<--------->-]<-.+++++++.>+++++[<+++++>-]<+.+++
+++++.+++.>++++++[<------>-]<-.+++++++...--------------.>++++++++[<+++++++++
++>-]<+.----------.++++++.>+++++++[<------------>-]<-.>++++++++[<+++++++++>-
]<.-------.>+++[<+++++++>-]<.-----------------.>+++++++[<---------->-]<+.>++
+++++[<++++++++++>-]<.-----.++++++++.+++.-------.-.>++++++[<--------->-]<.--
------------.>+++++[<++++++++>-]<+.>++++[<+++++++>-]<+.>+++++++[<---------->
-]<.>+++++++[<++++++++++++>-]<.------------.---.+++++++++++++.-------------.
>+++++++[<---------->-]<+.>++++++++[<+++++++++>-]<+.++++++++++.>+++++++[<---
--------->-]<+.>++++++[<+++++++++++++>-]<.+.+++++.------------.+.+++++.-----
--.>++++++[<---------->-]<+.------------.>++++++++[<+++++++++++>-]<+.-------
---.++++++.>+++++++[<------------>-]<-.>++++++++[<+++++++++>-]<.-------.>+++
[<+++++++>-]<.-----------------.>+++++++[<---------->-]<+.>++++++++[<+++++++
++++>-]<-.--------------.+++++.>++++++[<------------->-]<.+.

La solución que he encontrado yo, es convertir el código brainfuck a algo más amigable y depurarlo hasta encontrar la solución. La conversión la he realizado con VBBrainFNET y luego la depuración con Visual Studio. El crackme te pide una clave de cuatro cifras para darte la solución, pero si no quieres volverte loco puedes amañar los bucles para encontrar la solución.

¡SUERTE!

Enlaces