def pretty_repr(self, full_config_data): data_offset = full_config_data.find(self.binary_repr()) if data_offset < 0 and self.datatype == confConsts.TYPE_STR: self.length = 16 while self.length < 2048: data_offset = full_config_data.find(self.binary_repr()) if data_offset > 0: break self.length *= 2 if data_offset < 0: return 'Not Found' repr_len = len(self.binary_repr()) conf_data = full_config_data[data_offset + repr_len:data_offset + repr_len + self.length] if self.datatype == confConsts.TYPE_SHORT: conf_data = unpack('>H', conf_data)[0] if self.is_bool: ret = 'False' if conf_data == self.bool_false_value else 'True' return ret elif self.enum: return self.enum[conf_data] elif self.mask: ret_arr = [] for k, v in self.mask.items(): if k == 0 and k == conf_data: ret_arr.append(v) if k & conf_data: ret_arr.append(v) return ret_arr else: return conf_data elif self.datatype == confConsts.TYPE_INT: if self.is_ipaddress: return inet_ntoa(conf_data) else: conf_data = unpack('>i', conf_data)[0] if self.is_date and conf_data != 0: fulldate = str(conf_data) return "%s-%s-%s" % (fulldate[0:4], fulldate[4:6], fulldate[6:]) return conf_data if self.is_blob: if self.enum != None: ret_arr = [] i = 0 while i < len(conf_data): v = conf_data[i] if v == 0: return ret_arr v = self.enum[v] if v: ret_arr.append(v) i += 1 # Only EXECUTE_TYPE for now else: # Skipping unknown short value in the start string1 = netunpack(b'I$', conf_data[i + 3:])[0].decode() string2 = netunpack( b'I$', conf_data[i + 3 + 4 + len(string1):])[0].decode() ret_arr.append( "%s:%s" % (string1.strip('\x00'), string2.strip('\x00'))) i += len(string1) + len(string2) + 11 if self.is_transform: if conf_data == bytes(len(conf_data)): return 'Empty' ret_arr = [] prepend_length = unpack('>I', conf_data[0:4])[0] prepend = conf_data[4:4 + prepend_length] append_length_offset = prepend_length + 4 append_length = unpack( '>I', conf_data[append_length_offset:append_length_offset + 4])[0] append = conf_data[append_length_offset + 4:append_length_offset + 4 + append_length] ret_arr.append(prepend) ret_arr.append(append if append_length < 256 and append != bytes(append_length) else 'Empty') return ret_arr if self.is_malleable_stream: prog = [] fh = io.BytesIO(conf_data) while True: op = read_dword_be(fh) if not op: break if op == 1: l = read_dword_be(fh) prog.append("Remove %d bytes from the end" % l) elif op == 2: l = read_dword_be(fh) prog.append("Remove %d bytes from the beginning" % l) elif op == 3: prog.append("Base64 decode") elif op == 8: prog.append("NetBIOS decode 'a'") elif op == 11: prog.append("NetBIOS decode 'A'") elif op == 13: prog.append("Base64 URL-safe decode") elif op == 15: prog.append("XOR mask w/ random key") conf_data = prog if self.hashBlob: conf_data = conf_data.strip(b'\x00') conf_data = hashlib.md5(conf_data).hexdigest() return conf_data if self.is_headers: return self.parse_transformdata(conf_data) conf_data = conf_data.strip(b'\x00').decode() return conf_data
def pretty_repr(self, full_config_data): data_offset = full_config_data.find(self.binary_repr()) if data_offset < 0: return "Not Found" repr_len = len(self.binary_repr()) conf_data = full_config_data[data_offset + repr_len:data_offset + repr_len + self.length] if self.datatype == confConsts.TYPE_SHORT: conf_data = unpack(">H", conf_data)[0] if self.is_bool: ret = "False" if conf_data == self.bool_false_value else "True" return ret elif self.enum: return self.enum[conf_data] elif self.mask: ret_arr = [] for k, v in self.mask.items(): if k == 0 and k == conf_data: ret_arr.append(v) if k & conf_data: ret_arr.append(v) return ret_arr else: return conf_data elif self.datatype == confConsts.TYPE_INT: if self.is_ipaddress: return inet_ntoa(conf_data) else: conf_data = unpack(">I", conf_data)[0] if self.is_date and conf_data != 0: fulldate = str(conf_data) return f"{fulldate[0:4]}-{fulldate[4:6]}-{fulldate[6:]}" return conf_data if self.is_blob: if self.enum is not None: ret_arr = [] i = 0 while i < len(conf_data): v = conf_data[i] if v == 0: return ret_arr v = self.enum[v] if v: ret_arr.append(v) i += 1 # Only EXECUTE_TYPE for now else: # Skipping unknown short value in the start string1 = netunpack(b"I$", conf_data[i + 3:])[0].decode() string2 = netunpack( b"I$", conf_data[i + 3 + 4 + len(string1):])[0].decode() ret_arr.append("{}:{}".format(string1.strip("\x00"), string2.strip("\x00"))) i += len(string1) + len(string2) + 11 elif self.is_transform: if conf_data == bytes(len(conf_data)): return "Empty" ret_arr = [] prepend_length = unpack(">I", conf_data[0:4])[0] prepend = conf_data[4:4 + prepend_length].hex() append_length_offset = prepend_length + 4 append_length = unpack( ">I", conf_data[append_length_offset:append_length_offset + 4])[0] append = conf_data[append_length_offset + 4:append_length_offset + 4 + append_length].hex() ret_arr.append(prepend) ret_arr.append(append if append_length < 256 and append != bytes(append_length) else "Empty") return ret_arr elif self.is_malleable_stream: prog = [] fh = io.BytesIO(conf_data) while True: op = read_dword_be(fh) if not op: break if op == 1: l = read_dword_be(fh) prog.append(f"Remove {l} bytes from the end") elif op == 2: l = read_dword_be(fh) prog.append(f"Remove {l} bytes from the beginning") elif op == 3: prog.append("Base64 decode") elif op == 8: prog.append("NetBIOS decode 'a'") elif op == 11: prog.append("NetBIOS decode 'A'") elif op == 13: prog.append("Base64 URL-safe decode") elif op == 15: prog.append("XOR mask w/ random key") conf_data = prog else: conf_data = conf_data.hex() return conf_data if self.is_headers: conf_data = conf_data.strip(b"\x00") conf_data = [ chunk[1:].decode() for chunk in conf_data.split(b"\x00") if len(chunk) > 1 ] return conf_data conf_data = conf_data.strip(b"\x00").decode() return conf_data
def pretty_repr(self, full_config_data): data_offset = full_config_data.find(self.binary_repr()) if data_offset < 0: return "Not Found" repr_len = len(self.binary_repr()) conf_data = full_config_data[data_offset + repr_len:data_offset + repr_len + self.length] if self.datatype == confConsts.TYPE_SHORT: conf_data = unpack(">H", conf_data)[0] if self.is_bool: ret = "False" if conf_data == self.bool_false_value else "True" return ret elif self.enum: return self.enum[conf_data] elif self.mask: ret_arr = [] for k, v in self.mask.items(): if k == 0 and k == conf_data: ret_arr.append(v) if k & conf_data: ret_arr.append(v) return ret_arr else: return conf_data elif self.datatype == confConsts.TYPE_INT: if self.is_ipaddress: return inet_ntoa(conf_data) else: conf_data = unpack(">I", conf_data)[0] if self.is_date and conf_data != 0: fulldate = str(conf_data) return "%s-%s-%s" % (fulldate[0:4], fulldate[4:6], fulldate[6:]) return conf_data if self.is_blob: if self.enum != None: ret_arr = [] i = 0 while i < len(conf_data): v = conf_data[i] if v == 0: return ret_arr v = self.enum[v] if v: ret_arr.append(v) i += 1 # Only EXECUTE_TYPE for now else: # Skipping unknown short value in the start string1 = netunpack(b"I$", conf_data[i + 3:])[0].decode() string2 = netunpack( b"I$", conf_data[i + 3 + 4 + len(string1):])[0].decode() ret_arr.append( "%s:%s" % (string1.strip("\x00"), string2.strip("\x00"))) i += len(string1) + len(string2) + 11 if self.is_transform: if conf_data == bytes(len(conf_data)): return "Empty" ret_arr = [] prepend_length = unpack(">I", conf_data[0:4])[0] prepend = conf_data[4:4 + prepend_length] append_length_offset = prepend_length + 4 append_length = unpack( ">I", conf_data[append_length_offset:append_length_offset + 4])[0] append = conf_data[append_length_offset + 4:append_length_offset + 4 + append_length] ret_arr.append(prepend) ret_arr.append(append if append_length < 256 and append != bytes(append_length) else "Empty") return ret_arr return conf_data if self.is_headers: conf_data = conf_data.strip(b"\x00") conf_data = [ chunk[1:].decode() for chunk in conf_data.split(b"\x00") if len(chunk) > 1 ] return conf_data conf_data = conf_data.strip(b"\x00").decode() return conf_data