Windows 7 Challenge: Some guy found this pcap and executable. Ready, set, go!

Challenge Created By: Josh Grunzweig @jgrunzweig

For this challenge, users were given both a PCAP and a Windows executable file. Taking a quick look at the PCAP file, we see there are a number of individual connections from 172.16.95.1 to 172.16.95.190, each about the same size.

Figure 1 Connections in G0blinKing pcap file

Looking at a specific connection, we see that each one is transferring a single byte of data at a time.

Figure 2 Data in stream 0 for G0blinKing pcap file

Presumably, we can come to the conclusion that some data is being sent from one host to another, one byte at a time. To determine what data has been generated, we need to look at the Windows executable file.

Opening the file, we see a minor Easter egg, where the pdb string was overwritten.

Figure 3 Overwritten pdb path

Unfortunately for this file, it doesn’t disassemble terribly well, and we see a number of functions that simply jump to the actual function containing the relevant code. This is just a byproduct of how the file was compiled. Looking through the code, however, we can see that the actual core functionality of the code starts at a function at offset 0x412300.

Performing a quick triage of the sample and the functions that are called, we can get a high-level overview of what is going on. Note that I’ve renamed a few of the functions in the figure below based on guesses as to what the functions may be doing.

Figure 4 Main function of executable

So, we can safely conclude that some form of encryption is being performed against the data contained in file.txt, it’s then being encoded, and then sent across the network, where the PCAP was generated from. At this point we simply need to identify what is happening during encryption and encoding respectively.

For encryption, we track down a function that looks to be primarily responsible. We also identify a string aptly named ‘AWildKeyAppears!’, which is most likely going to be the key used for encryption. Looking at the beginning of this function, we identify a number of constants as seen in the following figure.

Figure 5 Encryption function

A number of these constants turn out to be red herrings. However, if we look at the constant of 0x9E3769B9, we see that this constant is used in the TEA/XTEA encryption algorithms. Further review of this function shows us that we’re simply dealing with XTEA, with a few red herrings thrown in. The following original source code shows what it looked like prior to compilation.

unsigned int key[4] = {0x6c695741, 0x79654b64, 0x65707041, 
0x21737261};

#define BLOCK_SIZE 8

void xtea_encipher(unsigned int num_rounds, uint32_t v[2], 
uint32_t const key[4]) {
    unsigned int i;
    uint32_t j, o, s, h;
    j = 0xBADA55;
    uint32_t delta = 0x9e3769b9;
    o = 0x4913092;
    s = 0x12345678;
    h = 0xDEADBEEF;
    uint32_t v0=v[0], v1=v[1], sum=0;
    for (i=0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 
3]);
        j += 4092;
        o -+ 4092;
        for (int x = 8; x < 32; x++) {
          s = s*8;
          j -= 64;
          o -= 8;
        }
        h = 64;
        sum += (delta + 4096);
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + 
key[(sum>>11) & 3]);
    }
    v[0]=v0; 
    v[1]=v1;
}

Now we can move onto the encoding function. At a quick glance, it looks to be base64. However, if we look at the alphabet, it does not look to be standard. The following is the traditional base64 alphabet.

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

This is the alphabet discovered within the Windows executable.

qtgJYKa8y5L4flzMQ/BsGpSkHIjhVrm3NCAi9cbeXvuwDx+R6dO7ZPEno21T0UFW

Knowing this, we can now create a script that will both parse the PCAP file and decrypt the contents sent across the wire. The following script was created to accomplish this.

import string
import dpkt
import sys
import base64
import struct


def xtea_decrypt(key,block, n=32, endian="!"):
  v0,v1 = struct.unpack(endian+"2L",block)
  k = struct.unpack(endian+"4L",key)
  delta,mask = 0x9e3779b9L,0xffffffffL
  sum = (delta * n) & mask
  for round in range(n):
    v1 = (v1 - (((v0<<4 ^ v0>>5) + v0) ^ (sum + k[sum>>11 & 
3]))) & mask
    sum = (sum - delta) & mask
    v0 = (v0 - (((v1<<4 ^ v1>>5) + v1) ^ (sum + k[sum & 3]))) & 
mask
  return struct.pack(endian+"2L",v0,v1)

all_data = ""

def parse_pcap_file(filename):
  global all_data
  f = open(filename)
  pcap = dpkt.pcap.Reader(f)
  for ts, buf in pcap:
    eth = dpkt.ethernet.Ethernet(buf)
    ip = eth.data
    tcp = ip.data
    if tcp.dport == 8080 and len(tcp.data) > 0:
      all_data += tcp.data

if __name__ == '__main__':
  if len(sys.argv) <= 1:
    print "%s [pcap file]" % __file__
    sys.exit(2)
  parse_pcap_file(sys.argv[1])

new_b64_chars  = 
"qtgJYKa8y5L4flzMQ/BsGpSkHIjhVrm3NCAi9cbeXvuwDx+R6dO7ZPEno21T0UF
W"
old_b64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+
/"

all_data = all_data.translate(string.maketrans(new_b64_chars, 
old_b64_chars))
data = base64.b64decode(all_data)

result = ""
key = 'AWildKeyAppears!'
for x in range(0, len(data)/8):
  o = xtea_decrypt(key, data[8*x:8*x+8], endian="<")
  result += o
print result

Running this script against the provided PCAP file, we’re presented with the following output.

PADDINGPADDINGPADDINGPADDINGPADDINGPADDINGPADDINGPADDINGP
PAN{did_1_mention_th0se_pupp3ts_fr34ked_m3_out_recent1y?}
PADDINGPADDINGPADDINGhibobPADDINGPADDINGPADDINGPAD

PAN{did_1_mention_th0se_pupp3ts_fr34ked_m3_out_recent1y?}