Skip to content

Commit

Permalink
Refresh rules at runtime for Yara Analyser Job (#1550)
Browse files Browse the repository at this point in the history
* Add yara dynamic update rules
* Add tests for yara dynamic update rules
* Add linux/amd64 spec to docker build fules.
  • Loading branch information
hacktobeer authored Sep 30, 2024
1 parent e086875 commit c16f355
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docker/api_server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ COPY web/. .
RUN npm run build

# Build Turbinia API Server, copy from build, and setup rest of requirements
FROM ubuntu:22.04 as build-stage2
FROM --platform=linux/amd64 ubuntu:22.04 as build-stage2

ENV DEBIAN_FRONTEND=noninteractive \
PIP_NO_CACHE_DIR=1
Expand Down
2 changes: 1 addition & 1 deletion docker/server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.04
FROM --platform=linux/amd64 ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive
ENV PIP_NO_CACHE_DIR=1
Expand Down
7 changes: 4 additions & 3 deletions docker/tests/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.04
FROM --platform=linux/amd64 ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive \
PIP_NO_CACHE_DIR=1
ARG PPA_TRACK=stable
Expand Down Expand Up @@ -57,9 +57,10 @@ RUN echo "Defaults secure_path=\"/home/turbinia/.venv/bin:/usr/local/sbin:/usr/l

# Install yara rules and fraken binary.
RUN cd /opt \
&& git clone https://github.com/Neo23x0/signature-base.git \
&& git clone https://github.com/Neo23x0/signature-base.git --depth=1\
&& sudo chown -R turbinia:turbinia /opt/signature-base \
&& find /opt/signature-base -type f -not -iname '*.yar' -not -iname '*.yara' -not -iname 'file-type-signatures.txt' -delete
&& sudo git config --global --add safe.directory /opt/signature-base \
&& find /opt/signature-base -type f -not -path '*.git/*' -not -iname '*.yar' -not -iname '*.yara' -not -iname 'file-type-signatures.txt' -delete
COPY turbinia/config/rules/*.yar /opt/signature-base/yara/
RUN mkdir -p /opt/fraken && chown -R turbinia:turbinia /opt/fraken
COPY --from=us-docker.pkg.dev/osdfir-registry/turbinia/release/fraken:latest --chown=turbinia:turbinia /bin/fraken /opt/fraken/fraken
Expand Down
7 changes: 4 additions & 3 deletions docker/worker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build 1 - Turbinia Worker
FROM ubuntu:22.04
FROM --platform=linux/amd64 ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive \
PIP_NO_CACHE_DIR=1
ARG PPA_TRACK=stable
Expand Down Expand Up @@ -52,9 +52,10 @@ RUN echo "Defaults secure_path=\"/home/turbinia/.venv/bin:/opt/fraken:/usr/local

# Install yara rules and fraken binary.
RUN cd /opt \
&& git clone https://github.com/Neo23x0/signature-base.git \
&& git clone https://github.com/Neo23x0/signature-base.git --depth=1\
&& sudo chown -R turbinia:turbinia /opt/signature-base \
&& find /opt/signature-base -type f -not -iname '*.yar' -not -iname '*.yara' -not -iname 'file-type-signatures.txt' -delete
&& sudo git config --global --add safe.directory /opt/signature-base \
&& find /opt/signature-base -type f -not -path '*.git/*' -not -iname '*.yar' -not -iname '*.yara' -not -iname 'file-type-signatures.txt' -delete
COPY turbinia/config/rules/*.yar /opt/signature-base/yara/
RUN mkdir -p /opt/fraken && chown -R turbinia:turbinia /opt/fraken
COPY --from=us-docker.pkg.dev/osdfir-registry/turbinia/release/fraken:latest --chown=turbinia:turbinia /bin/fraken /opt/fraken/fraken
Expand Down
53 changes: 48 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ urllib3 = [
]
debugpy = "^1.8.0"
jurigged = "^0.5.7"
gitpython = "^3.1.43"

[tool.poetry.group.test]
optional = true
Expand Down
40 changes: 40 additions & 0 deletions turbinia/workers/analysis/yara.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
# limitations under the License.
"""Task for running Yara on drives & directories."""

import git
import json
import logging
import os
import re

Expand All @@ -28,6 +30,8 @@
from turbinia.workers import Priority
from turbinia.workers import TurbiniaTask

log = logging.getLogger(__name__)


class YaraAnalysisTask(TurbiniaTask):
"""Task to use Yara to analyse files."""
Expand All @@ -43,6 +47,39 @@ class YaraAnalysisTask(TurbiniaTask):
'minscore': None
}

RULES = {
'https://github.com/Neo23x0/signature-base.git': '/opt/signature-base'
}

def update_rules(self, rules):
"""Update the Yara rules.
Args:
rules (dict): dict with repo url -> path mapping
Returns:
bool: True if success, False if error
"""
if rules is None:
rules = self.RULES

log.debug('Updating Yara rules')
for repo, path in rules.items():
try:
repository = git.Repo(path)
origin = repository.remotes.origin
origin.pull(depth=1)
log.debug('Successfully updated rules from %s in %s', repo, path)
except git.exc.InvalidGitRepositoryError as e:
log.debug(
'InvalidGitRepositoryError updating rules in %s: %s', path, str(e))
return False
except Exception as e:
log.debug('Unknown error updating rules in %s: %s', path, str(e))
return False

return True

def run(self, evidence, result):
"""Run the Yara worker.
Expand All @@ -52,6 +89,9 @@ def run(self, evidence, result):
Returns:
TurbiniaTaskResult object.
"""
# Let's update the Yara rules
self.update_rules(rules=self.RULES)

# Where to store the resulting output file.
output_file_name = 'yara_analysis.txt'
output_file_path = os.path.join(self.output_dir, output_file_name)
Expand Down
11 changes: 11 additions & 0 deletions turbinia/workers/analysis/yara_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# limitations under the License.
"""Tests for the Yara analysis task."""

import git
import logging
import os
import mock
Expand Down Expand Up @@ -74,6 +75,16 @@ def test_yara_no_stderr(self):
TurbiniaException, '.*Unknown \(no stderr\).*', self.task.runFraken,
self.result, self.evidence)

def test_update_rules(self):
"""Tests the update_rules method"""
ret = self.task.update_rules(None)
self.assertEqual(ret, True)

error_rules = {'http://dummy': '/'}
ret = self.task.update_rules(error_rules)
self.assertRaises(git.exc.InvalidGitRepositoryError)
self.assertEqual(ret, False)


if __name__ == '__main__':
unittest.main()

0 comments on commit c16f355

Please sign in to comment.