Commit c556697486817d399f1f5f825e23792f3eff24b1

Authored by Philippe Lagadec
1 parent 977cdd30

olevba: KeyboardInterrupt is now raised properly in every function

Showing 1 changed file with 53 additions and 1 deletions
oletools/olevba.py
... ... @@ -160,13 +160,13 @@ https://github.com/unixfreak0037/officeparser
160 160 # - improved logging, added -l option
161 161 # 2016-01-31 PL: - fixed issue #31 in VBA_Parser.open_mht
162 162 # - fixed issue #32 by monkeypatching email.feedparser
  163 +# 2016-02-07 PL: - KeyboardInterrupt is now raised properly
163 164  
164 165 __version__ = '0.42'
165 166  
166 167 #------------------------------------------------------------------------------
167 168 # TODO:
168 169 # + option --fast to disable VBA expressions parsing
169   -# + do not use logging, but a provided logger (null logger by default)
170 170 # + setup logging (common with other oletools)
171 171 # + add xor bruteforcing like bbharvest
172 172 # + options -a and -c should imply -d
... ... @@ -187,6 +187,7 @@ __version__ = '0.42'
187 187 # - extract_macros: convert to a class, split long function into smaller methods
188 188 # - extract_macros: read bytes from stream file objects instead of strings
189 189 # - extract_macros: use combined struct.unpack instead of many calls
  190 +# - all except clauses should target specific exceptions
190 191  
191 192 #------------------------------------------------------------------------------
192 193 # REFERENCES:
... ... @@ -778,6 +779,9 @@ def mso_file_extract(data):
778 779 try:
779 780 offset = struct.unpack_from('<H', data, offset=0x1E)[0] + 46
780 781 log.debug('Parsing MSO file: data offset = 0x%X' % offset)
  782 + except KeyboardInterrupt:
  783 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  784 + raise
781 785 except:
782 786 log.exception('Unable to parse MSO/ActiveMime file header')
783 787 raise RuntimeError('Unable to parse MSO/ActiveMime file header')
... ... @@ -790,6 +794,9 @@ def mso_file_extract(data):
790 794 log.debug('Attempting zlib decompression from MSO file offset 0x%X' % start)
791 795 extracted_data = zlib.decompress(data[start:])
792 796 return extracted_data
  797 + except KeyboardInterrupt:
  798 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  799 + raise
793 800 except:
794 801 log.exception('zlib decompression failed')
795 802 # None of the guessed offsets worked, let's try brute-forcing by looking
... ... @@ -801,6 +808,9 @@ def mso_file_extract(data):
801 808 log.debug('Attempting zlib decompression from MSO file offset 0x%X' % start)
802 809 extracted_data = zlib.decompress(data[start:])
803 810 return extracted_data
  811 + except KeyboardInterrupt:
  812 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  813 + raise
804 814 except:
805 815 log.exception('zlib decompression failed')
806 816 raise RuntimeError('Unable to decompress data from a MSO/ActiveMime file')
... ... @@ -1506,6 +1516,9 @@ def detect_base64_strings(vba_code):
1506 1516 decoded = base64.b64decode(value)
1507 1517 results.append((value, decoded))
1508 1518 found.add(value)
  1519 + except KeyboardInterrupt:
  1520 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1521 + raise
1509 1522 except:
1510 1523 # if an exception occurs, it is likely not a base64-encoded string
1511 1524 pass
... ... @@ -1533,6 +1546,9 @@ def detect_dridex_strings(vba_code):
1533 1546 decoded = DridexUrlDecode(value)
1534 1547 results.append((value, decoded))
1535 1548 found.add(value)
  1549 + except KeyboardInterrupt:
  1550 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1551 + raise
1536 1552 except:
1537 1553 # if an exception occurs, it is likely not a dridex-encoded string
1538 1554 pass
... ... @@ -1858,6 +1874,9 @@ class VBA_Parser(object):
1858 1874 # TODO: raise TypeError if this is a Powerpoint 97 file, since VBA macros cannot be detected yet
1859 1875 # set type only if parsing succeeds
1860 1876 self.type = TYPE_OLE
  1877 + except KeyboardInterrupt:
  1878 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1879 + raise
1861 1880 except:
1862 1881 # TODO: handle OLE parsing exceptions
1863 1882 log.exception('Failed OLE parsing for file %r' % self.filename)
... ... @@ -1887,12 +1906,18 @@ class VBA_Parser(object):
1887 1906 ole_data = z.open(subfile).read()
1888 1907 try:
1889 1908 self.ole_subfiles.append(VBA_Parser(filename=subfile, data=ole_data))
  1909 + except KeyboardInterrupt:
  1910 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1911 + raise
1890 1912 except:
1891 1913 log.debug('%s is not a valid OLE file' % subfile)
1892 1914 continue
1893 1915 z.close()
1894 1916 # set type only if parsing succeeds
1895 1917 self.type = TYPE_OpenXML
  1918 + except KeyboardInterrupt:
  1919 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1920 + raise
1896 1921 except:
1897 1922 # TODO: handle parsing exceptions
1898 1923 log.exception('Failed Zip/OpenXML parsing for file %r' % self.filename)
... ... @@ -1923,12 +1948,18 @@ class VBA_Parser(object):
1923 1948 ole_data = mso_file_extract(mso_data)
1924 1949 try:
1925 1950 self.ole_subfiles.append(VBA_Parser(filename=fname, data=ole_data))
  1951 + except KeyboardInterrupt:
  1952 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1953 + raise
1926 1954 except:
1927 1955 log.error('%s does not contain a valid OLE file' % fname)
1928 1956 else:
1929 1957 log.error('%s is not a valid MSO file' % fname)
1930 1958 # set type only if parsing succeeds
1931 1959 self.type = TYPE_Word2003_XML
  1960 + except KeyboardInterrupt:
  1961 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  1962 + raise
1932 1963 except:
1933 1964 # TODO: differentiate exceptions for each parsing stage
1934 1965 log.exception('Failed XML parsing for file %r' % self.filename)
... ... @@ -1979,8 +2010,14 @@ class VBA_Parser(object):
1979 2010 # TODO: check if it is actually an OLE file
1980 2011 # TODO: get the MSO filename from content_location?
1981 2012 self.ole_subfiles.append(VBA_Parser(filename=fname, data=ole_data))
  2013 + except KeyboardInterrupt:
  2014 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2015 + raise
1982 2016 except:
1983 2017 log.debug('%s does not contain a valid OLE file' % fname)
  2018 + except KeyboardInterrupt:
  2019 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2020 + raise
1984 2021 except:
1985 2022 log.exception('Failed decompressing an MSO container in %r - %s'
1986 2023 % (fname, MSG_OLEVBA_ISSUES))
... ... @@ -1989,10 +2026,16 @@ class VBA_Parser(object):
1989 2026 try:
1990 2027 log.debug('type(part_data) = %s' % type(part_data))
1991 2028 log.debug('part_data[0:20] = %r' % part_data[0:20])
  2029 + except KeyboardInterrupt:
  2030 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2031 + raise
1992 2032 except:
1993 2033 pass
1994 2034 # set type only if parsing succeeds
1995 2035 self.type = TYPE_MHTML
  2036 + except KeyboardInterrupt:
  2037 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2038 + raise
1996 2039 except:
1997 2040 log.exception('Failed MIME parsing for file %r - %s'
1998 2041 % (self.filename, MSG_OLEVBA_ISSUES))
... ... @@ -2012,6 +2055,9 @@ class VBA_Parser(object):
2012 2055 self.contains_macros = True
2013 2056 # set type only if parsing succeeds
2014 2057 self.type = TYPE_TEXT
  2058 + except KeyboardInterrupt:
  2059 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2060 + raise
2015 2061 except:
2016 2062 log.exception('Failed text parsing for file %r - %s'
2017 2063 % (self.filename, MSG_OLEVBA_ISSUES))
... ... @@ -2364,6 +2410,9 @@ class VBA_Parser_CLI(VBA_Parser):
2364 2410 print self.reveal()
2365 2411 else:
2366 2412 print 'No VBA macros found.'
  2413 + except KeyboardInterrupt:
  2414 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2415 + raise
2367 2416 except: #TypeError:
2368 2417 #raise
2369 2418 #TODO: print more info if debug mode
... ... @@ -2414,6 +2463,9 @@ class VBA_Parser_CLI(VBA_Parser):
2414 2463 # file type not OLE nor OpenXML
2415 2464 flags = '?'
2416 2465 message = 'File format not supported'
  2466 + except KeyboardInterrupt:
  2467 + # do not ignore exceptions when the user presses Ctrl+C/Pause:
  2468 + raise
2417 2469 except:
2418 2470 # another error occurred
2419 2471 #raise
... ...