Commit a136731b24ddb2d9ce938d79d6f3123d77c454a6

Authored by Philippe Lagadec
1 parent 99e9238e

olevba: added suspicious keywords detection

Showing 1 changed file with 66 additions and 1 deletions
oletools/olevba.py
@@ -87,8 +87,9 @@ Usage: olevba.py <file> @@ -87,8 +87,9 @@ Usage: olevba.py <file>
87 # 2014-12-14 v0.07 PL: - detect_autoexec() is now case-insensitive 87 # 2014-12-14 v0.07 PL: - detect_autoexec() is now case-insensitive
88 # 2014-12-15 v0.08 PL: - improved display for empty macros 88 # 2014-12-15 v0.08 PL: - improved display for empty macros
89 # - added pattern extraction 89 # - added pattern extraction
  90 +# 2014-12-25 v0.09 PL: - added suspicious keywords detection
90 91
91 -__version__ = '0.08' 92 +__version__ = '0.09'
92 93
93 #------------------------------------------------------------------------------ 94 #------------------------------------------------------------------------------
94 # TODO: 95 # TODO:
@@ -162,6 +163,36 @@ AUTOEXEC_KEYWORDS = { @@ -162,6 +163,36 @@ AUTOEXEC_KEYWORDS = {
162 #TODO: full list in MS specs?? 163 #TODO: full list in MS specs??
163 } 164 }
164 165
  166 +# Suspicious Keywords that may be used by malware
  167 +SUSPICIOUS_KEYWORDS = {
  168 + #TODO: use regex to support variable whitespaces
  169 + 'May read system environment variables':
  170 + ('environ',),
  171 + 'May open a file':
  172 + ('open',),
  173 + 'May write to a file (if combined with Open)':
  174 + ('write', 'put', 'output', 'print #'),
  175 + 'May read or write a binary file (if combined with Open)':
  176 + ('binary',),
  177 + 'May run an executable file or a system command':
  178 + ('shell', 'vbnormalfocus'),
  179 + 'May hide the application':
  180 + ('Application.Visible', 'ShowWindow', 'SW_HIDE'),
  181 + 'May create a directory':
  182 + ('MkDir',),
  183 + 'May save the current workbook':
  184 + ('ActiveWorkbook.SaveAs',),
  185 + 'May change which directory contains files to open at startup':
  186 + #TODO: confirm the actual effect
  187 + ('Application.AltStartupPath',),
  188 + 'May create an OLE object':
  189 + ('CreateObject',),
  190 + 'May run an application (if combined with CreateObject)':
  191 + ('Shell.Application',),
  192 + 'May enumerate application windows (if combined with Shell.Application object)':
  193 + ('.Windows', 'FindWindow'),
  194 +}
  195 +
165 # Patterns to be extracted (IP addresses, URLs, etc) 196 # Patterns to be extracted (IP addresses, URLs, etc)
166 # From patterns.py in balbuzard 197 # From patterns.py in balbuzard
167 RE_PATTERNS = ( 198 RE_PATTERNS = (
@@ -726,6 +757,26 @@ def detect_autoexec(vba_code): @@ -726,6 +757,26 @@ def detect_autoexec(vba_code):
726 return results 757 return results
727 758
728 759
  760 +def detect_suspicious(vba_code):
  761 + """
  762 + Detect if the VBA code contains suspicious keywords corresponding to
  763 + potential malware behaviour.
  764 +
  765 + :param vba_code: str, VBA source code
  766 + :return: list of str tuples (keyword, description)
  767 + """
  768 + #TODO: use regex to find keywords with word boundaries
  769 + # case-insensitive search
  770 + #vba_code = vba_code.lower()
  771 + results = []
  772 + for description, keywords in SUSPICIOUS_KEYWORDS.items():
  773 + for keyword in keywords:
  774 + if re.search(r'(?i)\b'+keyword+r'\b', vba_code):
  775 + #if keyword.lower() in vba_code:
  776 + results.append((keyword, description))
  777 + return results
  778 +
  779 +
729 def detect_patterns(vba_code): 780 def detect_patterns(vba_code):
730 """ 781 """
731 Detect if the VBA code contains specific patterns such as IP addresses, 782 Detect if the VBA code contains specific patterns such as IP addresses,
@@ -1001,6 +1052,20 @@ if __name__ == '__main__': @@ -1001,6 +1052,20 @@ if __name__ == '__main__':
1001 print 'Auto-executable macro keywords: None found' 1052 print 'Auto-executable macro keywords: None found'
1002 1053
1003 print '- '*39 1054 print '- '*39
  1055 + suspicious_keywords = detect_suspicious(vba_code)
  1056 + if suspicious_keywords:
  1057 + print 'Suspicious macro keywords found:'
  1058 + t = prettytable.PrettyTable(('Keyword', 'Description'))
  1059 + t.align = 'l'
  1060 + t.max_width['Keyword'] = 20
  1061 + t.max_width['Description'] = 59
  1062 + for keyword, description in suspicious_keywords:
  1063 + t.add_row((keyword, description))
  1064 + print t
  1065 + else:
  1066 + print 'Suspicious macro keywords: None found'
  1067 +
  1068 + print '- '*39
1004 patterns = detect_patterns(vba_code) 1069 patterns = detect_patterns(vba_code)
1005 if patterns: 1070 if patterns:
1006 print 'Patterns found:' 1071 print 'Patterns found:'