Contenido principal

WriteUp I'm feeling lucky - PlaidCTF 2011

Abril 25, 2011

Este fin de semana Plaid Parliament of Pwning fueron los anfitriones del plaid CTF, un concurso donde 440 equipos participaron de una serie de retos dirigidos a entusiastas y profesionales de la seguridad informática.

En total eran 38 retos que se debian resolver en 48 horas, las categorías del concurso fueron: Reversing, Web, Crypto, Trivia, Pwnables y QR Code.

Y pues bueno, un torneo grandioso donde los ganadores demostraron sus habilidades, felicitaciones a ellos y a PPP por tan genial y organizado evento!

Ahora sí, la resolución para el problema número 7: I'm feeling lucky.

WriteUp I'm Feeling lucky

Descripción

We found that one of the executives of AED keeps using 'Fortune Cookie' program everyday before he logs in to his *very* important machine.
We extracted the program, and we are certain that there's a key hidden somewhere in the binary.

Reverse engineer and get the key!

Download
http://www.plaidctf.com/chals/43e842e63a795e8f28739a018de547822382e7d3.exe

Resolución

Bueno, este es un breve resumen de lo que hice para obtener la respuesta del reto.
Lo primero que hice fue localizar el código que se ejecutaba al dar clic al botón con Ollydbg, llegando a la instrucción 00412530.

00412530  /$  68 90000000           PUSH 90
00412535  |.  B8 23DA5000           MOV EAX,43e842e6.0050DA23
0041253A  |.  E8 16550E00           CALL 43e842e6.004F7A55
0041253F  |.  8BF9                  MOV EDI,ECX
00412541  |.  33C0                  XOR EAX,EAX
00412543  |.  8945 F0               MOV [LOCAL.4],EAX
00412546  |.  C745 EC FFFFFF7F      MOV [LOCAL.5],7FFFFFFF
0041254D  |.  8B5D 08               MOV EBX,[ARG.1]
00412550  |.  8945 FC               MOV [LOCAL.1],EAX
00412553  |.  81FB 11010000         CMP EBX,111
00412559  |.  75 22                 JNZ SHORT 43e842e6.0041257D
0041255B  |.  FF75 10               PUSH [ARG.3]
0041255E  |.  8B07                  MOV EAX,DWORD PTR DS:[EDI]
00412560  |.  FF75 0C               PUSH [ARG.2]
00412563  |.  FF90 F4000000         CALL DWORD PTR DS:[EAX+F4]

En la instrucción 00412559 es donde se compara el mensaje enviado con 111 que pertenece a WM_COMMAND (Cuando se presiona el botón).
Luego de numerosas instrucciones el programa llama la función CryptDecrypt pasándole como parámetro general una llave y un texto el cual es luego mostrado como una galleta de la fortuna :)

Identifiqué todos los llamados (En orden de ejecución) a la biblioteca criptográfica de Microsoft teniendo como resultado el siguiente resumen.

4025F0:
CryptAcquireContext
|Arg1 = 0012FE40 phProv
|Arg2 = 00000000 pszContainer
|Arg3 = 00000000 pszProvider
|Arg4 = 00000001 dwProvType
\Arg5 = F0000000 dwFlags

CryptCreateHash
|Arg1 = 00188DD0 hProv
|Arg2 = 00008003 Algid (CALG_MD5)
|Arg3 = 00000000 hKey
|Arg4 = 00000000 dwFlags
\Arg5 = 0012FE48 phHash

401140:
CryptDestroyHash
\Arg1 = 00186F70 hHash

CryptCreateHash
|Arg1 = 00188DD0 hProv
|Arg2 = 00008003 Algid (CALG_MD5)
|Arg3 = 00000000 hKey
|Arg4 = 00000000 dwFlags
\Arg5 = 0012FE48 phHash

CryptHashData
|Arg1 = 00186F70 hHash
|Arg2 = 00B7ADD0 pbData (This is the key, but this is not the key you are looking for :p)
|Arg3 = 0000003F dwDataLen (63)
\Arg4 = 00000000 dwFlags

CryptDeriveKey
|Arg1 = 00188DD0 hProv
|Arg2 = 00006602 Algid (CALG_RC2)
|Arg3 = 00186F70 hBaseData
|Arg4 = 00000001 dwFlags
\Arg5 = 0012FE44 phKey

00412530:
CryptDecrypt
|Arg1 = 00189368 hKey
|Arg2 = 00000000 hHash
|Arg3 = 00000001 Final
|Arg4 = 00000000 dwFlags
|Arg5 = 00B7F570 pbData
\Arg6 = 0012F664 pdwDataLen

Luego simulé el funcionamiento y extraje la cadenas cifradas que se localizaban en el offset 140D18 del archivo ejecutable.

Creé un programa en C++ y un script en PHP que leyera archivos binarios e hiciera split (Disculpa a los lectores si la solución es un poco ortodoxa).

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <wincrypt.h>

int main(int argc, char* argv[]) {
    HCRYPTPROV hCryptProv;
    HCRYPTHASH hHash;
    HCRYPTKEY hKey;

    CryptAcquireContext(&hCryptProv, 0, 0, 1, 0xF0000000);
    CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash);

    BYTE *pbBuffer = (BYTE *)"This is the key, but this is not the key you are looking for :p";
    DWORD dwBufferLen = strlen((char *)pbBuffer);

    CryptHashData(hHash, pbBuffer, dwBufferLen, 0);
    CryptDeriveKey(hCryptProv, CALG_RC2, hHash, 1, &hKey);

    FILE *fp = fopen("filetmp.hex", "rb");

    fseek(fp, 0, SEEK_END);
    ULONG size = ftell(fp);
    unsigned char *buffer = (unsigned char*) calloc(size, sizeof(char));
    rewind(fp);
    fread(buffer, size, 1, fp);
    fclose(fp);

    CryptDecrypt(hKey, 0, 1, 0, buffer, &size);

    printf("%s\n", buffer);
    return 0;
}

Y el script de PHP que ejecutaba el anterior código

<?php
$file = file_get_contents('strings.hex'); // Obtain all ciphered strings
$file = str_replace("\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00", $file);
$file = explode("\x00\x00\x00\x00", $file); // Split based on null chars
foreach ($file as $line) { // Loop through all strings
    file_put_contents("filetmp.hex", $line); // Save the string in temporal file
    system("mission7.exe"); // Call mission7 executable
}

La respuesta se encontraba en una de las últimas galletas de la fortuna :D

Your character can be described as natural and unrestrained.
Your difficulties will strengthen you.
Oh YEAH, this is THE k3y U r L0ok1ng FOr :)
Your dreams are worth your best efforts to achieve them.
Your energy returns and you get things done.

Respuesta

Oh YEAH, this is THE k3y U r L0ok1ng FOr :)

Archivado en: Criptografía, Ingeniería Inversa, Programación |

5 comentarios

  1. Zarek Abril 25, 2011 @ 3:54 pm

    muy pasado!!! genial la resolución. gracias por compartir tanto. (seria bueno seguir con las conferencias de wargames).

  2. Juan Escobar Abril 26, 2011 @ 12:09 am

    Gracias por el solucionario y pulgar arriba para el comentario de Zarek

  3. Xylitol Abril 26, 2011 @ 10:15 am

    Thanks man

  4. kagure Abril 26, 2011 @ 8:14 pm

    Como siempre exelente que compartas las soluciones de este tipo de eventos que dificiles si son.

    Gracias. y apoyo lo de las conferencias se le extraña en publico.

  5. stuff » PlaidCTF 2011 – Division is HARD!! Abril 28, 2011 @ 1:04 pm

    [...] publico la solucion para el reto I'm feeling lucky. Y por mi parte les publicare la solucion para Division is hard, esto para ayudarle a cierto equipo [...]

Deja un comentario