Commit 3ec4b06639c9d5be5839ff2a7c46c12346881f0f
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 |