CanYouHack.it Crack6 Challenge – Lights Out (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

This crackme is for the crack challenge 6 of canyouhack.it.

In this crackme the goal is to turn on all the lights. Note that a light off to the next, so if we interrupt this, we win.

Tools

Exeinfo (For crackme info)

Delphi Decompiler (For decompile)

 OllyDbg (For debug)

Decompiling

With Delphi Decompiler we can found easy the buttons and his offsets.
Go to the offset 401A64 in OllyDbg and analyze the code.
We view two jumps, one turn ON the light and the other Turn OFF the next light. Patching the call from offset 401A8B we get the serial.

Links


st2 arcade
He de iniciar esta entrada diciendo que la segunda temporada de Stranger Things es sencillamente genial. Son 9 horas intensas
Karpoff.es Hace unos días intenté contactar con Karpoff ya que fué una inspiración para mi y muchos otros, lo conseguí
Introducción La película "Contact", estrenada en 1997 y dirigida por Robert Zemeckis, es una adaptación de la novela homónima de
Introducción Funcionamiento de RSA OllyDbg Calculando un serial válido Ejemplo operacional Keygen Links Introducción Empezamos con lo que espero que

Blooper Tech Movie V – Algo huele a podrido en Hawkins

st2 arcade

He de iniciar esta entrada diciendo que la segunda temporada de Stranger Things es sencillamente genial. Son 9 horas intensas que no dejan indiferente a nadie y además en el capítulo 8 nos han dejado una de esas perlas informáticas que tanto nos gustan.

La escena la protagoniza Bob Newby, un buen hombre amante de la electrónica de aquella época que trabaja en RadioShack y transcurre en el laboratorio secreto de Hawkins. En un momento dado, Bob propone «saltarse» la seguridad del laboratorio y para ello se traslada al sótano donde se encuentran los «servidores».

El PC de la época

Para comprender esta escena hay que situarse temporalmente. Estamos hablando de los años 80, en concreto la escena transcurre en 1984 y los equipos de los que dispone el laboratorio son unos maravillosos IBM. No se llega a apreciar bien el modelo de IBM utilizado pero teniendo en cuenta que el monitor que aparece es un terminal IBM 3180, la búsqueda se reduce a los sistemas compatibles S/36, S/38, AS/400, 5294 ó 5394.

IBM 3180

IBM 3180 (https://www.argecy.com/3180)

Cracking BASIC or BASIC Cracking?

La escena plantea un ataque de fuerza bruta a un código de 4 dígitos como se puede observar en la imagen a continuación. Esto puede parecer una chorrada hoy día pero podía suponer un pequeño reto para un micro de 8 bits.

Cracking Basic or Basic Cracking?

Cracking Basic or Basic Cracking?

A simple vista se aprecian una serie de bucles recursivos, una llamada a una función y una sentencia condicional. Desconozco si la sintaxis del lenguaje es la correcta pero mucho me temo que es más bien una mezcla de BASIC y pseudocódigo. Pero lo que más me ha llamado la atención sin duda es que la palabra THEN parece que se sale del monitor como si estuviera realizado en post-producción. Os invito a que ampliéis la imagen y comentéis lo que os parece a vosotr@s.

Os dejo aquí el código para los más curiosos.

10 DIM FourDigitPassword INTEGER
20 FOR i = 0 TO 9
30 		FOR j = 0 TO 9
40			FOR k = 0 TO 9
50				FOR l = 0 TO 9
60					FourDigitPassword = getFourDigits (i,j,k,l)
70					IF checkPasswordMatch(FourDigitPassword) = TRUE THEN
80						GOTO 140
90					END
100				NEXT l
110			NEXT k
120		NEXT j
130 NEXT i
140 PRINT FourDigitPassword

Aunque  la entrada está dentro del contexto de los Blooper Tech Movies, digamos que en esta ocasión no voy a ir más allá. La escena es creíble y queda bien integrada en la época en la que se desarrolla el capítulo. Por esto mismo, solamente espero que las temporadas venideras sean tan buenas y cuiden tanto los detalles como sus predecesoras.

Referencias

[1] Ficha IMDB – Stranger Thing

[2] Wikia de Stranger Things

[3] IBM 3180

[4] BASIC

Entrevista a Karpoff de «Karpoff Spanish Tutor»

Karpoff.es

Hace unos días intenté contactar con Karpoff ya que fué una inspiración para mi y muchos otros, lo conseguí y se me ocurrió hacerle una entrevista, aquí tenéis el resultado.

Para los recién llegados diré que, Karpoff Spanish Tutor era (y sigue siendo aunque no se actualice), una gran web colaborativa donde encontrar cantidad de manuales y programas en Castellano.

deurus: ¿Qué te llevó a realizar la web?, es decir, que te hizo levantarte una mañana y decir, venga, voy a realizar una web sobre ingeniería inversa.

Karpoff: Pues mira, fue de la siguiente manera. Por aquel entonces (te hablo de los 90 y poco) yo pasaba mi tiempo libre intentando saltar las protecciones de los programas que conseguía generalmente en revistas de informática.

Desconocía que existía un mundillo dedicado a esas artes.

En los años 90 no había internet ni nada parecido que yo sepa, sobre el 95 creo recordar, telefónica saco una cosa que se llamaba Infobia y era una especie de intranet de telefónica donde accedías a un contenido muy limitado, pero te permitía salir de alguna manera bastante limitada también a lo que conocemos como internet (todo era mega lento, velocidades de uno o dos kb por segundo) con módem y llamadas analógicas.

No se como, ya que no existia o no era conocido Google tampoco había casi buscadores, conocí la famosa y maravillosa pagina de «Fravia» dedicada a la ingeniería inversa con muchísima documentación, y proyectos de estudio de protecciones, lamentablemente para el momento hispano, toda la documentación estaba en ingles .

Investigando conocí paginas hispanas con proyectos interesantes (aunque muchas de ellas aun siendo hispanas publicaban todo en ingles)

Conocí también otra pagina, el “ECD” estudio colectivo de desprotecciones + WTK en castellano e ingles que me sorprendió gratamente y donde se publicaban proyectos propios del grupo WTK y de otros grupos como estado+porcino.

los tres grupos hispanos del momento eran WTK, TNT y KUT, pertenecí a TNT durante algún tiempo, aunque el objetivo del grupo no me convencía ya que era exclusivamente la creación de cracks a mansalva por lo que no estuve más de un año.

Yo echaba de menos un sitio como “Fravia” pero en castellano donde todos los interesados pudiéramos colaborar y ayudarnos con temas de ingeniería inversa.

Ya en los 90 y mucho, todo lo relacionado con internet había evolucionado bastante, las conexiones también eran mas rápidas, ya no hacia falta conectarte a infobia sino directamente a internet.

Yo disponía de mucho tiempo libre y empecé un proyecto en solitario “Karpoff Spanish Tutor” mas conocido como “la pagina de karpoff” con proyectos de mi cosecha y con temas que me gustaban mucho, como la programación, los compiladores el software en general etc.

Luego todo lo demás fue llegando poco a poco, a la gente le gustaba y tenia muchísimas ganas de aprender y sobre todo de colaborar.

El proyecto alcanzo unos niveles impresionantes en cuanto a colaboración y recepción de material, había días que estaba mas de 14 horas actualizando la pagina y buscando nuevos servidores para alojarla, ya que me los cerraban casi semanalmente. Y la verdad.. cada vez me costaba mas tiempo mantener la pagina.

Luego gracias a Red Futura tuvimos un hostin de calidad y gratuito.

El proyecto era tan amplio que me fue imposible conciliar vida laboral y vida en internet todo esto empezaba a ser incompatible.

deurus: ¿Empezaste solo o erais un grupo de amiguetes?

Karpoff: Esta te la he contestado en la primera pregunta, vamos… que empecé yo solo.

deurus: ¿Echas de menos el proyecto?

Karpoff: Hoy en día no. Hace falta muchísimo tiempo libre y muchísima dedicación a nivel organizativo.

Echo de menos el movimiento que se creo y la actividad que alcanzo el movimiento cracking hispano. Salían grupos de cracker con nuevos proyectos y paginas hasta de debajo de las piedras 🙂 la ingenieria inversa se puso un poco de moda, conocí a gente muy interesante como Ricardo Narvaja, Numi_tor, Demian y muchas otras personas con muchos conocimientos.

Después de cerrar la pagina todo se quedo un poco cojo y todo el movimiento se empezó a diluir bastante rápido.

deurus: ¿Lo retomarías día de hoy?

Karpoff: La verdad es que no, ya no es mi tiempo, ahora me dedico al trabajo y mi familia y en ratos libres intento reventar algún programa. Sobre todo crackmes.

deurus: ¿Tienes o colaboras activamente en algún proyecto relacionado con la Ingeniería Inversa? 

Karpoff: No, no tengo tiempo. Mantengo contacto por correo con gente de que conocí en esa época y me sorprende que la gente no se olvida de mí. Recibo bastante correo en esta cuenta pidiéndome alguna entrevistilla, opiniones y muchos muchos agradecimientos de mucha gente por la página.

deurus: Yo por aquel entonces tenía 17 años, ¿se le puede preguntar la edad a Karpoff?

Karpoff: Pues yo tengo 45, por aquel entonces tenia unos 29 . La ingeniería inversa siempre fue mi pasión. Desde bien pequeño mi obsesión ha sido conocer como y porque funcionaba todo 🙂 hasta el punto de desmontar todo aquello que me llamaba la atención, mi madre estaba desesperada ya que dejaba todo destripado y muchas veces sin posiblilidad de reparacion.

deurus: ¿Te dedicas a algo relacionado con la informática?

Karpoff: Si, desde esos tiempos me encargo de los sistemas informáticos y equipos técnicos de una empresa bastante conocida, además ese fue uno de los principales motivos del cierre de la página.

Hubo gente interesada en seguir con el proyecto, aunque finalmente todo quedó en nada. Supongo que vieron que el proyecto requería muchísimo tiempo y mucho mucho trabajo.

Me dio mucha lastima no poder seguir con la página y mucha más que nadie se hiciera cargo de ella.

No hace mucho al desaparecer los redireccionadores “come.to” adquirí un dominio “karpoff.es” donde enlace tres mirror de la página para dejar un punto de acceso a ellos.

deurus: Finalmente ¿quieres decir algo a los lectores?

Karpoff: Pues sí, sobre todo dar las gracias a los que me conocen y tuvieron relación con la página, siempre me han hecho sentir grande y siempre tuve mucha colaboración y muchos ánimos por parte de los lectores.

Para los que no me conocen y les gusta la ingeniería inversa, decirles que lo que se aprende crackeando no lo enseñan en ningún sitio 🙂 y es muy muy gratificante.

deurus: Muchas gracias por tu atención, ha sido un placer.

Karpoff: Muchas gracias a ti, me ha hecho mucha ilusión y me ha gustado mucho tu blog.

Saludos !!

Karpoff

Tras las Pantallas de ‘Contact’: Un Viaje a Través del Hardware y del Software

Introducción

La película «Contact«, estrenada en 1997 y dirigida por Robert Zemeckis, es una adaptación de la novela homónima de Carl Sagan. Más allá de su profunda exploración sobre la existencia de vida extraterrestre y el debate entre ciencia y fe, la película ofrece un interesante vistazo a la tecnología de la época. En este análisis, nos enfocaremos en los aspectos tecnológicos presentes en la película, detallando los sistemas operativos, software y hardware utilizados por los protagonistas.

Sinopsis

La Dra. Eleanor «Ellie» Arroway, interpretada por Jodie Foster, es una científica dedicada al proyecto SETI (Búsqueda de Inteligencia Extraterrestre). Tras años de búsqueda, capta una señal proveniente del espacio profundo que contiene instrucciones para construir una máquina enigmática. A medida que se desarrolla la trama, Ellie enfrenta desafíos políticos, religiosos y personales mientras lucha por interpretar el mensaje y lo que podría significar para la humanidad.

Análisis Tecnológico

Sistemas Operativos y Software

Uno de los aspectos más destacados en Contact es la presencia del sistema operativo UNIX. A lo largo de la película, se observan pistas que indican su uso, como pegatinas en las pantallas con mensajes del estilo: «Join the UNIX PARTY (The open system platform)». UNIX, desarrollado en la década de 1970, es conocido por su estabilidad y eficiencia, características esenciales en entornos científicos y de investigación.

La utilización de Netscape Navigator es recurrente. El logo de Netscape aparece en varias ocasiones, especialmente durante las videoconferencias que se muestran sin retrasos apreciables. Netscape fue uno de los primeros navegadores web ampliamente utilizados y jugó un papel crucial en la expansión de Internet durante los años 90.

Es importante destacar que, aunque la película promueve la idea de sistemas abiertos a través del uso de UNIX, Netscape Navigator no era software libre en el momento en que se rodó la película. Durante esa época, antes de 1997, Netscape era un navegador propietario. Sin embargo, en sistemas UNIX, Netscape tenía poca competencia y era el navegador predominante, soportando estándares abiertos como HTTP y HTML. Curiosamente, en 1998, poco después del estreno de la película, Netscape liberó el código fuente de su navegador, iniciando el proyecto Mozilla y contribuyendo significativamente al movimiento del software libre.

El software o plataforma denominada MADDEN HADDEN es utilizado por los protagonistas en diversas localizaciones, sugiriendo que es un estándar en su campo. Aunque en la realidad no existe un software conocido con ese nombre en el ámbito científico, en la película parece ser una herramienta integral para el análisis de datos y comunicación.

Videoconferencias y Comunicaciones

Las videoconferencias sin «lags» (retrasos) que se muestran en la película son notables, especialmente considerando las limitaciones tecnológicas de la época. La presencia del logo de Netscape durante estas comunicaciones resalta el optimismo sobre las capacidades de Internet en 1997. En ese entonces, las conexiones de alta velocidad no eran comunes, y las videollamadas de calidad eran más una aspiración que una realidad.

Estándares y Sistemas Abiertos

La promoción de sistemas abiertos es evidente en la película. El uso de UNIX, basado en estándares abiertos, refleja una filosofía de colaboración y accesibilidad en el ámbito científico. Aunque Netscape Navigator no era software libre durante la producción de la película, su soporte para estándares abiertos de Internet lo convirtió en una herramienta esencial para la comunicación y el intercambio de información entre científicos y profesionales.

Hardware

En términos de hardware, la película presenta una variedad de equipos representativos de la tecnología de los años 90:

Monitor NEC MultiSync XE21: Un monitor CRT de 21 pulgadas conocido por su alta resolución y calidad de imagen, ideal para aplicaciones que requieren detalles precisos.

Monitores con marcas ocultas: Es interesante notar que en varios monitores se utilizan post-its o adhesivos para cubrir la marca y el modelo. Esto podría deberse a decisiones de producción para evitar publicidad no deseada o cuestiones legales relacionadas con derechos de marca.

Monitor CTX: Aunque no se especifica el modelo, los monitores CTX eran populares por su fiabilidad y rendimiento a un costo razonable.

Monitor Hansol Mazellan 17px: Los monitores Hansol eran reconocidos por su calidad en la reproducción de gráficos, siendo utilizados en diseño y aplicaciones multimedia.

Monitor IBM: IBM fue pionera en tecnología informática, y sus monitores eran sinónimo de calidad y durabilidad. Aunque no se especifica el modelo exacto, es probable que se trate de uno de sus populares monitores CRT utilizados en entornos profesionales.

Evolución de UNIX y Windows

Para entender el contexto tecnológico de la época, es útil comparar la evolución de UNIX y Windows, así como de los navegadores Netscape Navigator e Internet Explorer.

Detalles Adicionales

Cobertura de marcas: La práctica de cubrir las marcas y modelos en los monitores podría indicar un intento de la producción por crear un entorno más universal y atemporal, evitando asociar la tecnología presentada con productos específicos que podrían quedar obsoletos rápidamente. En bastantes fotogramas se nota que esto es completamente intencionado.

Representación de la tecnología: La película equilibra la precisión técnica con las necesidades narrativas. Si bien algunas representaciones, como las videoconferencias fluidas, eran tecnológicamente avanzadas para la época, sirven para enfatizar la conectividad y colaboración global entre los científicos.

SETI y la Búsqueda de Vida Extraterrestre: En Contact, la Dra. Ellie Arroway dedica su vida al proyecto SETI (Search for Extraterrestrial Intelligence), reflejando el esfuerzo real de la comunidad científica por encontrar señales de inteligencia extraterrestre. SETI es una iniciativa internacional que utiliza radiotelescopios para detectar posibles comunicaciones de civilizaciones fuera de la Tierra. La película captura la pasión y los desafíos asociados con este tipo de investigación, destacando la dedicación de los científicos que trabajan en el límite de lo conocido.

El Mensaje de Arecibo: El radiotelescopio de Arecibo en Puerto Rico juega un papel significativo tanto en la realidad como en la película. En 1974, desde este observatorio, se envió el famoso Mensaje de Arecibo, una transmisión de radio dirigida al cúmulo estelar M13, diseñada para demostrar los avances tecnológicos humanos y nuestra existencia a posibles civilizaciones extraterrestres. El mensaje contenía información codificada sobre la composición humana, nuestro sistema numérico, la estructura del ADN y nuestra posición en el sistema solar. En «Contact», aunque la señal recibida por Ellie proviene de Vega y no está directamente relacionada con el Mensaje de Arecibo, la película establece paralelismos con este acontecimiento histórico. La utilización de Arecibo como escenario subraya la conexión entre los esfuerzos reales y ficticios en la búsqueda de inteligencia extraterrestre. La película explora la posibilidad de que, así como enviamos mensajes al espacio, podríamos recibir respuestas o comunicaciones de otras civilizaciones.

Matthew McConaughey: Es interesante notar cómo este actor ha participado en dos de las películas más destacadas de la ciencia ficción: Contact e Interstellar. En Contact, McConaughey interpreta un papel secundario como Palmer Joss, un escritor y asesor espiritual que cuestiona las implicaciones éticas y filosóficas del descubrimiento científico. Diecisiete años después, en Interstellar, asume el rol protagonista de Cooper, un ex piloto de la NASA que emprende una misión interestelar para salvar a la humanidad.

Números primos: El inicio de la investigación seria de la señal extraterrestre en la película se desencadena cuando, al analizar la señal recibida, los científicos descubren que esta codifica una secuencia de números primos. Este hallazgo resulta crucial, ya que los números primos, al ser divisibles únicamente por 1 y por sí mismos, no surgen de forma aleatoria en procesos naturales conocidos. Su presencia en la señal sugiere intencionalidad e inteligencia detrás de su emisión, lo que confirma que no se trata de ruido cósmico sino de una posible comunicación deliberada desde una civilización avanzada. Este descubrimiento impulsa a los científicos a profundizar en la decodificación, marcando el verdadero inicio de la búsqueda de vida extraterrestre.

Conclusión

Contact no solo es una obra que invita a reflexionar sobre nuestro lugar en el universo y la posibilidad de vida más allá de la Tierra, sino que también es un retrato de la tecnología de su tiempo. La inclusión de sistemas operativos como UNIX, navegadores como Netscape y hardware específico refleja una atención al detalle que enriquece la narrativa. A pesar de que Netscape Navigator no era software libre durante la producción de la película, su presencia destaca la importancia de los estándares abiertos y la colaboración en el avance científico.

También destaca por su compromiso con la precisión científica, en gran parte debido a la influencia de Carl Sagan, autor de la novela original y asesor en la producción. La representación de los procedimientos del SETI, el análisis de señales y las discusiones éticas y filosóficas reflejan debates reales en la comunidad científica. La inclusión de elementos como el Mensaje de Arecibo y las operaciones del radiotelescopio añaden autenticidad a la narrativa y acercan al público a la realidad de la exploración espacial.

Bibliografía y Enlaces

Galería

Solución al KeygenMe1 (RSA200) de Dihux

Introducción

Empezamos con lo que espero que sea una serie de crackmes RSA. En este caso en particular y como el propio autor nos adelanta, se trata de RSA-200.

En criptografía, RSA (Rivest, Shamir y Adleman) es un sistema criptográfico de clave pública desarrollado en 1977. Es el primer y más utilizado algoritmo de este tipo y es válido tanto para cifrar como para firmar digitalmente.

 Funcionamiento de RSA

  1. Inicialmente es necesario generar aleatoriamente dos números primos grandes, a los que llamaremos p y q.
  2. A continuación calcularemos n como producto de p y q:
    n = p * q
  3. Se calcula fi:
    fi(n)=(p-1)(q-1)
  4. Se calcula un número natural e de manera que MCD(e, fi(n))=1 , es decir e debe ser primo relativo de fi(n). Es lo mismo que buscar un numero impar por el que dividir fi(n) que de cero como resto.
  5. Mediante el algoritmo extendido de Euclides se calcula d que es el inverso modular de e.
    Puede calcularse d=((Y*fi(n))+1)/e para Y=1,2,3,... hasta encontrar un d entero.
  6. El par de números (e,n) son la clave pública.
  7. El par de números (d,n) son la clave privada.
  8. Cifrado: La función de cifrado es.
    c = m^e mod n
  9. Descifrado: La función de descifrado es.
    m = c^d mod n

OllyDbg

Con OllyDbg analizamos la parte del código que nos interesa.

00401065  |>push    19                          ; /Count = 19 (25.)
00401067  |>push    00404330                    ; |Buffer = dihux_ke.00404330
0040106C  |>push    2711                        ; |ControlID = 2711 (10001.)
00401071  |>push    dword ptr [ebp+8]           ; |hWnd
00401074  |>call    <GetDlgItemTextA>           ; \GetDlgItemTextA
00401079  |>cmp     eax, 5                      ;  Tamaño nombre >= 5
0040107C  |>jb      00401214
00401082  |>cmp     eax, 14                     ;  Tamaño nombre <= 0x14
00401085  |>ja      00401214
0040108B  |>mov     [404429], eax
00401090  |>push    96                          ; /Count = 96 (150.)
00401095  |>push    00404349                    ; |Buffer = dihux_ke.00404349
0040109A  |>push    2712                        ; |ControlID = 2712 (10002.)
0040109F  |>push    dword ptr [ebp+8]           ; |hWnd
004010A2  |>call    <GetDlgItemTextA>           ; \GetDlgItemTextA
004010A7  |>test    al, al
........
004010D8  |>xor     ecx, ecx                    ;  Case 0 of switch 004010B6
004010DA  |>/push    0
004010DC  |>|call    <__BigCreate@4>
004010E1  |>|mov     [ecx*4+404411], eax
004010E8  |>|inc     ecx
004010E9  |>|cmp     ecx, 6
004010EC  |>\jnz     short 004010DA
004010EE  |>push    dword ptr [404411]          ; /Arg3 = 00B60000
004010F4  |>push    10                          ; |16??
004010F6  |>push    0040401F                    ; |Arg1 = 0040401F ASCII "8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89"
004010FB  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401100  |>push    dword ptr [404415]          ; /Arg3 = 00C70000
00401106  |>push    10                          ; |Arg2 = 00000010
00401108  |>push    00404019                    ; |Arg1 = 00404019 ASCII "10001"
0040110D  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401112  |>push    dword ptr [404425]          ; /Arg3 = 00CB0000
00401118  |>push    10                          ; |Arg2 = 00000010
0040111A  |>push    00404349                    ; |Arg1 = 00404349 ASCII "123456789123456789"
0040111F  |>call    <__BigIn@12>                ; \dihux_ke.004013F3
00401124  |>push    00404330                    ; /String = "deurus"
00401129  |>call    <lstrlenA>                  ; \lstrlenA
0040112E  |>push    dword ptr [404419]
00401134  |>push    eax
00401135  |>push    00404330                    ;  ASCII "deurus"
0040113A  |>call    <__BigInB256@12>
0040113F  |>push    dword ptr [404421]          ;  c
00401145  |>push    dword ptr [404411]          ;  n = 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
0040114B  |>push    dword ptr [404415]          ;  e = 10001
00401151  |>push    dword ptr [404425]          ;  serial
00401157  |>call    <__BigPowMod@16>            ;  c = serial^e (mod n)
0040115C  |>mov     eax, 1337
00401161  |>push    0                           ; /Arg4 = 00000000
00401163  |>push    dword ptr [40441D]          ; |x
00401169  |>push    eax                         ; |0x1337
0040116A  |>push    dword ptr [404421]          ; |c
00401170  |>call    <__BigDiv32@16>             ; \x = c/0x1337
00401175  |>push    dword ptr [40441D]          ;  x
0040117B  |>push    dword ptr [404419]          ;  nombre
00401181  |>call    <__BigCompare@8>            ; ¿x = nombre?
00401186  |>jnz     short 0040119C
00401188  |>push    0                           ; /Style = MB_OK|MB_APPLMODAL
0040118A  |>push    00404014                    ; |Title = "iNFO"
0040118F  |>push    00404004                    ; |Text = "Serial is valid"
00401194  |>push    dword ptr [ebp+8]           ; |hOwner
00401197  |>call    <MessageBoxA>               ; \MessageBoxA
0040119C  |>xor     ecx, ecx
0040119E  |>/push    dword ptr [ecx*4+404411]
004011A5  |>|call    <__BigDestroy@4>
004011AA  |>|inc     ecx
004011AB  |>|cmp     ecx, 6
004011AE  |>\jnz     short 0040119E

 Lo primero que observamos es que el código nos proporciona el exponente público (e) y el módulo (n).

  • e = 10001
  • n = 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89

A continuación halla c = serial^d mod n. Finalmente Divide c entre 0x1337 y lo compara con el nombre.

Como hemos visto en la teoría de RSA, necesitamos hallar el exponente privado (d) para poder desencriptar, según la fórmula vista anteriormente.

  • Fórmula original: m=c^d mod n
  • Nuestra fórmula: Serial = x^d mod n. Siendo x = c * 0x1337

Calculando un serial válido

Existen varios ataques a RSA, nosotros vamos a usar el de factorización. Para ello vamos a usar la herramienta RSA Tool. Copiamos el módulo (n), el exponente público (e) y factorizamos (Factor N).

rsatool1

Hallados los primos p y q, hallamos d (Calc. D).

rsatool4

Una vez obtenido d solo nos queda obtener x, que recordemos es nombre * 0x1337.

Cuando decimos nombre nos referimos a los bytes del nombre en hexadecimal, para deurus serían 646575727573.

Ejemplo operacional

Nombre: deurus

x = 646575727573 * 0x1337 = 7891983BA4EC4B5
Serial = x^d mod n
Serial = 7891983BA4EC4B5^32593252229255151794D86C1A09C7AFCC2CCE42D440F55A2D mod 8ACFB4D27CBC8C2024A30C9417BBCA41AF3FC3BD9BDFF97F89
Serial = FD505CADDCC836FE32E34F5F202E34D11F385DEAD43D87FCD

Como la calculadora de Windows se queda un poco corta para trabajar con números tan grandes, vamos a usar la herramienta Big Integer Calculator. A continuación os dejo unas imágenes del proceso.

bigint_1

bigint_2

crackme_dihux_solved

Keygen

En esta ocasión hemos elegido Java ya que permite trabajar con números grandes de forma sencilla, os dejo el código más importante.

dihux_keygenme1_keygen

JButton btnNewButton = new JButton("Generar");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
BigInteger serial = new BigInteger("0");
BigInteger n = new BigInteger("871332984042175151665553882265818310920539633758381377421193");//módulo
BigInteger d = new BigInteger("316042180198461106401603389463895139535543421270452849695277");//exponente privado
BigInteger x = new BigInteger("4919");//0x1337
String nombre = t1.getText();
BigInteger nombre2 = new BigInteger(nombre.getBytes());
nombre2 = nombre2.multiply(x);
serial = nombre2.modPow(d, n);
t2.setText(serial.toString(16).toUpperCase());
}
});

Links


Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
File carving is the process of reassembling computer files from fragments in the absence of filesystem metadata. Wikipedia. "File carving", literalmente tallado
Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la
En una entrada anterior sobre cómo Expediente X abordó la tecnología de vanguardia, comenté que dedicaría un espacio a esos

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

List of file signatures for file carving

File carving is the process of reassembling computer files from fragments in the absence of filesystem metadata. Wikipedia.

«File carving», literalmente tallado de archivos aunque lo traduciremos como extracción, es el proceso de re-ensamblado de archivos extraídos de un conjunto de mayor tamaño.

Índice

  1. Image files / Archivos de imagen
  2. Microsoft Office >2007
  3. Open Office
  4. Autocad
  5. Others / Otros
  6. Links / Enlaces

List of headers and tails / Lista de cabeceras y pies

Header = Cabecera

Footer or tail = Pie

Image files / Archivos de imagen

  • JPEG
    • Header: FFD8
    • Footer: FFD9
  • GIF87a
    • Header: 47 49 46 38 37 61
    • Footer: 00 3B
  • GIF89a
    • Header: 47 49 46 38 39 61
    • Footer: 00 3B
  • BMP
    • Header: 42 4D
    • Footer: Don’t have footer, but size is in bytes 2,3,4,5 in little-endian order (low byte first).
      • Example: 00 00 C0 38 == 49208 bytes

bmpsize

  • PNG
    • Header: 89 50 4E 47 0D 0A 1A 0A
    • Footer: 49 45 4E 44 AE 42 60 82

Microsoft Office >2007

All this documents have the same header and footer, because of this, we need search the middle bytes. This type uses a ZIP file package.

Los documentos de Microsoft Office >2007 tienen la misma cabecera y pie, por lo que necesitamos bytes intermedios para distinguirlos. Usan encapsulado ZIP.

  • DOCX
    • Header: 50 4B 03 04 14 00 06 00
      • Middle: 77 6F 72 64 (word)
    • Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
  • XLSX
    • Header: 50 4B 03 04 14 00 06 00
      • Middle: 77 6F 72 6B 73 68 65 65 74 73 (worksheets)
    • Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
  • PPTX
    • Header: 50 4B 03 04 14 00 06 00
      • Middle: 70 72 65 73 65 6E 74 61 74 69 6F 6E (presentation)
    • Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
  • MDB / ACCDB
    • Header: 00 01 00 00 53 74 61 6E 64 61 72 64 20 4A 65 74 20 44 42 (….Standard Jet DB)
    • Footer: Don’t have footer.

Open Office

All this documents have the same header and footer, because of this, we need some bytes to differentiate them. In this case we can do this jumping 73 bytes from header. This type uses a ZIP file package.

Los documentos de OpenOffice tienen la misma cabecera y pie, por lo que necesitamos bytes intermedios para distinguirlos. Usan encapsulado ZIP.

  • ODS
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 73 70 72 65 (spre)
    • Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
  • ODT
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 74 65 78 64 (text)
    • Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
  • ODB
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 62 61 73 65 (base)
    • Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
  • ODG
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 67 72 61 70 (grap)
    • Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
  • ODF
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 66 6F 72 6D (form)
    • Tail: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.
  • ODP
    • Header: 50 4B 03 04 14 (PK..) jump +73 (0x49) bytes and 70 72 65 73 (pres)
    • Footer: 6D 61 6E 69 66 65 73 74 2E 78 6D 6C 50 4B 05 06 (manifest.xmlPK) followed by 18 additional bytes.

Autocad

  • DWG (R11/R12 versions)
    • Header: 41 43 31 30 30 39
    • Footer: CD 06 B2 F5 1F E6
  • DWG (R14 version)
    • Header: 41 43 31 30 31 34
    • Footer: 62 A8 35 C0 62 BB EF D4
  • DWG (2000 version)
    • Header: 41 43 31 30 31 34
    • Footer: DB BF F6 ED C3 55 FE
  • DWG (>2007 versions)
    • Header: 41 43 31 30 XX XX
    • Footer: Don’t have

Note: >2007 versions have two patterns and the key is the position 0x80. If in this position we get the bytes «68 40 F8 F7 92», we need to search again for this bytes and displace 107 bytes to find the end of the file. If in the position 0x80 we get another different bytes, we need to search again this bytes and displace 1024 bytes to find the end of the file.

Nota: Las versiones >2007 siguen dos patrones y la clave está en la posición 0x80. Si en la posicion 0x80 obtenemos los bytes «68 40 F8 F7 92», los buscamos una segunda vez y ha 107 bytes encontramos el final del archivo. Si en la posición 0x80 obtenemos otros bytes diferentes a los del primer caso, los volvemos a buscar y a 1024 bytes hallaremos el final del archivo.

Others / Otros

  • PDF
    • Header: 25 50 44 46 (%PDF)
    • Footers:
      • 0A 25 25 45 4F 46 (.%%EOF) or
      • 0A 25 25 45 4F 46 0A (.%%EOF.) or
      • 0D 0A 25 25 45 4F 46 0D 0A (..%%EOF..) or
      • 0D 25 25 45 4F 46 0D (.%%EOF.)
  • ZIP
    • Header: 50 4B 03 04
    • Footer: 50 4B 05 06 (PK..) followed by 18 additional bytes at the end of the file.
  • RAR (< 4.x version)
    • Header: 52 61 72 21 1A 07 00
    • Tail: C4 3D 7B 00 40 07 00
  • 7ZIP
    • Header: 37 7A BC AF 27 1C 00 03  (7z¼¯’…)
    • Footer: 01 15 06 01 00 20 followed by 5 additional bytes at the end of the file.
  • RTF
    • Header: 7B 5C 72 74 66 31
    • Footer: 5C 70 61 72 20 7D

Links / Enlaces

lost_in_bin

Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la solución en el decompilado y quizá por evocar recuerdos de tiempos pretéritos.

ELF Decompilado

/* This file was generated by the Hex-Rays decompiler version 8.4.0.240320.
   Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>

   Detected compiler: GNU C++
*/

#include <defs.h>


//-------------------------------------------------------------------------
// Function declarations

__int64 (**init_proc())(void);
__int64 sub_400650(); // weak
// int printf(const char *format, ...);
// int puts(const char *s);
// void __noreturn exit(int status);
// size_t strlen(const char *s);
// __int64 __fastcall MD5(_QWORD, _QWORD, _QWORD); weak
// int sprintf(char *s, const char *format, ...);
// __int64 ptrace(enum __ptrace_request request, ...);
// __int64 strtol(const char *nptr, char **endptr, int base);
// __int64 __isoc99_scanf(const char *, ...); weak
// int memcmp(const void *s1, const void *s2, size_t n);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
void *sub_400730();
__int64 sub_400760();
void *sub_4007A0();
__int64 sub_4007D0();
void fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// __int64 _gmon_start__(void); weak

//-------------------------------------------------------------------------
// Data declarations

_UNKNOWN main;
_UNKNOWN init;
__int64 (__fastcall *funcs_400E29)() = &sub_4007D0; // weak
__int64 (__fastcall *off_601DF8)() = &sub_4007A0; // weak
__int64 (*qword_602010)(void) = NULL; // weak
char *off_602080 = "FLAG-%s\n"; // idb
char a7yq2hryrn5yJga[16] = "7Yq2hrYRn5Y`jga"; // weak
const char aO6uH[] = "(O6U,H\""; // idb
_UNKNOWN unk_6020B8; // weak
_UNKNOWN unk_6020C8; // weak
char byte_6020E0; // weak
char s1; // idb
char byte_602110[]; // weak
char byte_602120[33]; // weak
char byte_602141[7]; // idb
__int64 qword_602148; // weak
__int64 qword_602150; // weak
__int64 qword_602158; // weak
__int64 qword_602160; // weak
__int64 qword_602178; // weak


//----- (0000000000400630) ----------------------------------------------------
__int64 (**init_proc())(void)
{
  __int64 (**result)(void); // rax

  result = &_gmon_start__;
  if ( &_gmon_start__ )
    return (__int64 (**)(void))_gmon_start__();
  return result;
}
// 6021D8: using guessed type __int64 _gmon_start__(void);

//----- (0000000000400650) ----------------------------------------------------
__int64 sub_400650()
{
  return qword_602010();
}
// 400650: using guessed type __int64 sub_400650();
// 602010: using guessed type __int64 (*qword_602010)(void);

//----- (0000000000400700) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
  __int64 v3; // rax
  int v4; // esi
  __int64 v5; // [rsp-8h] [rbp-8h] BYREF
  char *retaddr; // [rsp+0h] [rbp+0h] BYREF

  v4 = v5;
  v5 = v3;
  _libc_start_main((int (__fastcall *)(int, char **, char **))main, v4, &retaddr, (void (*)(void))init, fini, a3, &v5);
  __halt();
}
// 400706: positive sp value 8 has been found
// 40070D: variable 'v3' is possibly undefined

//----- (0000000000400730) ----------------------------------------------------
void *sub_400730()
{
  return &unk_6020C8;
}

//----- (0000000000400760) ----------------------------------------------------
__int64 sub_400760()
{
  return 0LL;
}

//----- (00000000004007A0) ----------------------------------------------------
void *sub_4007A0()
{
  void *result; // rax

  if ( !byte_6020E0 )
  {
    result = sub_400730();
    byte_6020E0 = 1;
  }
  return result;
}
// 6020E0: using guessed type char byte_6020E0;

//----- (00000000004007D0) ----------------------------------------------------
__int64 sub_4007D0()
{
  return sub_400760();
}

//----- (00000000004007D7) ----------------------------------------------------
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  size_t v3; // rax
  size_t v4; // rax
  int i; // [rsp+1Ch] [rbp-24h]
  int n; // [rsp+20h] [rbp-20h]
  int m; // [rsp+24h] [rbp-1Ch]
  int k; // [rsp+28h] [rbp-18h]
  int j; // [rsp+2Ch] [rbp-14h]

  if ( ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL) == -1 )
    goto LABEL_2;
  if ( a1 > 4 )
  {
    qword_602148 = strtol(a2[1], 0LL, 10);
    if ( qword_602148 )
    {
      qword_602150 = strtol(a2[2], 0LL, 10);
      if ( qword_602150 )
      {
        qword_602158 = strtol(a2[3], 0LL, 10);
        if ( qword_602158 )
        {
          qword_602160 = strtol(a2[4], 0LL, 10);
          if ( qword_602160 )
          {
            if ( -24 * qword_602148 - 18 * qword_602150 - 15 * qword_602158 - 12 * qword_602160 == -18393
              && 9 * qword_602158 + 18 * (qword_602150 + qword_602148) - 9 * qword_602160 == 4419
              && 4 * qword_602158 + 16 * qword_602148 + 12 * qword_602150 + 2 * qword_602160 == 7300
              && -6 * (qword_602150 + qword_602148) - 3 * qword_602158 - 11 * qword_602160 == -8613 )
            {
              qword_602178 = qword_602158 + qword_602150 * qword_602148 - qword_602160;
              sprintf(byte_602141, "%06x", qword_602178);
              v4 = strlen(byte_602141);
              MD5(byte_602141, v4, byte_602110);
              for ( i = 0; i <= 15; ++i )
                sprintf(&byte_602120[2 * i], "%02x", (unsigned __int8)byte_602110[i]);
              printf(off_602080, byte_602120);
              exit(0);
            }
          }
        }
      }
    }
LABEL_2:
    printf("password : ");
    __isoc99_scanf("%s", &s1);
    if ( strlen(&s1) > 0x10 )
    {
      puts("the password must be less than 16 character");
      exit(1);
    }
    for ( j = 0; j < strlen(&s1); ++j )
      *(&s1 + j) ^= 6u;
    if ( !strcmp(&s1, a7yq2hryrn5yJga) )
    {
      v3 = strlen(&s1);
      MD5(&s1, v3, byte_602110);
      for ( k = 0; k <= 15; ++k )
        sprintf(&byte_602120[2 * k], "%02x", (unsigned __int8)byte_602110[k]);
      printf(off_602080, byte_602120);
      exit(0);
    }
    puts("bad password!");
    exit(0);
  }
  printf("password : ");
  __isoc99_scanf("%s", &s1);
  if ( strlen(&s1) > 0x10 )
  {
    puts("the password must be less than 16 character");
    exit(1);
  }
  for ( m = 0; m < strlen(&s1); ++m )
  {
    *(&s1 + m) ^= 2u;
    ++*(&s1 + m);
    *(&s1 + m) = ~*(&s1 + m);
  }
  if ( !memcmp(&s1, &unk_6020B8, 9uLL) )
  {
    for ( n = 0; n < strlen(aO6uH); n += 2 )
    {
      aO6uH[n] ^= 0x45u;
      aO6uH[n + 1] ^= 0x26u;
    }
    puts(aO6uH);
  }
  else
  {
    puts("bad password!");
  }
  return 0LL;
}
// 4006A0: using guessed type __int64 __fastcall MD5(_QWORD, _QWORD, _QWORD);
// 4006E0: using guessed type __int64 __isoc99_scanf(const char *, ...);
// 602148: using guessed type __int64 qword_602148;
// 602150: using guessed type __int64 qword_602150;
// 602158: using guessed type __int64 qword_602158;
// 602160: using guessed type __int64 qword_602160;
// 602178: using guessed type __int64 qword_602178;

//----- (0000000000400DE0) ----------------------------------------------------
void __fastcall init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v3; // rbp
  __int64 i; // rbx

  v3 = &off_601DF8 - &funcs_400E29;
  init_proc();
  if ( v3 )
  {
    for ( i = 0LL; i != v3; ++i )
      (*(&funcs_400E29 + i))();
  }
}
// 601DF0: using guessed type __int64 (__fastcall *funcs_400E29)();
// 601DF8: using guessed type __int64 (__fastcall *off_601DF8)();

//----- (0000000000400E54) ----------------------------------------------------
void term_proc()
{
  ;
}

// nfuncs=33 queued=10 decompiled=10 lumina nreq=0 worse=0 better=0
// ALL OK, 10 function(s) have been successfully decompiled

Análisis estático

Anti-debug

Si la función ptrace retorna -1, significa que el programa está siendo depurado y redirige a LABEL_2.

if (ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL) == -1) {
    goto LABEL_2;
}

Cálculos y validaciones

El programa espera al menos 5 argumentos (nombre del programa y cuatro números enteros). Si se proporcionan los cuatro números enteros, se realizan los siguientes cálculos:

if (-24 * qword_602148 - 18 * qword_602150 - 15 * qword_602158 - 12 * qword_602160 == -18393
    && 9 * qword_602158 + 18 * (qword_602150 + qword_602148) - 9 * qword_602160 == 4419
    && 4 * qword_602158 + 16 * qword_602148 + 12 * qword_602150 + 2 * qword_602160 == 7300
    && -6 * (qword_602150 + qword_602148) - 3 * qword_602158 - 11 * qword_602160 == -8613)

Esto es un sistema de ecuaciones lineales mondo y lirondo que debe ser resuelto para encontrar los valores correctos de qword_602148, qword_602150, qword_602158 y qword_602160. Una vez resuelto el sistema de ecuaciones se realiza la operación:

 qword_602178 = qword_602158 + qword_602150 * qword_602148 - qword_602160;

A continuación se pasa el resultado de la variable qword_602178 a hexadecimal y se genera su hash MD5.

Solución en Python

Lo más rápido en esta ocasión es usar Python, pero esto se puede resolver hasta con lápiz y papel 😉

from sympy import symbols, Eq, solve
import hashlib

# Definir las variables
A, B, C, D = symbols('A B C D')

# Definir las ecuaciones
eq1 = Eq(-24*A - 18*B - 15*C - 12*D, -18393)
eq2 = Eq(9*C + 18*(A + B) - 9*D, 4419)
eq3 = Eq(4*C + 16*A + 12*B + 2*D, 7300)
eq4 = Eq(-6*(A + B) - 3*C - 11*D, -8613)

# Resolver el sistema de ecuaciones
solution = solve((eq1, eq2, eq3, eq4), (A, B, C, D))

# Verificar si se encontró una solución
if solution:
    print("Solución encontrada:")
    print(solution)

    # Obtener los valores de A, B, C y D
    A_val = solution[A]
    B_val = solution[B]
    C_val = solution[C]
    D_val = solution[D]

    # Mostrar los valores encontrados
    print(f"A = {A_val}")
    print(f"B = {B_val}")
    print(f"C = {C_val}")
    print(f"D = {D_val}")

    # Calcular qword_602178
    qword_602178 = C_val + B_val * A_val - D_val
    qword_602178 = int(qword_602178)  # Convertir a entero de Python
    print(f"qword_602178 = {qword_602178}")

    # Convertir qword_602178 a una cadena en formato hexadecimal
    byte_602141 = f"{qword_602178:06x}"
    print(f"byte_602141 (hex) = {byte_602141}")

    # Calcular el MD5 de la cadena
    md5_hash = hashlib.md5(byte_602141.encode()).hexdigest()
    print(f"MD5 hash = {md5_hash}")

    # Generar la flag
    flag = f"FLAG-{md5_hash}"
    print(f"Flag = {flag}")

else:
    print("No se encontró una solución.")

Al ejecutar el script veremos algo como esto:

Solución encontrada:
{A: 227, B: 115, C: 317, D: 510}
A = 227
B = 115
C = 317
D = 510
qword_602178 = 25912
byte_602141 (hex) = 006538
MD5 hash = 21a84f2c7c7fd432edf1686215db....
Flag = FLAG-21a84f2c7c7fd432edf1686215db....

Los Pistoleros Solitarios

En una entrada anterior sobre cómo Expediente X abordó la tecnología de vanguardia, comenté que dedicaría un espacio a esos tres personajes tan peculiares y entrañables que, desde el segundo plano, se ganaron un hueco en el corazón de los seguidores de la serie: los Pistoleros Solitarios. Pues bien, ha llegado el momento.

Estos tres tipos —John Fitzgerald Byers, Melvin Frohike y Richard “Ringo” Langly— no necesitaban armas ni placas del FBI. Su poder estaba en los teclados, los cables enredados y los monitores de tubo que parpadeaban en un sótano lleno de conspiraciones y café frío. Eran los outsiders de Expediente X, tres hackers con alma de periodistas que luchaban por algo tan simple y tan enorme como la verdad.

Su primera aparición fue en E.B.E. (temporada 1), casi como un alivio cómico: tres frikis que ayudaban a Mulder a rastrear información sobre ovnis. Pero pronto quedó claro que había algo especial en ellos. No solo eran fuente de datos, sino conciencia crítica en un mundo plagado de mentiras digitales y gobiernos con demasiados secretos. Con el tiempo se convirtieron en aliados imprescindibles de Mulder y Scully, y también en el reflejo más humano de lo que significa ser hacker: curiosos, testarudos, torpes a veces, pero con un sentido moral inquebrantable.

Byers era el idealista, el que aún creía en la decencia y en las instituciones (al menos en teoría). Frohike, el cínico veterano con corazón de oro, siempre dispuesto a arriesgarse por una buena causa… o por impresionar a Scully. Y Langly, el genio rebelde que parecía vivir en permanente conversación con su módem de 56 k. Juntos formaban un trío excéntrico, pero perfectamente equilibrado.

Mientras Mulder y Scully perseguían abducciones y virus extraterrestres, los pistoleros combatían en otra trinchera: la digital. Hackeaban redes gubernamentales, interceptaban comunicaciones cifradas y desmantelaban cortafuegos que, en los noventa, parecían pura ciencia ficción. Lo suyo no era la acción física, sino la resistencia informativa. Y aunque muchas veces eran el chiste del capítulo, también representaban algo muy real: la gente corriente que lucha contra el poder desde el conocimiento.

Su lema no declarado podría haber sido el clásico “la información quiere ser libre”, y en eso se mantuvieron firmes hasta el final. Si había que elegir entre la seguridad o la verdad, ellos siempre elegían la verdad, aunque les costara caro.

TemporadaEpisodioTítuloComentario
117E.B.E.Primera aparición de los pistoleros.
23BloodManipulación de dispositivos y mensajes ocultos. También control mental a través de la tecnología.
225AnasaziUn hacker roba archivos clasificados. Se tratan temas como el cifrado y filtración de datos del gobierno.
315ApocryphaAcceso a bases de datos secretas y descifrado de archivos comprometidos.
323WetwiredManipulación de señales televisivas.
414Memento MoriInfiltración digital en sistemas médicos y vigilancia biotecnológica.
51ReduxRobo y manipulación de pruebas digitales.
53Unusual SuspectsOrígenes de los pistoleros: intrusión, cifrado y espíritu hacker de los noventa.
511Kill SwitchIA autónoma y malware inteligente.
620Three of a KindHacking social, suplantación y síntesis de voz para infiltración corporativa.
713First Person ShooterHackeo de entornos virtuales y brechas de seguridad en sistemas de realidad aumentada.
915Jump the SharkSu sacrificio final: bloqueo de una amenaza biológica, ética hacker y altruismo extremo.
112ThisLangly como conciencia digital en un servidor. Debate sobre IA y trascendencia del código.

Morir por la verdad

El final de los pistoleros fue tan inesperado como heroico. En el episodio “Jump the Shark” de la novena temporada, descubren un complot bioterrorista que amenaza con liberar un virus mortal. No hay tiempo para avisar a nadie, ni margen para escapar. Así que, fieles a su estilo, deciden sacrificarse para salvar a otros. Sellan el laboratorio desde dentro, sabiendo que no volverán a salir.

Lo reconozco, este desenlace mi cogió completamente por sorpresa. No hay épica de Hollywood, ni música grandilocuente. Solo tres hombres anónimos haciendo lo correcto. Mueren juntos, sin reconocimiento, sin medallas, pero con la serenidad de quienes saben que su causa era justa. Y en ese silencio final, Expediente X nos recordó algo que las grandes historias suelen olvidar: que los verdaderos héroes a veces no llevan traje ni pistola, solo convicción.

Años después, Mulder vuelve a verlos —o cree verlos— en The Truth. Ya no están en este mundo, pero siguen a su lado, como fantasmas digitales de la conciencia hacker. Es un homenaje discreto a quienes siempre pelearon desde las sombras por liberar la verdad.

Para cerrar el círculo, Langly reaparece de forma inesperada en la temporada 11, dentro del episodio This. Su mente, o más bien su copia digital, sobrevive atrapada en un servidor, reclamando ser liberada. Es el epílogo perfecto: el hacker que muere físicamente, pero cuya conciencia sigue inmortal. Una vez más me volvió a sorprender Chris Carter con este homenaje.

Me gusta pensar que los pistoleros solitarios representaban algo más que tres hackers secundarios en una serie de los noventa. Fueron el reflejo de una época en la que creíamos que la tecnología podía liberar al ser humano, antes de que las redes sociales y la hiperconectividad lo diluyeran todo. Byers, Frohike y Langly no luchaban por fama ni por dinero: luchaban por entender el sistema para exponerlo, por esa curiosidad genuina que hoy apenas sobrevive entre líneas de código y algoritmos opacos. Quizá por eso seguimos recordándolos y mola tanto volver a ver los capítulos. Porque, de algún modo, todos los que amamos el conocimiento libre llevamos dentro un pequeño pistolero solitario, buscando la verdad entre los bits.