Commit 3ec4b06639c9d5be5839ff2a7c46c12346881f0f

Authored by decalage2
1 parent b4b52d22

rtfobj: temporary fix for issue #178

Showing 1 changed file with 10 additions and 2 deletions
oletools/rtfobj.py
@@ -72,8 +72,9 @@ http://www.decalage.info/python/oletools @@ -72,8 +72,9 @@ http://www.decalage.info/python/oletools
72 # 2017-04-11 PL: - added detection of the OLE2Link vulnerability CVE-2017-0199 72 # 2017-04-11 PL: - added detection of the OLE2Link vulnerability CVE-2017-0199
73 # 2017-05-04 PL: - fixed issue #164 to handle linked OLE objects 73 # 2017-05-04 PL: - fixed issue #164 to handle linked OLE objects
74 # 2017-06-08 PL: - fixed issue/PR #143: bin object with negative length 74 # 2017-06-08 PL: - fixed issue/PR #143: bin object with negative length
  75 +# 2017-06-29 PL: - temporary fix for issue #178
75 76
76 -__version__ = '0.51dev8' 77 +__version__ = '0.51dev9'
77 78
78 # ------------------------------------------------------------------------------ 79 # ------------------------------------------------------------------------------
79 # TODO: 80 # TODO:
@@ -279,7 +280,10 @@ DESTINATION_CONTROL_WORDS = frozenset(( @@ -279,7 +280,10 @@ DESTINATION_CONTROL_WORDS = frozenset((
279 b"mzeroAsc", b"mzeroDesc", b"mzeroWid", b"nesttableprops", b"nexctfile", b"nonesttables", b"objalias", b"objclass", 280 b"mzeroAsc", b"mzeroDesc", b"mzeroWid", b"nesttableprops", b"nexctfile", b"nonesttables", b"objalias", b"objclass",
280 b"objdata", b"object", b"objname", b"objsect", b"objtime", b"oldcprops", b"oldpprops", b"oldsprops", b"oldtprops", 281 b"objdata", b"object", b"objname", b"objsect", b"objtime", b"oldcprops", b"oldpprops", b"oldsprops", b"oldtprops",
281 b"oleclsid", b"operator", b"panose", b"password", b"passwordhash", b"pgp", b"pgptbl", b"picprop", b"pict", b"pn", b"pnseclvl", 282 b"oleclsid", b"operator", b"panose", b"password", b"passwordhash", b"pgp", b"pgptbl", b"picprop", b"pict", b"pn", b"pnseclvl",
282 - b"pntext", b"pntxta", b"pntxtb", b"printim", b"private", b"propname", b"protend", b"protstart", b"protusertbl", b"pxe", 283 + b"pntext", b"pntxta", b"pntxtb", b"printim",
  284 + # It seems \private should not be treated as a destination (issue #178)
  285 + # b"private",
  286 + b"propname", b"protend", b"protstart", b"protusertbl", b"pxe",
283 b"result", b"revtbl", b"revtim", b"rsidtbl", b"rtf", b"rxe", b"shp", b"shpgrp", b"shpinst", b"shppict", b"shprslt", b"shptxt", 287 b"result", b"revtbl", b"revtim", b"rsidtbl", b"rtf", b"rxe", b"shp", b"shpgrp", b"shpinst", b"shppict", b"shprslt", b"shptxt",
284 b"sn", b"sp", b"staticval", b"stylesheet", b"subject", b"sv", b"svb", b"tc", b"template", b"themedata", b"title", b"txe", b"ud", 288 b"sn", b"sp", b"staticval", b"stylesheet", b"subject", b"sv", b"svb", b"tc", b"template", b"themedata", b"title", b"txe", b"ud",
285 b"upr", b"userprops", b"wgrffmtfilter", b"windowcaption", b"writereservation", b"writereservhash", b"xe", b"xform", 289 b"upr", b"userprops", b"wgrffmtfilter", b"windowcaption", b"writereservation", b"writereservhash", b"xe", b"xform",
@@ -476,6 +480,8 @@ class RtfParser(object): @@ -476,6 +480,8 @@ class RtfParser(object):
476 480
477 def _control_word(self, matchobject, cword, param): 481 def _control_word(self, matchobject, cword, param):
478 #log.debug('control word %r at index %Xh' % (matchobject.group(), self.index)) 482 #log.debug('control word %r at index %Xh' % (matchobject.group(), self.index))
  483 + # TODO: according to RTF specs v1.9.1, "Destination changes are legal only immediately after an opening brace ({)"
  484 + # (not counting the special control symbol \*, of course)
479 if cword in DESTINATION_CONTROL_WORDS: 485 if cword in DESTINATION_CONTROL_WORDS:
480 # log.debug('%r is a destination control word: starting a new destination' % cword) 486 # log.debug('%r is a destination control word: starting a new destination' % cword)
481 self._open_destination(matchobject, cword) 487 self._open_destination(matchobject, cword)
@@ -569,6 +575,7 @@ class RtfObjParser(RtfParser): @@ -569,6 +575,7 @@ class RtfObjParser(RtfParser):
569 self.objects = [] 575 self.objects = []
570 576
571 def open_destination(self, destination): 577 def open_destination(self, destination):
  578 + # TODO: detect when the destination is within an objdata, report as obfuscation
572 if destination.cword == b'objdata': 579 if destination.cword == b'objdata':
573 log.debug('*** Start object data at index %Xh' % destination.start) 580 log.debug('*** Start object data at index %Xh' % destination.start)
574 581
@@ -625,6 +632,7 @@ class RtfObjParser(RtfParser): @@ -625,6 +632,7 @@ class RtfObjParser(RtfParser):
625 # TODO: extract useful cwords such as objclass 632 # TODO: extract useful cwords such as objclass
626 # TODO: keep track of cwords inside objdata, because it is unusual and indicates potential obfuscation 633 # TODO: keep track of cwords inside objdata, because it is unusual and indicates potential obfuscation
627 # TODO: same with control symbols, and opening bracket 634 # TODO: same with control symbols, and opening bracket
  635 + log.debug('- Control word "%s", param=%s, level=%d' % (cword, param, self.group_level))
628 pass 636 pass
629 637
630 638