TDC’s Remove the NAG – Parche

Intro

Es un crackme realizado en ensamblador y en el que el objetivo es remover la NAG de la forma más limpia posible.

Analizando a la víctima

Abrimos el crackme con Olly y ya a simple vista vemos los mensajes de la Nag y parte del código interesante. Si necesitaramos localizar la Nag podemos mirar en las intermodular calls las típicas subrutinas, en este caso se ve claramente  a MessageBoxA, bastaría con poner un breakpoint para localizar quien llama.

Aquí vemos la implicación de MessageBoxA.

004010A7     |> \6A 40                    PUSH 40                                         ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004010A9     |.  68 61304000              PUSH Nag1.00403061                              ; |Title = "[NAG] Please register this software!"
004010AE     |.  68 86304000              PUSH Nag1.00403086                              ; |Text = "[BULLSHIT] Please register this software for support and you'll receive the full version!"
004010B3     |.  FF75 08                  PUSH [ARG.1]                                    ; |hOwner = 7FFDF000
004010B6     |.  E8 49010000              CALL <JMP.&user32.MessageBoxA>                  ; \MessageBoxA
........
00401137     |.  6A 40                    PUSH 40                                         ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401139     |.  68 6E324000              PUSH Nag1.0040326E                              ; |Title = "Thank you!"
0040113E     |.  68 79324000              PUSH Nag1.00403279                              ; |Text = "Thank you for registering this software!"
00401143     |.  FF75 08                  PUSH [ARG.1]                                    ; |hOwner = 7FFDF000
00401146     |.  E8 B9000000              CALL <JMP.&user32.MessageBoxA>                  ; \MessageBoxA
........
00401155     |.  6A 40                    PUSH 40                                         ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401157     |.  68 E0304000              PUSH Nag1.004030E0                              ; |Title = "About"
0040115C     |.  68 E6304000              PUSH Nag1.004030E6                              ; |Text = "Remove the NAG by TDC\r\n\n..: Coded by\t: TDC\t\t\t:..\t\r\n..: Also known as\t: The Dutch Cracker\t:..\t\r\n..: Protection\t: Custom\t\t\t:..\t\r\n..: Contact info\t: tdc123@gmail.com\t:..\t\r\n..: Release date\t: 09-08-2005\t\t:..\t"...
00401161     |.  FF75 08                  PUSH [ARG.1]                                    ; |hOwner = 7FFDF000
00401164     |.  E8 9B000000              CALL <JMP.&user32.MessageBoxA>                  ; \MessageBoxA

 Un poco encima vemos la función SetDlgItemTextA, que nos mostrará el mensaje de que hemos parcheado correctamente.

dlgitem

00401106     |> \68 21304000              PUSH Nag1.00403021                              ; /Text = "Dirty crack! Nag removed not registered!"
0040110B     |.  6A 73                    PUSH 73                                         ; |ControlID = 73 (115.)
0040110D     |.  FF75 08                  PUSH [ARG.1]                                    ; |hWnd = 7FFDF000
00401110     |.  E8 FB000000              CALL <JMP.&user32.SetDlgItemTextA>              ; \SetDlgItemTextA
00401115     |.  EB 36                    JMP SHORT Nag1.0040114D
00401117     |>  68 10304000              PUSH Nag1.00403010                              ; /Text = "Nag not removed!"
0040111C     |.  6A 73                    PUSH 73                                         ; |ControlID = 73 (115.)
0040111E     |.  FF75 08                  PUSH [ARG.1]                                    ; |hWnd = 7FFDF000
00401121     |.  E8 EA000000              CALL <JMP.&user32.SetDlgItemTextA>              ; \SetDlgItemTextA
00401126     |.  EB 25                    JMP SHORT Nag1.0040114D
00401128     |>  68 4A304000              PUSH Nag1.0040304A                              ; /Text = "Clean crack! Good Job!"
0040112D     |.  6A 73                    PUSH 73                                         ; |ControlID = 73 (115.)
0040112F     |.  FF75 08                  PUSH [ARG.1]                                    ; |hWnd = 7FFDF000
00401132     |.  E8 D9000000              CALL <JMP.&user32.SetDlgItemTextA>              ; \SetDlgItemTextA

Encima de SetDlgItemTextA vemos el código que analiza si la Nag tiene que aparecer.

004010E6     |.  E8 C4000000              CALL Nag1.004011AF                              ;  ; Llamada interesante a analizar
004010EB     |.  803D B0324000 03         CMP BYTE PTR DS:[4032B0],3
004010F2     |.  74 12                    JE SHORT Nag1.00401106                          ;  ; Si de la llamada volvemos con un 3 -> Parcheo chapuza
004010F4     |.  803D B0324000 02         CMP BYTE PTR DS:[4032B0],2
004010FB     |.  74 1A                    JE SHORT Nag1.00401117                          ;  ; Si de la llamada volvemos con un 2 -> Sin parchear
004010FD     |.  803D B0324000 01         CMP BYTE PTR DS:[4032B0],1
00401104     |.  74 22                    JE SHORT Nag1.00401128                          ;  ; Si de la llamada volvemos con un 1 -> Buen trabajo Joe!
........
004011AF     /$  68 A2324000              PUSH Nag1.004032A2                              ; /String2 = "Value1"
004011B4     |.  68 A9324000              PUSH Nag1.004032A9                              ; |String1 = "Value2"
004011B9     |.  E8 64000000              CALL <JMP.&kernel32.lstrcmpA>                   ; \lstrcmpA
004011BE     |.  50                       PUSH EAX                                        ;  kernel32.BaseThreadInitThunk
004011BF     |.  85C0                     TEST EAX,EAX                                    ;  kernel32.BaseThreadInitThunk
004011C1     |.  75 10                    JNZ SHORT Nag1.004011D3
004011C3     |.  33C0                     XOR EAX,EAX                                     ;  kernel32.BaseThreadInitThunk
004011C5     |.  58                       POP EAX                                         ;  kernel32.75CDEE1C
004011C6     |.  85C0                     TEST EAX,EAX                                    ;  kernel32.BaseThreadInitThunk
004011C8     |.  74 15                    JE SHORT Nag1.004011DF
004011CA     |.  C605 B0324000 03         MOV BYTE PTR DS:[4032B0],3
004011D1     |.  EB 17                    JMP SHORT Nag1.004011EA
004011D3     |>  58                       POP EAX                                         ;  kernel32.75CDEE1C
004011D4     |.  33C0                     XOR EAX,EAX                                     ;  kernel32.BaseThreadInitThunk
004011D6     |.  C605 B0324000 02         MOV BYTE PTR DS:[4032B0],2
004011DD     |.  EB 0B                    JMP SHORT Nag1.004011EA
004011DF     |>  33C0                     XOR EAX,EAX                                     ;  kernel32.BaseThreadInitThunk
004011E1     |.  C605 B0324000 01         MOV BYTE PTR DS:[4032B0],1
004011E8     |.  EB 00                    JMP SHORT Nag1.004011EA
004011EA     \>  C3                       RETN

 Vemos dentro del Call 4011AF que Compara si Value1 = Value2 y dependiendo de esa comparación guarda en memoria (4032B0), los valores 1, 2 ó 3.

Basta con modificar en un editor hexadecimal la parabra «Value2» por «Value1» y ya tenemos el problema resuelto.

09-09-2014 11-04-03

09-09-2014 11-04-34

09-09-2014 11-05-26

Al pulsar Re-Check

09-09-2014 11-06-01

Notas finales

Se podía haber parcheado un montón de código para obtener el mismo resultado pero fijándonos en el código lo hemos conseguido parcheando un solo byte. Recuerda, cuando halla que parchear, cuantos menos bytes mejor.

 Links


While Crackmes.de returns, I leave a couple of files for practice. Mientras vuelve Crackmes.de, os dejo un par de archivos para practicar.
Aquí os dejo un video tutorial. El crackme lo podeis encontrar en crackmes.de.
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en

Retos stego 1-4 de Challengeland.co

Introducción

Hoy vamos a enfrentarnos a cuatro retos de esteganografía relativamente sencillos, y digo relativamente, debido a que hay tantas formas de esconder información en un archivo, ya sea imagen, vídeo o sonido, que afrontarlos suele ser desesperante. Las cuatro imágenes son aparentemente las mismas que la que se ve en portada.

Una buena práctica cuando te enfrentas a retos stego de tipo imagen es realizar una búsqueda inversa. Una búsqueda inversa consiste en buscar la imagen original mediante buscadores especializados como TinEye o Google. Si conseguimos la imagen original podemos resolver el reto simplemente comparando o nos puede dar una idea del tipo de modificación por su diferencia de tamaño, colores, degradados, etc.

Stego 1

Descargamos la imagen del reto. Se trata de una imagen JPEG de 526×263 y 76.6 KB (78445 bytes). Su hash SHA1 es «89aed5bbc3542bf5c60c4c318fe99cb1489f267a«

Realizamos una búsqueda inversa de la imagen y encontramos sin dificultad la imagen original mediante TinEye.

18-06-2016 07-27-02

Características de la imagen original:

  • Resolución: 526×263
  • Tamaño: 78447 bytes (76.6 KB)
  • Hash SHA1: 8924676317077fc07c252ddeec04bd2a0ecfdda4

Por lo que vemos ha cambiado el tamaño de 78447 bytes a 78445 bytes y su hash SHA1 tampoco coincide obviamente, lo que nos confirma que ha sufrido alguna modificación. Echando un vistazo con un editor hexadecimal te puedes volver loco por lo que vamos a realizar una comparación mediante la herramienta online DiffNow.

18-06-2016 07-40-51

Al realizar la comparación sale a relucir lo que buscamos. La clave es una simple cadena de texto.

Stego 2

Lo primero es realizar de nuevo la comparación.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen2.jpeg116386 bytes7641e3906f795c137269cefef29f30fcb9cb1b07

Como vemos, la imagen ha aumentado significativamente, de 76,6 KB a 113 KB. Cuando el aumento de tamaño llama la atención normalmente tenemos otro archivo insertado. Lo primero que suelo hacer yo es fijarme si ha sido modificado el final del archivo con un editor hexadecimal. Los bytes de cola de un archivo jpg/jpeg son FFD9 y en este caso no vemos modificación alguna al final del archivo. Si el archivo no está al final requiere realizar una búsqueda más exhaustiva. Para estos casos tengo una herramienta de creación propia que se llama Ancillary y que sirve para buscar cierto tipo de archivos dentro de otros como imágenes, documentos de Office, Open Office, pdf, etc. Ancillary encuentra otro jpg que es el que le daba el peso extra y que vemos a continuación. La clave es el título de la película (ojo a las mayúsculas/minúsculas).

image2_thumb

Stego 3

El tercer reto parece que tiene algún error debido a que el archivo coincide completamente con el original. Pienso que se ha subido la imagen original por error. Se lo he comunicado al admin del dominio y si algún día obtengo respuesta actualizaré la entrada.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen3.jpeg78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4

Actualización 21/08/2016

Al parecer, la solución de este reto es llegar a la conclusión de que la imagen no está modificada. La respuesta del Administrador de la web así lo confirma.

desingsecurity [at] gmail [dot] com – Sorry about the delay, is precisely what is intended with that challenge, they can determine if the image is changed or not , the challenge was solved you . We’ll be equal way improving this point.

Greetings and Thanks

Stego 4

Lo primero es realizar de nuevo la comparación.

ImagenTamañoSHA1
Original78447 bytes8924676317077fc07c252ddeec04bd2a0ecfdda4
imagen4.jpeg93174 bytesa6329ea4562ef997e5afd067f3b53bdab4665851

Al igual que en el caso dos el tamaño ha aumentado significativamente de modo que miramos al final del archivo y esta vez si vemos que hay insertado unos bytes tras el final del jpg (recordemos FFD9)

18-06-2016 07-10-40

El archivo tiene pinta de ser una hoja de cálculo de Open Office o Libre Office según indica la palabra «spreadsheet«. Lo abrimos con Excel y tras analizar la maraña de datos enseguida vemos una clave que llama la atención.

  • Challengeland (El dominio ya no existe) [Archive]

Herramientas utilizadas

Crypto – Vodka

Hemos interceptado un mensaje secreto, pero ninguno de nuestros traductores lo sabe interpretar, ¿sabrías interpretarlo tú? Lo único que hemos encontrado es esto en un foro: шжзклмнпфъ = 1234567890

Mensaje secreto: нж, фн, фф, шън, нф, шшъ, шжз, мф, шъп, фл, пк, шъш, шшм, шшк, шъл, шшл, фл, шъш, шшл, фл, шшн, шшъ, фл, шъм, шшн, шъш, шъз, шшш, фл, пж, шшн, шшл, шшш, шжл

Solución

Parece que el mensaje secreto está encriptado utilizando un alfabeto cifrado que corresponde a números. Según la clave proporcionada (шжзклмнпфъ = 1234567890), cada letra del alfabeto cirílico se sustituye por un número.

Primero, descompondremos la clave dada:
ш = 1
ж = 2
з = 3
к = 4
л = 5
м = 6
н = 7
п = 8
ф = 9
ъ = 0

Ahora, aplicamos esta clave al mensaje secreto:

нж, фн, фф, шън, нф, шшъ, шжз, мф, шъп, фл, пк, шъш, шшм, шшк, шъл, шшл, фл, шъш, шшл, фл, шшн, шшъ, фл, шъм, шшн, шъш, шъз, шшш, фл, пж, шшн, шшл, шшш, шжл

Sustituyendo cada letra según la clave:

нж = 72
фн = 97
фф = 99
шън = 107
нф = 79
шшъ = 110
шжз = 123
мф = 69
шъп = 108
фл = 95
пк = 84
шъш = 101
шшм = 116
шшк = 114
шъл = 105
шшл = 115
фл = 95
шъш = 101
шшл = 115
фл = 95
шшн = 117
шшъ = 110
фл = 95
шъм = 106
шшн = 117
шъш = 101
шъз = 130
шшш = 111
фл = 95
пж = 82
шшн = 117
шшл = 115
шшш = 111
шжл = 125

El mensaje traducido a números es:

72, 97, 99, 107, 79, 110, 123, 69, 108, 95, 84, 101, 116, 114, 105, 115, 95, 101, 115, 95, 117, 110, 95, 106, 117, 101, 130, 111, 95, 82, 117, 115, 111, 125

Este parece ser un mensaje cifrado en números. La secuencia de números se puede interpretar de varias maneras (como ASCII, coordenadas, etc.). Si asumimos que es un texto codificado en ASCII:

Convertimos cada número a su correspondiente carácter ASCII:

72 = H
97 = a
99 = c
107 = k
79 = O
110 = n
123 = {
69 = E
108 = l
95 = _
84 = T
101 = e
116 = t
114 = r
105 = i
115 = s
95 = _
101 = e
115 = s
95 = _
117 = u
110 = n
95 = _
106 = j
117 = u
101 = e
130 = ?
111 = o
95 = _
82 = R
117 = u
115 = s
111 = o
125 = }

Juntando todo:

HackOn{El_Tetris_e_s_u_n_j_u_e?o_Ruso}

La parte «{El_Tetris_e_s_u_n_j_u_e?o_Ruso}» parece un mensaje en español. Probablemente deba ser leído como: HackOn{El_Tetris_es_un_juego_Ruso}

Así, el mensaje secreto es: HackOn{El_Tetris_es_un_juego_Ruso}.