Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for FireEye HX .mans files #1205

Merged
merged 6 commits into from
May 21, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api_client/python/timesketch_api_client/sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def list_timelines(self):
return timelines

def upload(self, timeline_name, file_path, index=None):
"""Upload a CSV, JSONL, or Plaso file to the server for indexing.
"""Upload a CSV, JSONL, mans, or Plaso file to the server for indexing.

Args:
timeline_name: Name of the resulting timeline.
Expand Down
4 changes: 2 additions & 2 deletions config/dpkg/timesketch-server.timesketch.default
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ GOOGLE_OIDC_HOSTED_DOMAIN = None
GOOGLE_OIDC_USER_WHITELIST = []

#-------------------------------------------------------------------------------
# Upload and processing of Plaso storage files.
# Upload and processing of Plaso storage or mans files.

# To enable this feature you need to configure an upload directory and
# how to reach the Redis database used by the distributed task queue.
UPLOAD_ENABLED = False

# Folder for temporarily storage of Plaso dump files before being processed and
# Folder for temporarily storage of Plaso dump or mans files before being processed and
# inserted into the datastore.
UPLOAD_FOLDER = '/tmp'

Expand Down
2 changes: 1 addition & 1 deletion contrib/timesketch-importer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# limitations under the License.

# This script watches a directory for new files and executes the importer
# on any .plaso, .csv and .jsonl files. To be place in /usr/local/bin/
# on any .plaso, .mans, .csv and .jsonl files. To be place in /usr/local/bin/

config_file="/etc/timesketch-importer.conf"
if [ -s "$config_file" ]; then
Expand Down
4 changes: 2 additions & 2 deletions data/timesketch.conf
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,13 @@ GOOGLE_OIDC_HOSTED_DOMAIN = None
GOOGLE_OIDC_USER_WHITELIST = []

#-------------------------------------------------------------------------------
# Upload and processing of Plaso storage files.
# Upload and processing of Plaso storage or mans files.

# To enable this feature you need to configure an upload directory and
# how to reach the Redis database used by the distributed task queue.
UPLOAD_ENABLED = False

# Folder for temporarily storage of Plaso dump files before being processed and
# Folder for temporarily storage of Plaso dump or mans files before being processed and
# inserted into the datastore.
UPLOAD_FOLDER = '/tmp'

Expand Down
6 changes: 3 additions & 3 deletions importer_client/python/timesketch_import_client/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ def add_excel_file(self, filepath, **kwargs):
self.add_data_frame(data_frame)

def add_file(self, filepath, delimiter=','):
"""Add a CSV, JSONL or a PLASO file to the buffer.
"""Add a CSV, JSONL, mans or a PLASO file to the buffer.

Args:
filepath: the path to the file to add.
Expand Down Expand Up @@ -535,7 +535,7 @@ def add_file(self, filepath, delimiter=','):
fh, delimiter=delimiter,
chunksize=self._threshold_entry):
self.add_data_frame(chunk_frame, part_of_iter=True)
elif file_ending == 'plaso':
elif file_ending in ('plaso', 'mans'):
self._upload_binary_file(filepath)

elif file_ending == 'jsonl':
Expand All @@ -550,7 +550,7 @@ def add_file(self, filepath, delimiter=','):

else:
raise TypeError(
'File needs to have a file extension of: .csv, .jsonl or '
'File needs to have a file extension of: .csv, .jsonl, mans or '
'.plaso')

def add_json(self, json_entry, column_names=None):
Expand Down
5 changes: 3 additions & 2 deletions importer_client/python/tools/timesketch_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ def upload_file(
return 'Sketch needs to be set'

_, _, file_extension = file_path.rpartition('.')
if file_extension.lower() not in ('plaso', 'csv', 'jsonl'):
if file_extension.lower() not in ('plaso', 'mans', 'csv', 'jsonl'):
return (
'File needs to have one of the following extensions: '
'.plaso, .csv, .jsonl (not {0:s})').format(file_extension.lower())
'.plaso, .mans, .csv, '
'.jsonl (not {0:s})').format(file_extension.lower())

with importer.ImportStreamer() as streamer:
streamer.set_sketch(my_sketch)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ Werkzeug==0.16.0
WTForms==2.2.1
xlrd==1.2.0
tabulate==0.8.6
mans_to_es==1.6
2 changes: 1 addition & 1 deletion timesketch/frontend/src/views/SketchManageTimelines.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ limitations under the License.

<b-message type="is-success">
<p>
Upload a new timeline or choose an existing one from the list below. You can upload either a Plaso storage file, JSONL, or a CSV file.
Upload a new timeline or choose an existing one from the list below. You can upload either a Plaso storage file, mans, JSONL, or a CSV file.
<br>
If you are uploading a CSV or JSONL file make sure to read the <a href="https://github.com/google/timesketch/blob/master/docs/Users-Guide.md#adding-timelines" rel="noreferrer" target="_blank">documentation</a> to learn what columns are needed.
</p>
Expand Down
2 changes: 1 addition & 1 deletion timesketch/frontend/src/views/SketchOverview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ limitations under the License.
<div class="card-content">
<div class="content">
<p>
Supported formats are Plaso storage file, JSONL, or a CSV file.
Supported formats are Plaso storage file, mans, JSONL, or a CSV file.
If you are uploading a CSV or JSONL file make sure to read the <a href="https://github.com/google/timesketch/blob/master/docs/Users-Guide.md#adding-timelines" rel="noreferrer" target="_blank">documentation</a> to learn what columns are needed.
</p>
<ts-upload-timeline-form @toggleModal="showUploadTimelineModal = !showUploadTimelineModal"></ts-upload-timeline-form>
Expand Down
42 changes: 41 additions & 1 deletion timesketch/lib/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Celery task for processing Plaso storage files."""
"""Celery task for processing Plaso storage or mans files."""

from __future__ import unicode_literals

Expand All @@ -29,6 +29,7 @@
from flask import current_app
from sqlalchemy import create_engine
from elasticsearch.exceptions import RequestError
from mans_to_es import MansToEs

from timesketch import create_celery_app
from timesketch.lib import errors
Expand Down Expand Up @@ -108,6 +109,8 @@ def _get_index_task_class(file_extension):
"""
if file_extension == 'plaso':
index_class = run_plaso
elif file_extension == 'mans':
index_class = run_mans
elif file_extension in ['csv', 'jsonl']:
index_class = run_csv_jsonl
else:
Expand Down Expand Up @@ -519,3 +522,40 @@ def run_csv_jsonl(file_path, events, timeline_name, index_name, source_type):
_set_timeline_status(index_name, status='ready')

return index_name


@celery.task(track_started=True, base=SqlAlchemyTask)
def run_mans(file_path, events, timeline_name, index_name, source_type):
"""Create a Celery task for processing mans file.

Args:
file_path: Path to the mans file.
events: A string with the events. Not used in mans.
timeline_name: Name of the Timesketch timeline.
index_name: Name of the datastore index.
source_type: Type of file, csv or jsonl.

Returns:
Name (str) of the index.
"""
# Log information to Celery
message = 'Index timeline [{0:s}] to index [{1:s}] (source: {2:s})'
logging.info(message.format(timeline_name, index_name, source_type))

elastic_host = current_app.config['ELASTIC_HOST']
elastic_port = int(current_app.config['ELASTIC_PORT'])
try:
mte = MansToEs(filename=file_path, name=timeline_name, index=index_name,
es_host=elastic_host, es_port=elastic_port)
mte.run()
except Exception as e: # pylint: disable=broad-except
garanews marked this conversation as resolved.
Show resolved Hide resolved
# Mark the searchindex and timelines as failed and exit the task
error_msg = traceback.format_exc()
_set_timeline_status(index_name, status='fail', error_msg=error_msg)
logging.error('Error: {0!s}\n{1:s}'.format(e, error_msg))
return None

# Mark the searchindex and timelines as ready
_set_timeline_status(index_name, status='ready')

return index_name
2 changes: 1 addition & 1 deletion timesketch/templates/sketch/timelines.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{% if sketch.has_permission(current_user, 'write') and upload_enabled %}
<div class="card">
<h4>Import timeline</h4>
<p>You can upload either a Plaso storage file, JSONL, or a CSV file.<br>
<p>You can upload either a Plaso storage file, mans, JSONL, or a CSV file.<br>
<i>Supported Plaso version: {{ plaso_version }}</i>
</p>
<ts-core-upload sketch-id="{{ sketch.id }}" visible="true" btn-text="'Select file'"></ts-core-upload>
Expand Down
2 changes: 1 addition & 1 deletion timesketch/tsctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def run(self, file_path, sketch_id, username, timeline_name):
extension = extension.lstrip('.')
filename = os.path.basename(file_path_no_extension)

supported_extensions = ('plaso', 'csv', 'jsonl')
supported_extensions = ('plaso', 'mans', 'csv', 'jsonl')

if not os.path.isfile(file_path):
sys.exit('No such file: {0:s}'.format(file_path))
Expand Down