Commit 4e1f626d4576af5577f072273a5efaad2d30fcf0
1 parent
0dfa259f
crypto: use msoffcrypto's is_encrypted if possible
There were cases where our own test of byte 0x15 of SummaryInformation stream was incorrect. So leave test to the professionals ;-)
Showing
1 changed file
with
33 additions
and
1 deletions
oletools/crypto.py
| @@ -197,8 +197,40 @@ def is_encrypted(some_file): | @@ -197,8 +197,40 @@ def is_encrypted(some_file): | ||
| 197 | :returns: True if (and only if) the file contains encrypted content | 197 | :returns: True if (and only if) the file contains encrypted content |
| 198 | """ | 198 | """ |
| 199 | log.debug('is_encrypted') | 199 | log.debug('is_encrypted') |
| 200 | + | ||
| 201 | + # ask msoffcrypto if possible | ||
| 202 | + if check_msoffcrypto(): | ||
| 203 | + log.debug('Checking for encryption using msoffcrypto') | ||
| 204 | + file_handle = None | ||
| 205 | + file_pos = None | ||
| 206 | + try: | ||
| 207 | + if isinstance(some_file, OleFileIO): | ||
| 208 | + # TODO: hacky, replace once msoffcrypto-tools accepts OleFileIO | ||
| 209 | + file_handle = some_file.fp | ||
| 210 | + file_pos = file_handle.tell() | ||
| 211 | + file_handle.seek(0) | ||
| 212 | + else: | ||
| 213 | + file_handle = open(some_file, 'rb') | ||
| 214 | + | ||
| 215 | + return msoffcrypto.OfficeFile(file_handle).is_encrypted() | ||
| 216 | + | ||
| 217 | + except Exception as exc: | ||
| 218 | + log.warning('msoffcrypto failed to interpret file {} or determine ' | ||
| 219 | + 'whether it is encrypted: {}' | ||
| 220 | + .format(file_handle.name, exc)) | ||
| 221 | + | ||
| 222 | + finally: | ||
| 223 | + try: | ||
| 224 | + if file_pos is not None: # input was OleFileIO | ||
| 225 | + file_handle.seek(file_pos) | ||
| 226 | + else: # input was file name | ||
| 227 | + file_handle.close() | ||
| 228 | + except Exception as exc: | ||
| 229 | + log.warning('Ignoring error during clean up: {}'.format(exc)) | ||
| 230 | + | ||
| 231 | + # if that failed, try ourselves with older and less accurate code | ||
| 200 | if isinstance(some_file, OleFileIO): | 232 | if isinstance(some_file, OleFileIO): |
| 201 | - return _is_encrypted_ole(some_file) # assume it is OleFileIO | 233 | + return _is_encrypted_ole(some_file) |
| 202 | if zipfile.is_zipfile(some_file): | 234 | if zipfile.is_zipfile(some_file): |
| 203 | return _is_encrypted_zip(some_file) | 235 | return _is_encrypted_zip(some_file) |
| 204 | # otherwise assume it is the name of an ole file | 236 | # otherwise assume it is the name of an ole file |