def xor_string(md5=None, data=None, key=0, null=0): """ XOR data. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :param key: The XOR key to use. :type key: int :param null: Whether or not to skip nulls. :type null: int (0 or 1) :returns: str """ if md5: data = get_file(md5) out = '' for c in data: if ord(c) == 0 and null == 1: out += c elif ord(c) == key and null == 1: out += c else: out += chr(ord(c) ^ key) return out
def xor_search(md5=None, data=None, string=None, skip_nulls=0): """ Search a string for potential XOR keys. Uses a small list of common plaintext terms, XORs those terms using keys 0-255 and searches the data for any match. If there is a match, that key is included in the results. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :param string: The custom string to XOR and search for. :type string: str :param skip_nulls: Whether or not to skip nulls. :type skip_nulls: int (0 or 1) :returns: list """ if md5: data = get_file(md5) if string is None or string == '': plaintext_list = [ 'This program', 'kernel32', 'KERNEL32', 'http', 'svchost', 'Microsoft', 'PE for WIN32', 'startxref', '!This program cannot be run in DOS mode', '\xD0\xCF\x11\xE0\xA1\xB1\x1a\xE1', 'D\x00o\x00c\x00u\x00m\x00e\x00n\x00t\x00 \x00S\x00u\x00m\x00m\x00a\x00r\x00y\x00 \x00I\x00n\x00f\x00o\x00r\x00m\x00a\x00t\x00i\x00o\x00n', ] else: plaintext_list = ["%s" % string] results = [] for plaintext in plaintext_list: for i in range(0, 255): xord_string = xor_string(data=plaintext, key=i, null=skip_nulls) if xord_string in data: if i not in results: results.append(i) results.sort() return results
def make_unicode_strings(md5=None, data=None): """ Find and return all printable Unicode strings in a string. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) strings_data = 'Unicode Strings\n' strings_data += "-" * 30 strings_data += "\n" unicode_regex = re.compile('(([%s]\x00){4,})' % string.printable) matches = unicode_regex.findall(data) strings_data += '\n'.join([x[0].replace('\x00', '') for x in matches]) return strings_data + "\n\n\n\n"
def make_ascii_strings(md5=None, data=None): """ Find and return all printable ASCII strings in a string. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) strings_data = 'ASCII Strings\n' strings_data += "-" * 30 strings_data += "\n" ascii_regex = re.compile('([ -~]{4,})') matches = ascii_regex.findall(data) strings_data += '\n'.join([x for x in matches]) return strings_data + "\n\n\n\n"
def make_hex(md5=None, data=None): """ Convert data into hex formatted output. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) length = 16 hex_data = '' digits = 4 if isinstance(data, unicode) else 2 for i in xrange(0, len(data), length): s = data[i:i+length] hexa = ' '.join(["%0*X" % (digits, ord(x)) for x in s]) text = ' '.join([x if 0x20 <= ord(x) < 0x7F else '.' for x in s]) hex_data += "%04X %-*s %s\r\n" % (i, length*(digits + 1), hexa, text) return hex_data
def make_stackstrings(md5=None, data=None): """ Find and return all stack strings in a string. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) x = 0 prev = 0 strings = '' while x < len(data): if (data[x] == '\xc6') and ((data[x + 1] == '\x45') or (data[x + 1] == '\x84')): a = ord(data[x + 3]) if (a <= 126 and a >= 32) or (a == 9): strings += data[x + 3] prev = x x += 4 elif (data[x] == '\xc6') and (data[x + 1] == '\x44'): a = ord(data[x + 4]) if (a <= 126 and a >= 32) or (a == 9): strings += data[x + 4] prev = x x += 5 elif (data[x] == '\xc6') and ((data[x + 1] == '\x05') or (data[x + 1] == '\x85')): a = ord(data[x + 6]) if (a <= 126 and a >= 32) or (a == 9): strings += data[x + 6] prev = x x += 7 else: if ((x - prev) == 12): strings += '\n' x += 1 strings = strings.replace('\x00', '\r') return strings
def make_hex(md5=None, data=None): """ Convert data into hex formatted output. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) length = 16 hex_data = '' digits = 4 if isinstance(data, unicode) else 2 for i in xrange(0, len(data), length): s = data[i:i + length] hexa = ' '.join(["%0*X" % (digits, ord(x)) for x in s]) text = ' '.join([x if 0x20 <= ord(x) < 0x7F else '.' for x in s]) hex_data += "%04X %-*s %s\r\n" % (i, length * (digits + 1), hexa, text) return hex_data
def make_stackstrings(md5=None, data=None): """ Find and return all stack strings in a string. :param md5: The MD5 of the Sample to parse. :type md5: str :param data: The data to parse. :type data: str :returns: str """ if md5: data = get_file(md5) x = 0 prev = 0 strings = '' while x < len(data): if (data[x] == '\xc6') and ((data[x+1] == '\x45') or (data[x+1] == '\x84')): a = ord(data[x+3]) if (a <= 126 and a >= 32) or (a==9): strings += data[x+3] prev = x x += 4 elif (data[x] == '\xc6') and (data[x+1] == '\x44'): a = ord(data[x+4]) if (a <= 126 and a >= 32) or (a==9): strings += data[x+4] prev = x x += 5 elif (data[x] == '\xc6') and ((data[x+1] == '\x05') or (data[x+1] == '\x85')): a = ord(data[x+6]) if (a <= 126 and a >= 32) or (a==9): strings += data[x+6] prev = x x += 7 else: if ((x - prev) ==12): strings += '\n' x += 1 strings = strings.replace('\x00', '\r') return strings