Пример #1
0
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
Пример #2
0
    def run(self, argv):
        parser = OptionParser()
        parser.add_option("-c", "--collection", action="store", dest="collection",
                type="string", help="collection (if not samples)")
        parser.add_option("-m", "--md5", action="store", dest="md5",
                type="string", help="md5 of file")
        parser.add_option("-o", "--output", action="store", dest="filename",
                type="string", help="output filename")
        (opts, args) = parser.parse_args(argv)
        data = None
        collection = opts.collection or Sample._meta['collection']
        if opts.md5:
            try:
                data = get_file(opts.md5, collection=collection)
            except:
                print "[+] could not read data for %s" % opts.md5
                return

        if data:
            if opts.filename:
                filename = opts.filename
            else:
                filename = get_filename(opts.md5, collection=collection)
            if filename == None:
                filename = opts.md5
            print "[+] writing %d bytes to %s" % (len(data), filename)
            try:
                fin = open(filename, 'wb')
                fin.write(data)
                fin.close()
            except:
                print "[+] error writing %s to disk" % filename
    def run(self, argv):
        parser = OptionParser()
        parser.add_option("-m",
                          "--md5",
                          action="store",
                          dest="md5",
                          type="string",
                          help="MD5 of file to retrieve")
        parser.add_option("-f",
                          "--file",
                          action="store",
                          dest="file",
                          type="string",
                          help="File to analyze")
        parser.add_option("-v",
                          "--verbose",
                          action="store_true",
                          dest="verbose",
                          default=False,
                          help="Be verbose")
        (opts, args) = parser.parse_args(argv)

        if opts.md5:
            if opts.verbose:
                print "[+] attempting to call get_file on %s" % opts.md5
            data = get_file(opts.md5)
        elif opts.file:
            try:
                fin = open(opts.file, 'rb')
            except IOError, e:
                print str(e)
                return
            data = fin.read()
            fin.close()
Пример #4
0
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
Пример #5
0
 def run(self, argv):
     samples = mongo_connector(settings.COL_SAMPLES)
     today = datetime.datetime.fromordinal(datetime.datetime.now().toordinal())
     md5s = samples.find({"source.instances.date": {"$gte": today}})
     filename = "%s/%s.tar.bz2" % ("/tmp/samples", today.strftime("%Y-%m-%d"))
     tar = tarfile.open(filename, "w:bz2")
     for md5 in md5s:
         m = md5['md5']
         f = md5['filename']
         s = get_file(m)
         info = tarfile.TarInfo(name="%s" % f)
         info.mtime = time.time()
         info.size = len(s)
         tar.addfile(info, StringIO(s))
     tar.close()
Пример #6
0
 def run(self, argv):
     samples = mongo_connector(settings.COL_SAMPLES)
     today = datetime.datetime.fromordinal(datetime.datetime.now().toordinal())
     md5s = samples.find({"source.instances.date": {"$gte": today}})
     filename = "%s/%s.tar.bz2" % ("/tmp/samples", today.strftime("%Y-%m-%d"))
     tar = tarfile.open(filename, "w:bz2")
     for md5 in md5s:
         m = md5['md5']
         f = md5['filename']
         s = get_file(m)
         info = tarfile.TarInfo(name="%s" % f)
         info.mtime = time.time()
         info.size = len(s)
         tar.addfile(info, BytesIO(s))
     tar.close()
Пример #7
0
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
Пример #8
0
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
Пример #9
0
    def run(self, argv):
        parser = OptionParser()
        parser.add_option("-c",
                          "--collection",
                          action="store",
                          dest="collection",
                          type="string",
                          help="collection (if not samples)")
        parser.add_option("-m",
                          "--md5",
                          action="store",
                          dest="md5",
                          type="string",
                          help="md5 of file")
        parser.add_option("-o",
                          "--output",
                          action="store",
                          dest="filename",
                          type="string",
                          help="output filename")
        (opts, args) = parser.parse_args(argv)
        data = None
        collection = opts.collection or Sample._meta['collection']
        if opts.md5:
            try:
                data = get_file(opts.md5, collection=collection)
            except:
                print "[+] could not read data for %s" % opts.md5
                return

        if data:
            if opts.filename:
                filename = opts.filename
            else:
                filename = get_filename(opts.md5, collection=collection)
            if filename == None:
                filename = opts.md5
            print "[+] writing %d bytes to %s" % (len(data), filename)
            try:
                fin = open(filename, 'wb')
                fin.write(data)
                fin.close()
            except:
                print "[+] error writing %s to disk" % filename
Пример #10
0
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"
Пример #11
0
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"
Пример #12
0
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"
Пример #13
0
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"
Пример #14
0
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
Пример #15
0
    def _scan(self, context):
        data = get_file(context.md5)
        zipdata = create_zip([("samples", data)])
        url = self.config.get('OPSWAT_url', '')

        req = urllib2.Request(url)
        req.add_header("Content-Type", "application/zip")
        req.add_data(bytearray(zipdata))
        out = urllib2.urlopen(req)
        text_out = out.read()

        # Parse XML output
        handler = XMLTagHandler()
        parser = xml.parsers.expat.ParserCreate()
        parser.StartElementHandler = handler.StartElement
        parser.EndElementHandler = handler.EndElement
        parser.CharacterDataHandler = handler.CharData
        parser.Parse(text_out)

        for threat in handler.threatList:
            self._add_result('av_result', threat["threat_name"], {"engine":threat["engine_name"], "date":datetime.now().isoformat()})
Пример #16
0
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
Пример #17
0
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
Пример #18
0
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
Пример #19
0
    def run(self, argv):
        parser = OptionParser()
        parser.add_option("-m", "--md5", action="store", dest="md5",
                type="string", help="MD5 of file to retrieve")
        parser.add_option("-f", "--file", action="store", dest="file",
                type="string", help="File to analyze")
        parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                default=False, help="Be verbose")
        (opts, args) = parser.parse_args(argv)

        if opts.md5:
            if opts.verbose:
                print "[+] attempting to call get_file on %s" % opts.md5
            data = get_file(opts.md5)
        elif opts.file:
            try:
                fin = open(opts.file, 'rb')
            except IOError, e:
                print str(e)
                return
            data = fin.read()
            fin.close()
Пример #20
0
    def run(self, argv):
        parser = OptionParser()
        parser.add_option("-m", "--md5", action="store", dest="md5",
                type="string", help="MD5 of file to retrieve")
        parser.add_option("-f", "--file", action="store", dest="file",
                type="string", help="File to analyze")
        parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                default=False, help="Be verbose")
        (opts, args) = parser.parse_args(argv)

        if opts.md5:
            if opts.verbose:
                print "[+] attempting to call get_file on %s" % opts.md5
            data = get_file(opts.md5)
        elif opts.file:
            fin = open(opts.file, 'rb')
            data = fin.read()
            fin.close()
        if opts.verbose:
            print "[+] parsing %d bytes" % len(data)
        if len(data) > 512:
            oparser = OfficeParser(data, opts.verbose)
            oparser.parse_office_doc()
Пример #21
0
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
Пример #22
0
     sys.exit(1)
 filename = None
 error_count = 0
 if opts.gridfs:
     print "Copying GridFS data matching md5s to new collection..."
     filename = opts.gridfs
 elif opts.griddelete:
     print "Deleting matching md5s from GridFS..."
     filename = opts.griddelete
 count = 0
 no_data = 0
 try:
     with open(filename) as o:
         for line in o:
             md5 = line.strip()
             data = get_file(md5, opts.collection)
             if data:
                 if opts.gridfs:
                     put_file(md5, data)
                     s = Sample.objects(md5=md5).first()
                     if s:
                         s.discover_binary()
                         try:
                             s.save()
                         except:
                             error_count += 1
                             err.write(
                                 "Error saving sample for discover binary: %s"
                                 % md5)
                 elif opts.griddelete:
                     delete_file(md5, opts.collection)
Пример #23
0
     sys.exit(1)
 filename = None
 error_count = 0
 if opts.gridfs:
     print "Copying GridFS data matching md5s to new collection..."
     filename = opts.gridfs
 elif opts.griddelete:
     print "Deleting matching md5s from GridFS..."
     filename = opts.griddelete
 count = 0
 no_data = 0
 try:
     with open(filename) as o:
         for line in o:
             md5 = line.strip()
             data = get_file(md5, opts.collection)
             if data:
                 if opts.gridfs:
                     put_file(md5, data)
                     s = Sample.objects(md5=md5).first()
                     if s:
                         s.discover_binary()
                         try:
                             s.save()
                         except:
                             error_count += 1
                             err.write("Error saving sample for discover binary: %s" % md5)
                 elif opts.griddelete:
                     delete_file(md5, opts.collection)
                 count += 1
             else: