Ejemplo n.º 1
0
def parse(workbook_path):
    vba_path = workbook_path + '.vba'
    vba_parser = VBA_Parser(workbook_path)
    vba_modules = vba_parser.extract_all_macros(
    ) if vba_parser.detect_vba_macros() else []

    for _, _, _, content in vba_modules:
        decoded_content = content.decode('latin-1')
        lines = []
        if '\r\n' in decoded_content:
            lines = decoded_content.split('\r\n')
        else:
            lines = decoded_content.split('\n')
        if lines:
            name = lines[0].replace('Attribute VB_Name = ', '').strip('"')
            content = [
                line for line in lines[1:]
                if not (line.startswith('Attribute') and 'VB_' in line)
            ]
            if content and content[-1] == '':
                content.pop(len(content) - 1)
                lines_of_code = len(content)
                non_empty_lines_of_code = len([c for c in content if c])
                if non_empty_lines_of_code > 0:
                    if not os.path.exists(os.path.join(vba_path)):
                        os.makedirs(vba_path)
                    with open(os.path.join(vba_path, name + '.bas'), 'w') as f:
                        f.write('\n'.join(content))
Ejemplo n.º 2
0
def parse(workbook_path):
    #    vba_path = 'src.vba'
    vba_path = workbook_path + '.vba'
    vba_parser = VBA_Parser(workbook_path)
    vba_modules = vba_parser.extract_all_macros(
    ) if vba_parser.detect_vba_macros() else []

    for _, _, filename, content in vba_modules:
        #        decoded_content = content.decode('latin-1')
        decoded_content = content
        lines = []
        if '\r\n' in decoded_content:
            lines = decoded_content.split('\r\n')
        else:
            lines = decoded_content.split('\n')
        if lines:
            content = []
            for line in lines:
                if line.startswith('Attribute') and 'VB_' in line:
                    if 'VB_Name' in line and KEEP_NAME:
                        content.append(line)
                else:
                    content.append(line)
            if content and content[-1] == '':
                content.pop(len(content) - 1)
                non_empty_lines_of_code = len([c for c in content if c])
                if non_empty_lines_of_code > 0:
                    if not os.path.exists(os.path.join(vba_path)):
                        os.makedirs(vba_path)
                    with open(os.path.join(vba_path, filename),
                              'w',
                              encoding='utf-8') as f:
                        f.write('\n'.join(content))
Ejemplo n.º 3
0
    def parse_vba(self, save_path):
        save = False
        vbaparser = VBA_Parser(__sessions__.current.file.path)
        # Check for Macros
        if not vbaparser.detect_vba_macros():
            self.log('error', "No Macro's Detected")
            return
        self.log('info', "Macro's Detected")
        # try:
        if True:
            an_results = {'AutoExec': [], 'Suspicious': [], 'IOC': [], 'Hex String': [], 'Base64 String': [], 'Dridex string': [], 'VBA string': []}
            for (filename, stream_path, vba_filename, vba_code) in vbaparser.extract_macros():
                self.log('info', "Stream Details")
                self.log('item', "OLE Stream: {0}".format(string_clean(stream_path)))
                self.log('item', "VBA Filename: {0}".format(string_clean(vba_filename)))
                # Analyse the VBA Code
                vba_scanner = VBA_Scanner(vba_code)
                analysis = vba_scanner.scan(include_decoded_strings=True)
                for kw_type, keyword, description in analysis:
                    an_results[kw_type].append([string_clean_hex(keyword), description])

                # Save the code to external File
                if save_path:
                    try:
                        with open(save_path, 'ab') as out:
                            out.write(vba_code)
                        save = True
                    except Exception:
                        self.log('error', "Unable to write to {0}".format(save_path))
                        return
            # Print all Tables together
            self.log('info', "AutoRun Macros Found")
            self.log('table', dict(header=['Method', 'Description'], rows=an_results['AutoExec']))

            self.log('info', "Suspicious Keywords Found")
            self.log('table', dict(header=['KeyWord', 'Description'], rows=an_results['Suspicious']))

            self.log('info', "Possible IOC's")
            self.log('table', dict(header=['IOC', 'Type'], rows=an_results['IOC']))

            self.log('info', "Hex Strings")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Hex String']))

            self.log('info', "Base64 Strings")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Base64 String']))

            self.log('info', "Dridex string")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Dridex string']))

            self.log('info', "VBA string")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['VBA string']))

            if save:
                self.log('success', "Writing VBA Code to {0}".format(save_path))
                # except:
                # self.log('error', "Unable to Process File")
        # Close the file
        vbaparser.close()
Ejemplo n.º 4
0
    def get_vba(self, myfile, source='filepath'):
        """
        Given a file, parses out the stream paths, vba code, and vba filenames for each.
        :param myfile: filename
        :param source: type of data being passed in.  Either "filepath" to indicate we need to read from disk or
        "filecontents" meaning that the file contents are being passed as a parameter.
        :return: pandas Series that can be used in concert with the pandas DataFrame apply method
        """
        if source == 'filepath':
            filedata = open(myfile, 'rb').read()
        else:
            filedata = myfile

        try:
            vbaparser = VBA_Parser('mmbot', data=filedata)
            pathnames = ''
            if vbaparser.detect_vba_macros():
                filenameslist = []
                pathnameslist = []
                vbacodelist = []
                for (filename, stream_path, filename_vba,
                     extracted_vba) in vbaparser.extract_macros():
                    vbacodelist.append(extracted_vba.decode("ascii", "ignore"))

                    if pathnames is None:
                        pathnameslist.append(
                            stream_path.decode("ascii", "ignore"))
                        filenameslist.append(
                            filename_vba.decode("ascii", "ignore"))
                    else:
                        pathnameslist.append(
                            stream_path.decode("ascii", "ignore"))
                        filenameslist.append(
                            filename_vba.decode("ascii", "ignore"))
                allcode = "\n\n\n\n".join(vbacodelist)
                filenames = ", ".join(filenameslist)
                pathnames = ", ".join(pathnameslist)

            else:
                pathnames = 'No VBA Macros found'
                filenames = 'No VBA Macros found'
                allcode = 'No VBA Macros found'

        except Exception as e:
            pathnames = 'Error:' + str(e)
            filenames = 'Error:' + str(e)
            allcode = 'Error:' + str(e)

        return pd.Series({
            'extracted_vba': allcode,
            'stream_path': pathnames,
            'filename_vba': filenames
        })
Ejemplo n.º 5
0
def get_result(filename):
    try:
        behavior = {}

        vbaparser = VBA_Parser(filename)

        if vbaparser.detect_vba_macros():
            results = vbaparser.analyze_macros()
            for item in results:
                details = re.sub(r'\(.*\)', '', str(item[2]))
                details = details.replace('strings', 'str')
                details = re.sub(r' $', '', details)
                if item[0] == 'AutoExec':
                    behavior.update({item[1]: details})
                if item[0] == 'Suspicious':
                    behavior.update({item[1]: details})

            macro = vbaparser.reveal()
            attributes = re.findall(r'Attribute VB.*',
                                    macro,
                                    flags=re.MULTILINE)
            macro = re.sub(r'Attribute VB.*', '', macro)
            vbaparser.close()
            return {
                "behavior": behavior,
                "macro": macro,
                "attributes": attributes
            }

    except:
        return {}
Ejemplo n.º 6
0
 def extract_macros(self, path) -> list:
     '''
     Extract macros
     '''
     temp_list = []
     with ignore_excpetion(Exception):
         for (temp_f, temp_s, vbaname, vbacode) in VBA_Parser(path).extract_macros():
             temp_list.append({"Name": vbaname, "VBA": vbacode})
     return temp_list
Ejemplo n.º 7
0
 def extract_macros(self, path) -> list:
     '''
     Extract macros
     '''
     List = []
     try:
         for (f, s, vbaname, vbacode) in VBA_Parser(path).extract_macros():
             List.append({"Name": vbaname, "VBA": vbacode})
     except:
         pass
     return List
Ejemplo n.º 8
0
def get_vba(workbook):
    vba_parser = VBA_Parser(workbook)
    vba_modules = vba_parser.extract_all_macros() if vba_parser.detect_vba_macros() else []

    modules = {}

    for _, _, _, content in vba_modules:
        decoded_content = content.decode('latin-1')
        lines = []
        if '\r\n' in decoded_content:
            lines = decoded_content.split('\r\n')
        else:
            lines = decoded_content.split('\n')
        if lines:
            name = lines[0].replace('Attribute VB_Name = ', '').strip('"')
            content = [line for line in lines[1:] if not (
                line.startswith('Attribute') and 'VB_' in line)]
            non_empty_lines_of_code = len([c for c in content if c])
            modules[name] = '\n'.join(content)
    return modules
Ejemplo n.º 9
0
def get_result(filename):
	try:
		behavior = {}

		vbaparser = VBA_Parser(filename)

		if vbaparser.detect_vba_macros():
			results = vbaparser.analyze_macros()
			for item in results:
				details = re.sub(r'\(.*\)', '', str(item[2]))
				details = details.replace('strings', 'str')
				details = re.sub(r' $', '', details)
				if item[0] == 'AutoExec':
					behavior.update({item[1]: details})
				if item[0] == 'Suspicious':
					behavior.update({item[1]: details})

			macro = vbaparser.reveal()
			attributes = re.findall(r'Attribute VB.*', macro, flags=re.MULTILINE)
			macro = re.sub(r'Attribute VB.*', '', macro)
			
			return {"behavior": behavior, "macro": macro, "attributes": attributes}
			vbaparser.close()
	except:
		return {}
Ejemplo n.º 10
0
    def parse_vba(self, save_path):
        save = False
        vbaparser = VBA_Parser(__sessions__.current.file.path)
        # Check for Macros
        if not vbaparser.detect_vba_macros():
            self.log('error', "No Macro's Detected")
            return
        self.log('info', "Macro's Detected")
        # try:
        if True:
            an_results = {'AutoExec': [], 'Suspicious': [], 'IOC': [], 'Hex String': [], 'Base64 String': [], 'Dridex string': [], 'VBA string': []}
            for (filename, stream_path, vba_filename, vba_code) in vbaparser.extract_macros():
                self.log('info', "Stream Details")
                self.log('item', "OLE Stream: {0}".format(string_clean(stream_path)))
                self.log('item', "VBA Filename: {0}".format(string_clean(vba_filename)))
                # Analyse the VBA Code
                vba_scanner = VBA_Scanner(vba_code)
                analysis = vba_scanner.scan(include_decoded_strings=True)
                for kw_type, keyword, description in analysis:
                    an_results[kw_type].append([string_clean_hex(keyword), description])

                # Save the code to external File
                if save_path:
                    try:
                        with open(save_path, 'ab') as out:
                            out.write(vba_code)
                        save = True
                    except:
                        self.log('error', "Unable to write to {0}".format(save_path))
                        return
            # Print all Tables together
            self.log('info', "AutoRun Macros Found")
            self.log('table', dict(header=['Method', 'Description'], rows=an_results['AutoExec']))

            self.log('info', "Suspicious Keywords Found")
            self.log('table', dict(header=['KeyWord', 'Description'], rows=an_results['Suspicious']))

            self.log('info', "Possible IOC's")
            self.log('table', dict(header=['IOC', 'Type'], rows=an_results['IOC']))

            self.log('info', "Hex Strings")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Hex String']))

            self.log('info', "Base64 Strings")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Base64 String']))

            self.log('info', "Dridex string")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['Dridex string']))

            self.log('info', "VBA string")
            self.log('table', dict(header=['Decoded', 'Raw'], rows=an_results['VBA string']))

            if save:
                self.log('success', "Writing VBA Code to {0}".format(save_path))
                # except:
                # self.log('error', "Unable to Process File")
        # Close the file
        vbaparser.close()