Skip to content

Commit

Permalink
file carve download stream AES zip (idaholab#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmguero committed Jan 4, 2024
1 parent cfc29f7 commit 9a941dc
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 18 deletions.
1 change: 0 additions & 1 deletion Dockerfiles/file-monitor.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ RUN sed -i "s/main$/main contrib non-free/g" /etc/apt/sources.list.d/debian.sour
clamd \
psutil \
pycryptodome \
pyminizip \
python-magic \
stream-zip \
supervisor \
Expand Down
4 changes: 2 additions & 2 deletions docs/file-scanning.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The `EXTRACTED_FILE_PRESERVATION` [environment variable in `zeek.env`](malcolm-c
* `all`: preserve flagged files in `./zeek-logs/extract_files/quarantine` and all other extracted files in `./zeek-logs/extract_files/preserved`
* `none`: preserve no extracted files

The `EXTRACTED_FILE_HTTP_SERVER_…` [environment variables in `zeek.env` and `zeek-secret.env`](malcolm-config.md#MalcolmConfigEnvVars) configure access to the Zeek-extracted files path through the means of a simple HTTPS directory server accessible at **https://localhost/extracted-files/** if connecting locally. Beware that Zeek-extracted files may contain malware. As such, these files may be optionally ZIP archived (with or without a password) or encrypted (to be decrypted using `openssl`, e.g., `openssl enc -aes-256-cbc -d -in example.exe.encrypted -out example.exe`) upon download. In other words:
The `EXTRACTED_FILE_HTTP_SERVER_…` [environment variables in `zeek.env` and `zeek-secret.env`](malcolm-config.md#MalcolmConfigEnvVars) configure access to the Zeek-extracted files path through the means of a simple HTTPS directory server accessible at **https://localhost/extracted-files/** if connecting locally. Beware that Zeek-extracted files may contain malware. As such, these files may be optionally ZIP archived (without a password or password-protected according to the [WinZip AES encryption specification](https://www.winzip.com/en/support/aes-encryption/)) or encrypted (to be decrypted using `openssl`, e.g., `openssl enc -aes-256-cbc -d -in example.exe.encrypted -out example.exe`) upon download. In other words:

* to disable the extracted files server:
- `EXTRACTED_FILE_HTTP_SERVER_ENABLE=false`
Expand All @@ -34,7 +34,7 @@ The `EXTRACTED_FILE_HTTP_SERVER_…` [environment variables in `zeek.env` and `z
- downloaded files are zipped, without a password:
+ `EXTRACTED_FILE_HTTP_SERVER_ZIP=true`
+ `EXTRACTED_FILE_HTTP_SERVER_KEY=`
- downloaded files are zipped, with a password:
- downloaded files are zipped, [AES-encrypted](https://www.winzip.com/en/support/aes-encryption/) with a password:
+ `EXTRACTED_FILE_HTTP_SERVER_ZIP=true`
+ `EXTRACTED_FILE_HTTP_SERVER_KEY=xxxxxxxxxxxxx`
- downloaded files are OpenSSL AES-256-CBC-compatibly encrypted:
Expand Down
19 changes: 4 additions & 15 deletions shared/bin/zeek_carved_http_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import argparse
import hashlib
import os
import pyminizip
import sys
from Crypto.Cipher import AES
from datetime import datetime
Expand Down Expand Up @@ -75,24 +74,14 @@ def do_GET(self):

elif os.path.isfile(fullpath) or os.path.islink(fullpath):
if args.zip:
# ZIP file
# ZIP file (streamed, AES-encrypted with password or unencrypted)
self.send_response(200)
self.send_header('Content-type', "application/zip")
self.send_header('Content-Disposition', f'attachment; filename={os.path.basename(fullpath)}.zip')
self.end_headers()

if args.key:
# password-protected ZIP file (temporarily persisted to disk)
with temporary_filename(suffix='.zip') as tmpFileName:
pyminizip.compress(fullpath, None, tmpFileName, args.key, 1)
with open(tmpFileName, 'rb') as f:
while chunk := f.read(65536):
self.wfile.write(chunk)

else:
# unprotected ZIP file (streamed)
for chunk in stream_zip(LocalFilesForZip([fullpath])):
self.wfile.write(chunk)
for chunk in stream_zip(LocalFilesForZip([fullpath]), password=args.key if args.key else None):
self.wfile.write(chunk)

elif args.key:
# openssl-compatible encrypted file
Expand All @@ -119,7 +108,7 @@ def do_GET(self):
break

else:
# unencrypted file
# original file, unencrypted
SimpleHTTPRequestHandler.do_GET(self)

else:
Expand Down

0 comments on commit 9a941dc

Please sign in to comment.