CodeGate 2012 Quals – Binary 200

Find a printable string that the program would print ultimately.

Down (pw: infected)

Summary: unpack, XTEA decrypt

The program is packed PE x86 executable file (dll). The packer was easy, and it took few minute to get a unpacked file (PE tools + ImpRec).
The program consists of a lot of functions, but the most of them are not interesting for us.
The most interesting part of the program is located at address 1000169E

How you can guess “TeaDecryptEncrypt” function is my favorite and adored XTEA crypto function.
It consists of encrypt and decrypt function, but we are interested in only decrypt one.

After analysis of all parameters of function, we reconstructed whole algorithm:

#include <stdio.h>
#include <time.h>
 
#define uint32_t unsigned int
int prem_data(unsigned int *new_key, unsigned char* key)
{
  int result, i;
  result = 0;
  new_key[0] = 0;
  new_key[1] = 0;
  new_key[2] = 0;
  new_key[3] = 0;
  for ( i = 0; i < 4; ++i )
  {
    result = i;
    new_key[i] = key[4*i+3] | (key[4*i+2] << 8) | (key[4*i+1] << 16) | (key[4*i] << 24);
  }
  return result;
}
void decrypt4 (uint32_t* v, uint32_t* k, unsigned char* new_keys) 
{
    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    uint32_t delta=0x61C88647;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
 
    unsigned char* vv = (unsigned char*)v;
    v0 = vv[3] | (vv[2] << 8) | (vv[1] << 16) | (vv[0] << 24);
    v1 = vv[7] | (vv[6] << 8) | (vv[5] << 16) | (vv[4] << 24);
 
    for (i=0; i < 0x20; i++) 
    {                 
	v1 -= (((v0<<4)^(v0>>5)) + v0) ^ (sum + k[(sum>>11) & 3]);
	sum += delta;                                   
	v0 -= (((v1<<4)^(v1>>5)) + v1) ^ (sum + k[sum & 3]);                                 
 
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
 
    new_keys[0] = (unsigned char)(v0 >> 24);
    new_keys[1] = (unsigned char)(v0 >> 16);
    new_keys[2] = (unsigned char)(v0 >> 8);
    new_keys[3] = (unsigned char)v0;
    new_keys[4] = (unsigned char)(v1 >> 24);
    new_keys[5] = (unsigned char)(v1 >> 16);
    new_keys[6] = (unsigned char)(v1 >> 8);
    new_keys[7] = (unsigned char)(v1);
}
unsigned char g_data[17]   = "\x1E\xa0\xf5\xc6\xD9\xec\x02\xf6\x59\x18\x7c\x2e\x6f\x85\x5d\xde";
unsigned char hardcoded_keys[17] = "\x1E\xAE\xA1\xC7\xB3\x50\x6D\x02\x5A\x61\x33\xE4\x5B\xF0\x13\x8A";
void main()
{
	unsigned char tmp_data[17];
	prem_data((uint32_t*)tmp_data, g_data);
	decrypt4 ((uint32_t*)hardcoded_keys, (uint32_t*)tmp_data, (unsigned char*)tmp_data);
	tmp_data[8] = '\0';
	printf("Key: %s", tmp_data);
}

C:\ctf\codegate2012\bin200\tea_2\debug>tea.exe
Key: &I%W=K)l

1 comment

  1. Thanks for the writeup guys, but FYI you could find the XTEA implementation used by YUT (pretty sure of that) here : http://polarssl.org/trac/browser/trunk/library/xtea.c .
    Congratz dudes!

Leave a Reply

Your email address will not be published.