Commit d02c84562f0273643a123cd6e94aa4c084cd0b64

Authored by decalage2
1 parent d14635d2

pyxswf, xxxswf: fixed to run on Python 2+3 (issue #62)

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
... ...