예제 #1
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, 'a') 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()
예제 #2
0
파일: office.py 프로젝트: asymptotic/viper
 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, 'a') 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()
예제 #3
0
def scan_macro(vba_code):
   
   SCAN = {}

   vba_scanner = VBA_Scanner(vba_code)
   results = vba_scanner.scan(include_decoded_strings=False)
   for key, subiter in itertools.groupby(results, operator.itemgetter(0)):
      groups = []
      groups.extend(['%s: %s' % (desc[1], desc[2]) for desc in subiter])
      SCAN['%s' % key] = groups

   if not SCAN:
      return 'No results from scan'

   return SCAN
예제 #4
0
def scan_macro(vba_code):

    SCAN = {}

    vba_scanner = VBA_Scanner(vba_code)
    results = vba_scanner.scan(include_decoded_strings=False)
    for key, subiter in itertools.groupby(results, operator.itemgetter(0)):
        groups = []
        groups.extend(['%s: %s' % (desc[1], desc[2]) for desc in subiter])
        SCAN['%s' % key] = groups

    if not SCAN:
        return 'No results from scan'

    return SCAN
예제 #5
0
    def process(self, sample, tag):
        try:
            hashbot      = Hasher(sample)
            mymagic      = magic.Magic(mime=True)
            sample_info  = self.identify_sample(oletools.oleid.OleID(sample))
            vba          = VBA_Parser(sample)
    
            # Extend the results of sample_info with extra data and add to Splunk
            sample_info['submit_date']   = int(time())
            sample_info['filetype']      = mymagic.from_file(sample)
            sample_info['sample_type']   = 'office'
            sample_info['id_tag']        = tag
            sample_info['sha1']          = hashbot.get_sha1()
            sample_info['md5']           = hashbot.get_md5()
            indicators                   = dict()

            if self.doc_has_macros(vba):
                macro = self.macro_extraction(vba)
                data  = VBA_Scanner(macro['vba_code']).scan(include_decoded_strings=False)
    
                i = 1
                for kw_type, keyword, description in data:
                    indicators[str(i)] = {'type':kw_type, 
                                          'keyword':keyword, 
                                          'description':description
                                         } 
                    i+=1

            sample_info['indicators'] = indicators
            self.share_data(sample_info)
            self.store_sample(sample)
        except Exception, e:
            print "Error on",sample,e
예제 #6
0
    def parse_vba(self, save_path):
        """
        Parse VBA scripts.
        """
        save = False
        vbaparser = VBA_Parser(__sessions__.current.file.path)
        # Check for Macros
        if not vbaparser.detect_vba_macros():
            self.log("error", "No macros detected")
            return
        self.log("info", "Macros 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, "a") as out:
                            out.write(vba_code)
                        save = True
                    except Exception as e:
                        self.log(
                            "error",
                            "Unable to write to {0}: {1}".format(save_path, e))
                        return

            # Print all tables together
            if an_results["AutoExec"]:
                self.log("info", "Autorun macros found")
                self.log(
                    "table",
                    dict(header=["Method", "Description"],
                         rows=an_results["AutoExec"]))

            if an_results["Suspicious"]:
                self.log("info", "Suspicious keywords found")
                self.log(
                    "table",
                    dict(header=["Keyword", "Description"],
                         rows=an_results["Suspicious"]))

            if an_results["IOC"]:
                self.log("info", "Possible IOCs")
                self.log("table",
                         dict(header=["IOC", "Type"], rows=an_results["IOC"]))

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

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

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

            if an_results["VBA string"]:
                self.log("info", "VBA strings")
                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))

        # Close the file
        vbaparser.close()
예제 #7
0
 print ('error', "macro not detected ")
 #경고모듈 넣는 위치 
 sys.exit(1)

print ('info', "macro detected ! ")

for (filename, stream_path, vba_filename, vba_code) in vbaparser.extract_macros():
  print ("- "*79)
  print ("filename    :", filename)
  print ("OLE stream  :", stream_path)
  print ("VBA filename:", vba_filename)
  print ("- "*39)
  print ("vba_code",vba_code)

     
vba_scanner = VBA_Scanner(vba_code)
results = vba_scanner.scan(include_decoded_strings=True)
for kw_type, keyword, description in results:
 print ("type=%s - keyword=%s - description=%s" % (kw_type, keyword, description))
     
autoexec_keywords = detect_autoexec(vba_code)
if autoexec_keywords:
 print("Auto-executable Macro keyword is detected. :")
for keyword, description in autoexec_keywords:
   print("%s: %s' % (keyword, description)")
else:
 print ("Auto-executable Macro keywords is not detected.")

results = vbaparser.analyze_macros()
for kw_type, keyword, description in results:
 print ("type=%s - keyword=%s - description=%s" % (kw_type, keyword, description))
예제 #8
0
    vba = VBA_Parser(filepath)
    result = {'Suspicious': False, 'Base64 Strings': False, 'Hex Strings': False, 'Version': olevbaVersion}
except TypeError:
    result = {'Error': redir_err.getvalue() }
    json_data = json.dumps(result, indent=4)
    print json_data
    sys.exit()

# set stderr back to original __stderr__ 
sys.stderr = sys.__stderr__

if vba.detect_vba_macros():
    result['vba'] = 'VBA Macros found'
    streams = []
    for (filename, stream_path, vba_filename, vba_code) in vba.extract_macros():
        vba_scanner = VBA_Scanner(vba_code)
        scan_results = vba_scanner.scan(include_decoded_strings=False)
        vba_scan_results = []
        for kw_type, keyword, description in scan_results:
            vba_scan_results.append({'type': kw_type, 'keyword': keyword, 'description': description})
            if (kw_type == 'Suspicious'):
                result['Suspicious'] = True
            if (keyword == 'Base64 Strings'):
                result['Base64 Strings'] = True
            if (keyword == 'Hex Strings'):
                result['Hex Strings'] = True

        streams.append({'Filename': filename, 'OLE stream': stream_path, 'VBA filename': vba_filename, 
            'VBA code': vba_code, 'scan_result': vba_scan_results })
    result['streams'] = streams
else:
예제 #9
0
    def macro_scorer(self, text):
        self.log.debug("Macro scorer running")
        score_section = None

        try:
            vba_scanner = VBA_Scanner(text)
            vba_scanner.scan(include_decoded_strings=True)

            for string in self.ADDITIONAL_SUSPICIOUS_KEYWORDS:
                if re.search(string, text, re.IGNORECASE):
                    # play nice with detect_suspicious from olevba.py
                    vba_scanner.suspicious_keywords.append((string, 'May download files from the Internet'))

            stringcount = len(vba_scanner.autoexec_keywords) + len(vba_scanner.suspicious_keywords) + \
                len(vba_scanner.iocs)

            if stringcount > 0:
                score_section = ResultSection(SCORE.NULL, "Interesting macro strings found")

                if len(vba_scanner.autoexec_keywords) > 0:
                    subsection = ResultSection(min(self.MAX_STRING_SCORE,
                                                   SCORE.LOW * len(vba_scanner.autoexec_keywords)),
                                               "Autoexecution strings")

                    for keyword, description in vba_scanner.autoexec_keywords:
                        subsection.add_line(keyword)
                        subsection.add_tag(TAG_TYPE.OLE_MACRO_SUSPICIOUS_STRINGS,
                                           keyword, TAG_WEIGHT.HIGH,
                                           usage=TAG_USAGE.IDENTIFICATION)
                    score_section.add_section(subsection)

                if len(vba_scanner.suspicious_keywords) > 0:
                    subsection = ResultSection(min(self.MAX_STRING_SCORE,
                                                   SCORE.MED * len(vba_scanner.suspicious_keywords)),
                                               "Suspicious strings or functions")

                    for keyword, description in vba_scanner.suspicious_keywords:
                        subsection.add_line(keyword)
                        subsection.add_tag(TAG_TYPE.OLE_MACRO_SUSPICIOUS_STRINGS,
                                           keyword, TAG_WEIGHT.HIGH,
                                           usage=TAG_USAGE.IDENTIFICATION)
                    score_section.add_section(subsection)

                if len(vba_scanner.iocs) > 0:
                    subsection = ResultSection(min(500, SCORE.MED * len(vba_scanner.iocs)),
                                               "Potential host or network IOCs")

                    scored_macro_uri = False
                    for keyword, description in vba_scanner.iocs:
                        # olevba seems to have swapped the keyword for description during iocs extraction
                        # this holds true until at least version 0.27

                        subsection.add_line("{}: {}".format(keyword, description))
                        desc_ip = self.ip_re.match(description)
                        if self.parse_uri(description) is True:
                            scored_macro_uri = True
                        elif desc_ip:
                            ip_str = desc_ip.group(1)
                            if not is_ip_reserved(ip_str):
                                scored_macro_uri = True
                                subsection.add_tag(TAG_TYPE.NET_IP,
                                                   ip_str,
                                                   TAG_WEIGHT.HIGH,
                                                   usage=TAG_USAGE.CORRELATION)
                    score_section.add_section(subsection)
                    if scored_macro_uri and self.scored_macro_uri is False:
                        self.scored_macro_uri = True
                        scored_uri_section = ResultSection(score=500,
                                                           title_text="Found network indicator(s) within macros")
                        self.ole_result.add_section(scored_uri_section)

        except Exception as e:
            self.log.debug("OleVBA VBA_Scanner constructor failed: {}".format(str(e)))

        return score_section
예제 #10
0
    def olevba_info(self):

        try:
            __import__('imp').find_module('oletools')
            from oletools.olevba import VBA_Parser, VBA_Scanner
            from oletools.olevba import __version__ as olevbaVersion
        except ImportError:
            self.error('Import Error: Module oletools not found')
        # Redirect stderr to devnull in case input file is not a valid office document. When parsing a non valid
        # document VBA Parser raises an error to stderr.
        redir_err = sys.stderr = StringIO()
        try:
            vba = VBA_Parser(self.path)
            result = {
                'Suspicious': False,
                'Base64 Strings': False,
                'Hex Strings': False,
                'Version': olevbaVersion
            }
        except TypeError:
            self.error('File type error: ' + redir_err.getvalue())

        # set stderr back to original __stderr__
        sys.stderr = sys.__stderr__

        if vba.detect_vba_macros():
            result['vba'] = 'VBA Macros found'
            streams = []
            for (filename, stream_path, vba_filename,
                 vba_code) in vba.extract_macros():
                vba_scanner = VBA_Scanner(vba_code)
                scan_results = vba_scanner.scan(include_decoded_strings=False)
                vba_scan_results = []
                for kw_type, keyword, description in scan_results:
                    vba_scan_results.append({
                        'type':
                        str(kw_type).encode('utf-8'),
                        'keyword':
                        str(keyword).encode('utf-8'),
                        'description':
                        str(description).encode('utf-8')
                    })

                    if (kw_type == 'Suspicious'):
                        result['Suspicious'] = True
                    if (keyword == 'Base64 Strings'):
                        result['Base64 Strings'] = True
                    if (keyword == 'Hex Strings'):
                        result['Hex Strings'] = True

                streams.append({
                    'Filename':
                    self.filename,
                    'OLE stream':
                    stream_path,
                    'VBA filename':
                    vba_filename.decode('unicode-escape').encode('utf-8'),
                    'VBA code':
                    vba_code.decode('unicode-escape').encode('utf-8'),
                    'scan_result':
                    vba_scan_results
                })
            result['streams'] = streams
        else:
            result['vba'] = 'No VBA Macros found'

        return result
예제 #11
0
    #details_path = os.path.join(macro_dir, 'macro_{0}.details'.format(macro_index))
    #with codecs.open(details_path, 'w', encoding='unicode_escape') as fp:
    #try:
    #fp.write(u'filename: {0}\nstream_path: {1}\nvba_filename: {2}\n'.format(
    #filename,
    #stream_path,
    #unicode(vba_filename, 'unicode_escape')))
    #except:
    #traceback.print_exc()

    #sys.stdout.write(details_path + '\n')

    macro_json['analysis'] = []

    scanner = VBA_Scanner(vba_code)
    #analysis_path = os.path.join(macro_dir, 'macro_{0}.analysis'.format(macro_index))
    kw_counts = {}  # key = keyword, value = int
    #with open(analysis_path, 'w') as fp:
    for kw_type, keyword, description in scanner.scan(
            include_decoded_strings=True):
        macro_json['analysis'].append({
            'kw_type':
            unicode(kw_type, encoding='utf-8', errors='replace'),
            'keyword':
            unicode(
                keyword,
                encoding='utf-8',
                errors='replace',
            ),
            'description':