Desafío 26 de ESET Latinoamérica: Escuchando una fuga de información

Bienvenidos a un nuevo desafío de ESET Latinoamérica. En esta oportunidad, en nuestra entrega número 26 necesitamos analizar una captura de tráfico sospechosa.

A nuestro equipo de investigación le llegó una porción de una captura de red de una comunicación FTP donde se sospecha que se está intercambiando información sensible. El problema es que no se ha podido identificar si realmente se trata de una fuga de información.

Análisis preliminares de la captura de tráfico, permitieron identificar en esta porción de tráfico que por lo menos se intercambiaron dos archivos diferentes por la red de la compañía, uno de los cuales parece estar cifrado. Como esta captura de tráfico se han detectado otras similares, todas teniendo como destino la  misma computadora.

Lo que más ha llamado la atención de nuestros analistas de seguridad, es que la máquina a la cual se dirige el tráfico pertenece a un empleado que  renunció a la empresa y trabajará hasta finales de la próxima semana.

De esta forma hemos planteado las condiciones de nuestro Desafío 26. El ganador del reto deberá entregarnos la clave del archivo que parece estar cifrado y además determinar si en la captura de tráfico hay información que pueda ser considerada sensible y de esta forma prevenir que se fugue la información con el empleado que renuncia, y en caso afirmativo poder iniciar algún proceso de tipo disciplinario.

Les recordamos que aquellos que encuentren la solución deben enviar un comentario a este post detallando su respuesta. El viernes de la semana que viene, estaremos aprobando todos los comentarios y publicando la solución al desafío en WeLiveSecurity.El ganador se llevará una licencia de las última versión de la más completa solución de seguridad: ESET Smart Security.

La próxima semana estaremos dando algunas pistas sobre como pueden resolver este desafío, así que estén pendientes de nuestras redes sociales. Hasta entonces no daremos ningún tipo de información.

¡Éxitos resolviendo el desafío y que lo disfruten!

Actualización

Analizando la captura de tráfico se encuentran un par de archivos, que pueden ser descargados. Uno de ellos va a estar cifrado, por lo cual la idea es encontrar la clave para ver de que se trata. El otro archivo es un ejecutable. Es importante analizar que pasa cuando se ejecuta este archivo, haciéndose las siguientes preguntas: ¿se genera un archivo nuevo? ¿ lo qué se genera es realmente lo que parece ser?.

Autor , ESET

  • Emiliano

    La clave del archivo cifrado es “samuelfinleybreesemorseinventordeltelegrafo”
    El empleado parece estar robando una lista de clientes (es la captura de una planilla de calculos)
    Los pasos para llegar a la solucion fueron:
    * Extraer los dos archivos de la caputra.
    * Analizar el comportamiento del exe (notar que crea un archivo de audio con extension dll).
    * Descifrar el archivo (era codigo morse).
    * Usar el mensaje cifrado como password para descifrar segundo archivo.
    * Este ultimo archivo descifrado era la imagen que el empleado estaba intentando robar.

    Saludos.

  • Hector Andres Castañeda Revill

    HOLA SALUSOS

  • Los siguientes fueron los pasos para recuperar la clave del archivo cifrado y descubrir si hay contenido sensible que pueda ser considerado como una posible fuga de información al ser transmitido por FTP:

    1. Extraer los archivos exect.exe e importante.gpg de la captura.

    2. Extraer el archivo que contiene la funcionalidad principal del archivo ejecutable y decompilarlo (archivo generado a través de py2exe o similar)

    3. Entender el funcionamiento del código ofuscado (lee una cadena y por cada carácter en dicha cadena forma un sonido, el cual finalmente puede ser interpretado como código morse).

    4. El mensaje en morse que puede escucharse del archivo twunk.dll es .-.. .- -.-. .-.. .- …- . . … … .- — ..- . .-.. ..-. .. -. .-.. . -.– -… .-. . . … . — — .-. … . .. -. …- . -. – — .-. -.. . .-.. – . .-.. . –. .-. .- ..-. — .-.-., el cual se decodifica a “la clave es samuelfinleybreesemorseinventordeltelegrafo”. Para este punto obtenemos el primer requisito del reto el cual es recuperar la clave del archivo cifrado.

    5. El siguiente paso es descifrar el archivo importante.gpg a través de la utilidad gpg:

    gpg -o unknown.bin -d importante.gpg

    6. Analizamos el archivo descifrado unknown.bin y determinamos que se trata de una imagen de formato JPEG, el cual contiene una lista de nombres, DNI, teléfonos, trabajos, salarios, entre otros, los cuales pueden ser considerados como información sensible, y por lo tanto afirmar que se trata de un caso de fuga de información.

    Código decompilado: https://www.sinfocol.org/archivos/2014/03/desafio26.py
    Imagen con información sensible: https://www.sinfocol.org/archivos/2014/03/unknown.jpg

  • Abraham Diaz

    Pasos que seguí:
    1) Abrir la captura de paquetes con Wireshark, se extraen los 2 archivos de la captura con ayuda de un filtro como http://ftp.request.command == “RETR” para ubicar el inicio de la transmision de cada uno y usando la opción de seguir el stream TCP > guardar como…

    Obtenemos exect.exe e importante.gpg, este es el archivo cifrado.

    2) Usé PEStudio para analizarlo, en Sections Headers podemos ver que hay secciones llamadas UPX0 y UPX1 asi que se uso UPX para probar y descomprimir el ejecutable.

    3) Ya se pueden ver las secciones con un nombre más común, revisamos más a fondo la sección donde estan los Resources y ademas de los iconos vemos 2 archivos: PYTHON27.DLL y PYTHONSCRIPT. Se puede deducir que se usó una herramienta para convertir un script de python a exe, especificamente py2exe.

    Usando Py2ExeDumper extraemos los 2 resources y el zip adjunto al final del exe para que Easy Python Decompiler nos ayude a decompilar el script, ya que se encuentra en Python bytecode.

    4) Vamos a obtener 3 archivos, pero el que nos interesa es el que tiene el nombre 2.pyc_dis que al abrirlo nos muestra en comentario que se llamaba originalmente desafio26.py, el problema es que esta obfuscado (probablemente con pyobfuscate). Aún así podemos distinguir que importa la librería wave y al final del código genera un archivo twunk.dll, al ver la documentación oficial de python vemos que se esta generando realmente un archivo de audio y utiliza una cadena de caracteres que tiene muchas letras p y l y podemos pensar que es código morse (puntos y lineas). Asi que usando python interactivo podemos pasarlo facilmente a morse:

    ‘plpp pl lplp plpp pl pppl p p ppp ppp pl ll ppl p plpp pplp pp lp plpp p lpll lppp plp p p ppp p ll lll plp ppp p pp lp pppl p lp l lll plp lpp p plpp l p plpp p llp plp pl pplp lll plplp’.replace(‘p’,’.’).replace(‘l’,’-‘)

    Obtenemos:

    ‘.-.. .- -.-. .-.. .- …- . . … … .- — ..- . .-.. ..-. .. -. .-.. . -.– -… .-. . . … . — — .-. … . .. -. …- . -. – — .-. -.. . .-.. – . .-.. . –. .-. .- ..-. — .-.-.’

    Usando un decodificador en línea obtenemos:
    LA CLAVE ES SAMUELFINLEYBREESEMORSEINVENTORDELTELEGRAFO

    5) Regresamos al archivo importante.gpg, instaló Gpg4win, después dando clic derecho sobre el archivo utilizamos la opción Descifrar y verificar, nos va a pedir una contraseña, sin embargo al meterla en mayusculas no da error, la convertimos y la clave es: samuelfinleybreesemorseinventordeltelegrafo
    Finalmente obtenemos un archivo sin extensión pero con ayuda de file y renombrando a extensión jpg, al abrirlo vemos una captura de pantalla de una hoja de excel LISTADO CLIENTES.xls que será catalogada como fuga de información :D

  • Juan Esteban Valencia Pantoja

    Buenas tardes,

    De acuerdo a lo solicitado en el desafio envio la respuestas solicitadas:

    La clave del archivo es :samuelfinleybreesemorseinventordeltelegrafo

    La informacion sensible es una imagen que contiene el listado de clientes (se encuentra adjunta).

    Si se requiere un solucionario agradeceria me informen para compartirlo con la comunidad.

    Me parecio muy interesante y agradable el desafio, muchas gracias por la preparacion, elaboracion y el esfuerzo realizado.

    Ojala pueda ganarme el premio sino les agradeceria mencionarme en el blog.

    Saludos desde Colombia,

    Juan Esteban Valencia Pantoja

  • Marcelo Pedrozo

    La clave del archivo
    es SAMUELFINLEYBREESEMORSEINVENTORDELTELEGRAFO y se envía
    información sensible con el listado de los clientes y sus salarios.

    Tengo un pdf con los solución paso a paso, ¿se las facilito por algún correo?

    Saludos

  • Marcelo Pedrozo

    La clave del archivo
    es SAMUELFINLEYBREESEMORSEINVENTORDELTELEGRAFO y se envía
    información sensible con el listado de los clientes y sus salarios.

    Tengo un pdf con los solución paso a paso, ¿se las facilito por algún correo?

    Saludos
    Marcelo Pedrozo

  • Henry Sanchez

    Del archivo PCAP, verificamos que se transmitieron vía FTP 2 archivos de nombres ‘exect.exe’ y ‘importante.gpg’´, extraemos del archivo pcap ambos ficheros y tal como dicen sus extensiones se trata de un archivo EXE y un archivo gpg cifrado (se verifico utilizando el comando file) el cual requiere una clave para su descifrado la cual es desconocida por nosotros en este momento.

    Pasando al análisis del archivo ejecutable exect.exe, una rapida vista al cargarlo en ollydbg nos indica que este se encuentra empaquetado al parecer por UPX, así que hacemos uso del aplicativo upx con el flag -d para obtener el exe original desempacado:

    ~$upx -d exect.exe

    Ultimate Packer for eXecutables

    Copyright (C) 1996 – 2013

    UPX 3.91w Markus Oberhumer, Laszlo Molnar & John Reiser Sep 30th 2013

    File size Ratio Format Name

    ——————– —— ———– ———–

    3399985 <- 2192177 64.48% win32/pe exect.exe

    Unpacked 1 file.

    Obtenemos un resultado favorable, lo que confirma que efectivamente el ejecutable fue empaquetado usando UPX, sobre el nuevo ejecutable ejecutamos el comando strings obteniendo algunas cadenas un tanto interesantes:

    ~$ strings exect.exe

    ….

    PYTHONSCRIPT

    PYTHON27.DLL

    PYTHON27.DLL

    C:Python27libsite-packagespy2exeboot_common.pyR

    Could not load python dll

    PYTHON27.DLL

    PYTHON27.DLL

    LoadLibrary(pythondll) failed

    PYTHONINSPECT

    Py_SetPythonHome

    SoftwarePythonPythonCore

    PythonPath

    ….

    Esto nos lleva a sospechar que el ejecutable ha sido creado utilizando py2exe una aplicación para generar archivos portable ejecutables de windows (PE). Para obtener el archivo de código python compilado que se encuentra dentro del ejecutable utilizaremos el script unpy2exe (https://github.com/matiasb/unpy2exe), obteniendo el siguiente resultado:

    ~$ unpy2exe.py -o ./exect/ exect.exe

    Magic value: 78563412

    Code bytes length: 5544

    Archive name: –

    Extracting boot_common.py.pyc

    Extracting desafio26.py.pyc

    Hemos logrado extraer dos archivos de código python compilado, el primero de ellos “boot_common.py.pyc”, es un archivo generico que es incluido por py2exe por lo que nos centramos en analizar el segundo archivo “desafio26.py.pyc”, para esto haremos uso del script uncompyle2 (https://github.com/wibiti/uncompyle2) lo cual nos entregará un código python de alto nivel desde desafio26.py.pyc:

    ~$ python uncompyle2 desafio26.py.pyc

    # 2014.04.01 10:10:04 Hora est. del PacÝfico de SA

    #Embedded file name: desafio26.py

    import wave

    import array

    import math

    import time

    if 0:

    i11iIiiIii

    if 0:

    O0 / iIii1I11I1II1 % OoooooooOO – i1IIi

    o0OO00 = 44100

    oo = ‘plpp pl lplp plpp pl pppl p p ppp ppp pl ll ppl p plpp pplp pp lp plpp

    p lpll lppp plp p p ppp p ll lll plp ppp p pp lp pppl p lp l lll plp lpp p plpp

    l p plpp p llp plp pl pplp lll plplp’

    i1iII1IiiIiI1 = 1000

    iIiiiI1IiI1I1 = 0.2

    if 0:

    OoOoOO00

    if 0:

    OOOo0 / Oo – Ooo00oOo00o.I1IiI

    o0OOO = time.time()

    if 0:

    ooOo + Ooo0O

    IiiIII111iI = math.pi * 2

    IiII = IiiIII111iI / (float(o0OO00) / i1iII1IiiIiI1)

    iI1Ii11111iIi = iIiiiI1IiI1I1 * o0OO00

    if 0:

    I1II1

    Ooo0OO0oOO = []

    oooO0oo0oOOOO = 0.0

    O0oO = 0

    while O0oO < len(oo):

    o0oO0 = oo[O0oO]

    if 0:

    i11Ii11I1Ii1i

    Ooo = 0

    if 0:

    ooO00oOoo – O0OOo

    if o0oO0 == 'p':

    if 0:

    Oooo0000 * i1IIi11111i / I11i1i11i1I % ooIiII1I1i1i1ii / ooO00oOoo +

    OOOo0

    Ooo = iI1Ii11111iIi

    if 0:

    Ooo0O + ooO00oOoo / I11i1i11i1I.ooOo

    if o0oO0 == 'l':

    if 0:

    Oo % i11Ii11I1Ii1i.OOOo0 / ooO00oOoo * OOOo0

    Ooo = 3 * iI1Ii11111iIi

    if 0:

    OoOoOO00 + Ooo00oOo00o.I11i1i11i1I

    OoOooOOOO = 0

    while OoOooOOOO IiiIII111iI:

    oooO0oo0oOOOO = oooO0oo0oOOOO – IiiIII111iI

    OoOooOOOO = OoOooOOOO + 1

    if 0:

    i11Ii11I1Ii1i / i1IIi + i11iIiiIii – O0OOo

    if o0oO0 != ‘p’ and o0oO0 != ‘l’:

    if 0:

    Ooo00oOo00o

    OoOooOOOO = 0

    while OoOooOOOO < 2 * iI1Ii11111iIi:

    Ooo0OO0oOO.append(int(0))

    OoOooOOOO = OoOooOOOO + 1

    if 0:

    O0 – Oooo0000 / Oooo0000 + ooIiII1I1i1i1ii % ooIiII1I1i1i1ii – i

    1IIi11111i

    OoOooOOOO = 0

    while OoOooOOOO < iI1Ii11111iIi:

    Ooo0OO0oOO.append(int(0))

    OoOooOOOO = OoOooOOOO + 1

    if 0:

    Oooo0000 – i1IIi11111i – I1IiI % i1IIi / I1II1

    O0oO = O0oO + 1

    if 0:

    OoOoOO00 – OoOoOO00.OOOo0 / ooOo

    i1iIIIiI1I = ''

    OOoO000O0OO = []

    iiI1IiI = len(Ooo0OO0oOO)

    OoOooOOOO = 0

    II = 0

    if 0:

    I1II1

    while OoOooOOOO < iiI1IiI:

    if 0:

    Oo.OOOo0 / O0OOo

    IiiiI1II1I1 = Ooo0OO0oOO[OoOooOOOO]

    if IiiiI1II1I1 < 0:

    IiiiI1II1I1 = IiiiI1II1I1 + 65536

    OOoO000O0OO.append(int(IiiiI1II1I1 % 256))

    OOoO000O0OO.append(int(IiiiI1II1I1 / 256))

    if 0:

    OoooooooOO.iIii1I11I1II1

    OoOooOOOO = OoOooOOOO + 1

    II = II + 1

    if 0:

    i11Ii11I1Ii1i / OoooooooOO % ooO00oOoo – iIii1I11I1II1

    if II == 500000:

    II = 0

    if 0:

    i11iIiiIii.i11Ii11I1Ii1i / Oo * O0 % I1II1 % iIii1I11I1II1

    if 0:

    iIii1I11I1II1 – O0OOo * Ooo00oOo00o + ooOo + Oooo0000 + Oooo0000

    Ooo0OO0oOO = []

    if 0:

    Oooo0000 – Ooo00oOo00o % ooIiII1I1i1i1ii % Oooo0000 / I1IiI – Ooo00oOo00o

    if 0:

    Oooo0000 * O0

    i1iIIIiI1I = array.array('B', OOoO000O0OO).tostring()

    if 0:

    I1II1 + Oo

    Ii1I = wave.open('twunk.dll', 'wb')

    Ii1I.setparams((1,

    2,

    o0OO00,

    1,

    'NONE',

    'noncompressed'))

    Ii1I.writeframes(i1iIIIiI1I)

    Ii1I.close()

    if 0:

    i11iIiiIii / O0 * I1IiI % i11Ii11I1Ii1i % I1II1

    Ii1 = time.time()

    if 0:

    ooOo + ooO00oOoo + ooO00oOoo / OoOoOO00

    if 0:

    OoooooooOO

    if 0:

    OoooooooOO % I1IiI / ooIiII1I1i1i1ii % ooOo

    if 0:

    OoooooooOO

    +++ okay decompyling desafio26.py.pyc

    Obtenemos un código que se encuentra un poco ofuscado, del análisis del código obtenido apreciamos que se realizan operaciones sobre el string "oo = 'plpp pl lplp plpp pl pppl p p ppp ppp pl ll ppl p plpp pplp pp lp plpp p lpll lppp plp p p ppp p ll lll plp ppp p pp lp pppl p lp l lll plp lpp p plpp l p plpp p llp plp pl pplp lll plplp'" y el resultado de estas operaciones es guardado en un archivo WAV llamado 'twunk.dll'. Al reproducir este archivo notamos que el sonido se trata de código morse por lo que se puede inferir que el objetivo de la aplicación es convertir el valor de la cadena 'oo' a una representación sonora en un archivo de formato WAV, una vez llegados a esta conclusión se paso a decodificar la cadena 'oo' teniendo en cuenta que una 'p' representa a un punto '.' y 'l' representa una línea '-' en el alfabeto morse, obteniendo el siguiente resultado:

    la clave es samuelfinleybreesemorseinventordeltelegrafo

    Como dato adicional no se pudo encontrar la representación de 'plplp' el cual es el último valor de la cadena 'oo'.

    Procedemos luego a descifrar el archivo 'importante.gpg' utilizando la herramienta 'gpg', obteniendo luego un archivo, aplicamos el comando file sobre el archivo obtenido y verificamos que se trata de una imagen JPEG.

    En la imagen obtenida podemos apreciar un libro excel llamado 'LISTADO CLIENTES.xls' en el cual se aprecian datos confidenciales tales como los nombres completos de los clientes además de sus DNI, teléfono, salario y trabajo. Con la información recolectada hasta el momento podemos responder a las preguntas realizadas:

    1.- La clave es 'samuelfinleybreesemorseinventordeltelegrafo'.

    2.- El archivo 'importante.gpg' contiene información sensible sobre los datos de los clientes de la organización afectada.

    Henry Sánchez https://twitter.com/_g05u_

  • Everth J. Gallegos Puma

    LA CLAVE ES SAMUEL FIMLEY BREESE MORSE INVENTOR DEL TELETEGRAFO información del FTP: usuario23 password 12345

  • Everth J. Gallegos Puma

    existe un archivo pgp el cual la clave sale del archivo generado por el exe al decifrar se encuentra el listado de clientes de la empresa donde trabaja aparte de dicho archivo enviado existe el usuario y contraseña del ftp

  • Guest

    Buenos días Camilo.
    El martes 1 de abril te envié la respuesta al desafío.
    ¿Me podrías confirmar que te llegó?

    Desde ya muchas gracias
    Saludos
    Marcelo Pedrozo

    • Camilo Gutierrez

      Que tal Emiliano, ya acabamos de publicar la solución del desafío.

Síguenos