Post

Sekure Decrypt


The challenge files includes a core dump (core), an ELF binary (dec) and a source code (src.c) written in C. The dec binary might have crash because of segmentation fault and dumped the core.

1
2
3
4
$ file *
core:  ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from './dec', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: './dec', platform: 'x86_64'
dec:   ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=daf03fccbc32333244dc0f36e874e27457110af1, for GNU/Linux 3.2.0, with debug_info, not stripped
src.c: C source, ASCII text

The content of ‘src.c’ file is below, which will read ‘flag.enc’ file content, decrypts with AES algorithm and print the decrypted content. The decrypted content might be the flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mcrypt.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>

int encrypt(void* buffer, int buffer_len, char* IV, char* key, int key_len) {
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);

  if( buffer_len % blocksize != 0 ) { 
    return 1; 
  }

  mcrypt_generic_init(td, key, key_len, IV);
  mcrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  
  return 0;
}

int decrypt(void* buffer, int buffer_len, char* IV, char* key, int key_len) {
  MCRYPT td = mcrypt_module_open("rijndael-128", NULL, "cbc", NULL);
  int blocksize = mcrypt_enc_get_block_size(td);

  if( buffer_len % blocksize != 0 ){ 
    return 1;
  }
  
  mcrypt_generic_init(td, key, key_len, IV);
  mdecrypt_generic(td, buffer, buffer_len);
  mcrypt_generic_deinit (td);
  mcrypt_module_close(td);
  
  return 0;
}

void* read_file(char* filename, int len) {
  FILE *fp = fopen(filename, "rb");
  void* data = malloc(len);
  fread(data, 1, len, fp);
  fclose(&fp);
  return data;
}

int main(int argc, char* argv[]) // gcc src.c -o dec -lmcrypt -ggdb
{
  char* IV = "AAAAAAAAAAAAAAAA";
  char *key = getenv("KEY");
  int keysize = 16;
  char* buffer;
  int buffer_len = 16;

  void *ciphertext = read_file("flag.enc", buffer_len);
  decrypt(ciphertext, buffer_len, IV, key, keysize);
  printf("Decrypted contents: %s\n", ciphertext);

  return 0;
}

Looks like we need to recreate this. But we do not have the key of AES algorithm and the cipher text.

The key can be retrieved from the core dump.

1
2
3
$ strings core | grep KEY
KEY=
KEY=VXISlqY>Ve6D<{#F

In the ‘src.c’ source code above, after reading the content of the ‘flag.enc’ file, it is allocated in memory using malloc(), which means it resides in the heap. To determine the location of the heap, we can use GDB for verification.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ gdb -q ./dec
Reading symbols from ./dec...

(gdb) r
Starting program: /home/remnux/HTB/RE/Sekure Decrypt/dec 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e0be85 in __GI__IO_fread (buf=0x555555559480, size=1, count=16, fp=0x0) at iofread.c:35
35	iofread.c: No such file or directory.

(gdb) info proc mapping
process 3930
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
      0x555555554000     0x555555555000     0x1000        0x0 /home/remnux/HTB/RE/Sekure Decrypt/dec
      0x555555555000     0x555555556000     0x1000     0x1000 /home/remnux/HTB/RE/Sekure Decrypt/dec
      0x555555556000     0x555555557000     0x1000     0x2000 /home/remnux/HTB/RE/Sekure Decrypt/dec
      0x555555557000     0x555555558000     0x1000     0x2000 /home/remnux/HTB/RE/Sekure Decrypt/dec
      0x555555558000     0x555555559000     0x1000     0x3000 /home/remnux/HTB/RE/Sekure Decrypt/dec
      0x555555559000     0x55555557a000    0x21000        0x0 [heap]
      0x7ffff7d86000     0x7ffff7d89000     0x3000        0x0 
      0x7ffff7d89000     0x7ffff7dab000    0x22000        0x0 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7dab000     0x7ffff7f23000   0x178000    0x22000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7f23000     0x7ffff7f71000    0x4e000   0x19a000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7f71000     0x7ffff7f75000     0x4000   0x1e7000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7f75000     0x7ffff7f77000     0x2000   0x1eb000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
      0x7ffff7f77000     0x7ffff7f7b000     0x4000        0x0 
      0x7ffff7f7b000     0x7ffff7f81000     0x6000        0x0 /usr/lib/libmcrypt.so.4.4.8
      0x7ffff7f81000     0x7ffff7f9a000    0x19000     0x6000 /usr/lib/libmcrypt.so.4.4.8
      0x7ffff7f9a000     0x7ffff7fa7000     0xd000    0x1f000 /usr/lib/libmcrypt.so.4.4.8
      0x7ffff7fa7000     0x7ffff7fa9000     0x2000    0x2b000 /usr/lib/libmcrypt.so.4.4.8
      0x7ffff7fa9000     0x7ffff7fab000     0x2000    0x2d000 /usr/lib/libmcrypt.so.4.4.8
      0x7ffff7fab000     0x7ffff7fb2000     0x7000        0x0 
      0x7ffff7fcb000     0x7ffff7fce000     0x3000        0x0 [vvar]
      0x7ffff7fce000     0x7ffff7fcf000     0x1000        0x0 [vdso]
      0x7ffff7fcf000     0x7ffff7fd0000     0x1000        0x0 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7fd0000     0x7ffff7ff3000    0x23000     0x1000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ff3000     0x7ffff7ffb000     0x8000    0x24000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x2c000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x2d000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]

In the output, it is evident that the heap memory is located immediately below the memory region allocated for the ‘dec’ ELF binary.

Now we know where the ‘flag.enc’ file content will be allocated. We can analyze the core dump using pwn tools to find the heap in the core dump.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ python3 -q

>>> from pwn import Corefile

>>> core = Corefile('core')
[x] Parsing corefile...
[*] '/home/remnux/HTB/RE/Sekure Decrypt/core'
    Arch:      amd64-64-little
    RIP:       0x7fca32b0f3eb
    RSP:       0x7fff92e111e0
    Exe:       '/home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec' (0x562e29888000)
    Fault:     0x1f204
[+] Parsing corefile...: Done

>>> print('\n'.join([str(mapping) for mapping in core.mappings]))
562e29888000-562e29889000 r--p 1000 /home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec
562e29889000-562e2988a000 r-xp 1000 /home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec
562e2988a000-562e2988b000 r--p 1000 /home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec
562e2988b000-562e2988c000 r--p 1000 /home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec
562e2988c000-562e2988d000 rw-p 1000 /home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec
562e2adce000-562e2adef000 rw-p 21000 
7fca32ac6000-7fca32ac9000 rw-p 3000 
7fca32ac9000-7fca32aee000 r--p 25000 /usr/lib/x86_64-linux-gnu/libc-2.30.so
7fca32aee000-7fca32c66000 r-xp 178000 /usr/lib/x86_64-linux-gnu/libc-2.30.so
7fca32c66000-7fca32cb0000 r--p 4a000 /usr/lib/x86_64-linux-gnu/libc-2.30.so
7fca32cb0000-7fca32cb3000 r--p 3000 /usr/lib/x86_64-linux-gnu/libc-2.30.so
7fca32cb3000-7fca32cb6000 rw-p 3000 /usr/lib/x86_64-linux-gnu/libc-2.30.so
7fca32cb6000-7fca32cba000 rw-p 4000 
7fca32cba000-7fca32cc0000 r--p 6000 /usr/lib/libmcrypt.so.4.4.8
7fca32cc0000-7fca32cd9000 r-xp 19000 /usr/lib/libmcrypt.so.4.4.8
7fca32cd9000-7fca32ce6000 r--p d000 /usr/lib/libmcrypt.so.4.4.8
7fca32ce6000-7fca32ce8000 r--p 2000 /usr/lib/libmcrypt.so.4.4.8
7fca32ce8000-7fca32cea000 rw-p 2000 /usr/lib/libmcrypt.so.4.4.8
7fca32cea000-7fca32cf1000 rw-p 7000 
7fca32d12000-7fca32d13000 r--p 1000 /usr/lib/x86_64-linux-gnu/ld-2.30.so
7fca32d13000-7fca32d35000 r-xp 22000 /usr/lib/x86_64-linux-gnu/ld-2.30.so
7fca32d35000-7fca32d3d000 r--p 8000 /usr/lib/x86_64-linux-gnu/ld-2.30.so
7fca32d3d000-7fca32d3e000 rw-p 1000 
7fca32d3e000-7fca32d3f000 r--p 1000 /usr/lib/x86_64-linux-gnu/ld-2.30.so
7fca32d3f000-7fca32d40000 rw-p 1000 /usr/lib/x86_64-linux-gnu/ld-2.30.so
7fca32d40000-7fca32d41000 rw-p 1000 
7fff92df3000-7fff92e14000 rw-p 21000 [stack]
7fff92f4d000-7fff92f50000 r--p 3000 
7fff92f50000-7fff92f51000 r-xp 1000 [vdso]
ffffffffff600000-ffffffffff601000 --xp 1000 [vsyscall]

Now we know from core dump that the heap is located at offset 0x562e2adce000 to offset 0x562e2adef000.

I had written a python script that will search the heap for each 16 byte value and AES decrypt to find potential flag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from pwn import Corefile
from Crypto.Cipher import AES

def extractPossibleFlag(corePath, startAddress, size, key, iv):
    core = Corefile(corePath)
    data = core.read(startAddress, size)

    for i in range(0, len(data), 16):
        chunk = data[i:i+16]

        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypted = cipher.decrypt(chunk)

        if decrypted.startswith(b'HTB'):
            return decrypted

def main():
    corePath = 'core'
    startAddress = 0x562e2adce000
    size = 2000    
    key = b'VXISlqY>Ve6D<{#F'
    iv = b'A' * 16

    flag = extractPossibleFlag(corePath, startAddress, size, key, iv)
    print(flag)

if __name__ == "__main__":
    main()
1
2
3
4
5
6
7
8
9
10
11
$ python3 ./decode.py 

[+] Parsing corefile...: Done
[*] '/home/remnux/HTB/RE/Sekure Decrypt/core'
    Arch:      amd64-64-little
    RIP:       0x7fca32b0f3eb
    RSP:       0x7fff92e111e0
    Exe:       '/home/user/Documents/RE/easy/Sekure Decrypt/release/debug/dec' (0x562e29888000)
    Fault:     0x1f204
    
b'HTB{t1m_l3arn_C}'

This post is licensed under CC BY 4.0 by the author.

Trending Tags