Commit d02c84562f0273643a123cd6e94aa4c084cd0b64
1 parent
d14635d2
pyxswf, xxxswf: fixed to run on Python 2+3 (issue #62)
Showing
2 changed files
with
22 additions
and
17 deletions
oletools/pyxswf.py
| ... | ... | @@ -56,11 +56,13 @@ http://www.decalage.info/python/oletools |
| 56 | 56 | # - improved usage display with -h |
| 57 | 57 | # 2016-09-06 v0.50 PL: - updated to match the rtfobj API |
| 58 | 58 | # 2016-10-25 PL: - fixed print for Python 3 |
| 59 | +# 2016-11-01 PL: - replaced StringIO by BytesIO for Python 3 | |
| 59 | 60 | |
| 60 | 61 | __version__ = '0.50' |
| 61 | 62 | |
| 62 | 63 | #------------------------------------------------------------------------------ |
| 63 | 64 | # TODO: |
| 65 | +# + update xxxswf to latest version | |
| 64 | 66 | # + add support for LZMA-compressed flash files (ZWS header) |
| 65 | 67 | # references: http://blog.malwaretracker.com/2014/01/cve-2013-5331-evaded-av-by-using.html |
| 66 | 68 | # http://code.metager.de/source/xref/adobe/flash/crossbridge/tools/swf-info.py |
| ... | ... | @@ -72,7 +74,8 @@ __version__ = '0.50' |
| 72 | 74 | |
| 73 | 75 | #=== IMPORTS ================================================================= |
| 74 | 76 | |
| 75 | -import optparse, sys, os, rtfobj, StringIO | |
| 77 | +import optparse, sys, os, rtfobj | |
| 78 | +from io import BytesIO | |
| 76 | 79 | from thirdparty.xxxswf import xxxswf |
| 77 | 80 | import thirdparty.olefile as olefile |
| 78 | 81 | |
| ... | ... | @@ -122,7 +125,7 @@ def main(): |
| 122 | 125 | f = ole._open(direntry.isectStart, direntry.size) |
| 123 | 126 | # check if data contains the SWF magic: FWS or CWS |
| 124 | 127 | data = f.getvalue() |
| 125 | - if 'FWS' in data or 'CWS' in data: | |
| 128 | + if b'FWS' in data or b'CWS' in data: | |
| 126 | 129 | print('OLE stream: %s' % repr(direntry.name)) |
| 127 | 130 | # call xxxswf to scan or extract Flash files: |
| 128 | 131 | xxxswf.disneyland(f, direntry.name, options) |
| ... | ... | @@ -133,9 +136,9 @@ def main(): |
| 133 | 136 | elif options.rtf: |
| 134 | 137 | for filename in args: |
| 135 | 138 | for index, orig_len, data in rtfobj.rtf_iter_objects(filename): |
| 136 | - if 'FWS' in data or 'CWS' in data: | |
| 139 | + if b'FWS' in data or b'CWS' in data: | |
| 137 | 140 | print('RTF embedded object size %d at index %08X' % (len(data), index)) |
| 138 | - f = StringIO.StringIO(data) | |
| 141 | + f = BytesIO(data) | |
| 139 | 142 | name = 'RTF_embedded_object_%08X' % index |
| 140 | 143 | # call xxxswf to scan or extract Flash files: |
| 141 | 144 | xxxswf.disneyland(f, name, options) | ... | ... |
oletools/thirdparty/xxxswf/xxxswf.py
| ... | ... | @@ -5,6 +5,8 @@ |
| 5 | 5 | # - Tag Parser |
| 6 | 6 | # - ActionScript Decompiler |
| 7 | 7 | |
| 8 | +# 2016-11-01 PL: - A few changes for Python 2+3 compatibility | |
| 9 | + | |
| 8 | 10 | import fnmatch |
| 9 | 11 | import hashlib |
| 10 | 12 | import imp |
| ... | ... | @@ -14,7 +16,7 @@ import re |
| 14 | 16 | import struct |
| 15 | 17 | import sys |
| 16 | 18 | import time |
| 17 | -from StringIO import StringIO | |
| 19 | +from io import BytesIO | |
| 18 | 20 | from optparse import OptionParser |
| 19 | 21 | import zlib |
| 20 | 22 | |
| ... | ... | @@ -63,14 +65,14 @@ def yaraScan(d): |
| 63 | 65 | def findSWF(d): |
| 64 | 66 | # d = buffer of the read file |
| 65 | 67 | # Search for SWF Header Sigs in files |
| 66 | - return [tmp.start() for tmp in re.finditer('CWS|FWS', d.read())] | |
| 68 | + return [tmp.start() for tmp in re.finditer(b'CWS|FWS', d.read())] | |
| 67 | 69 | |
| 68 | 70 | def hashBuff(d): |
| 69 | 71 | # d = buffer of the read file |
| 70 | 72 | # This function hashes the buffer |
| 71 | 73 | # source: http://stackoverflow.com/q/5853830 |
| 72 | 74 | if type(d) is str: |
| 73 | - d = StringIO(d) | |
| 75 | + d = BytesIO(d) | |
| 74 | 76 | md5 = hashlib.md5() |
| 75 | 77 | while True: |
| 76 | 78 | data = d.read(128) |
| ... | ... | @@ -99,16 +101,16 @@ def verifySWF(f,addr): |
| 99 | 101 | print(' - [ERROR] Invalid SWF Size') |
| 100 | 102 | return None |
| 101 | 103 | if type(t) is str: |
| 102 | - f = StringIO(t) | |
| 104 | + f = BytesIO(t) | |
| 103 | 105 | # Error check for version above 20 |
| 104 | 106 | if ver > 20: |
| 105 | 107 | print(' - [ERROR] Invalid SWF Version') |
| 106 | 108 | return None |
| 107 | 109 | |
| 108 | - if 'CWS' in header: | |
| 110 | + if b'CWS' in header: | |
| 109 | 111 | try: |
| 110 | 112 | f.read(3) |
| 111 | - tmp = 'FWS' + f.read(5) + zlib.decompress(f.read()) | |
| 113 | + tmp = b'FWS' + f.read(5) + zlib.decompress(f.read()) | |
| 112 | 114 | print(' - CWS Header') |
| 113 | 115 | return tmp |
| 114 | 116 | |
| ... | ... | @@ -117,7 +119,7 @@ def verifySWF(f,addr): |
| 117 | 119 | print('- [ERROR]: Zlib decompression error. Invalid CWS SWF') |
| 118 | 120 | return None |
| 119 | 121 | |
| 120 | - elif 'FWS' in header: | |
| 122 | + elif b'FWS' in header: | |
| 121 | 123 | try: |
| 122 | 124 | tmp = f.read(size) |
| 123 | 125 | print(' - FWS Header') |
| ... | ... | @@ -144,20 +146,20 @@ def headerInfo(f): |
| 144 | 146 | # [HEADER] Movie width: 217.00 |
| 145 | 147 | # [HEADER] Movie height: 85.00 |
| 146 | 148 | if type(f) is str: |
| 147 | - f = StringIO(f) | |
| 149 | + f = BytesIO(f) | |
| 148 | 150 | sig = f.read(3) |
| 149 | 151 | print('\t[HEADER] File header: %s' % sig) |
| 150 | - if 'C' in sig: | |
| 152 | + if b'C' in sig: | |
| 151 | 153 | print('\t[HEADER] File is zlib compressed.') |
| 152 | 154 | version = struct.unpack('<b', f.read(1))[0] |
| 153 | 155 | print('\t[HEADER] File version: %d' % version) |
| 154 | 156 | size = struct.unpack('<i', f.read(4))[0] |
| 155 | 157 | print('\t[HEADER] File size: %d' % size) |
| 156 | 158 | # deflate compressed SWF |
| 157 | - if 'C' in sig: | |
| 159 | + if b'C' in sig: | |
| 158 | 160 | f = verifySWF(f,0) |
| 159 | 161 | if type(f) is str: |
| 160 | - f = StringIO(f) | |
| 162 | + f = BytesIO(f) | |
| 161 | 163 | f.seek(0, 0) |
| 162 | 164 | x = f.read(8) |
| 163 | 165 | ta = f.tell() |
| ... | ... | @@ -245,10 +247,10 @@ def CWSize(f): |
| 245 | 247 | |
| 246 | 248 | def compressSWF(f): |
| 247 | 249 | if type(f) is str: |
| 248 | - f = StringIO(f) | |
| 250 | + f = BytesIO(f) | |
| 249 | 251 | try: |
| 250 | 252 | f.read(3) |
| 251 | - tmp = 'CWS' + f.read(5) + zlib.compress(f.read()) | |
| 253 | + tmp = b'CWS' + f.read(5) + zlib.compress(f.read()) | |
| 252 | 254 | return tmp |
| 253 | 255 | except: |
| 254 | 256 | pass | ... | ... |