Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
phutelmyer committed Oct 24, 2023
2 parents a99fb55 + c8bcfed commit 5dfe332
Show file tree
Hide file tree
Showing 18 changed files with 95 additions and 66 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog
Changes to the project will be tracked in this file via the date of change.

## 2023-10-24
- Improvements and tests for `ScanQR` scanner (@ryanohoro)

## 2023-10-23
- Adding the ability to use precompiled YARA rules: Speed up YARA initialization on Strelka boot by using precompiled rules
- Configuration file updates: Adding compiled YARA location
Expand Down
2 changes: 2 additions & 0 deletions configs/python/backend/backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ scanners:
- 'bmp_file'
- 'image/webp'
priority: 5
options:
support_inverted: True
'ScanRar':
- positive:
flavors:
Expand Down
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ The table below describes each scanner and its options. Each scanner has the hid
| ScanFloss | Analyzes executable files with FireEye [floss](https://github.com/fireeye/flare-floss) | `tempfile_directory` -- location where `tempfile` will write temporary files (defaults to `/tmp/`)<br>`limit` -- Maximum amount of strings to collect. (defaults to `100`) |
| ScanFooter | Collects file footer | `length` -- number of footer characters to log as metadata (defaults to `50`) <br> `encodings` -- list of output encodings, any of `classic`, `raw`, `hex`, `backslash` |
| ScanGif | Extracts data embedded in GIF files | N/A |
| ScanGzip | Decompresses gzip files | N/A
| ScanGzip | Decompresses gzip files | N/A
| ScanHash | Calculates file hash values | N/A |
| ScanHeader | Collects file header | `length` -- number of header characters to log as metadata (defaults to `50`) <br> `encodings` -- list of output encodings, any of `classic`, `raw`, `hex`, `backslash` |
| ScanHtml | Collects metadata and extracts embedded files from HTML files | `parser` -- sets the HTML parser used during scanning (defaults to `html.parser`) <br> `max_links` -- Maximum amount of links to output in hyperlinks field (defaults to `50`) |
Expand All @@ -784,7 +784,7 @@ The table below describes each scanner and its options. Each scanner has the hid
| ScanPhp | Collects metadata from PHP files | N/A |
| ScanPkcs7 | Extracts files from PKCS7 certificate files | N/A |
| ScanPlist | Collects attributes from binary and XML property list files | `keys` -- list of keys to log (defaults to `all`) |
| ScanQr | Collects QR code metadata from image files | N/A | [Aaron Herman](https://github.com/aaronherman)
| ScanQr | Collects QR code metadata from image files | `support_inverted` -- Enable/disable image inversion to support inverted QR codes (white on black). Adds some image processing overhead. | [Aaron Herman](https://github.com/aaronherman)
| ScanRar | Extracts files from RAR archives | `limit` -- maximum number of files to extract (defaults to `1000`)<br>`password_file` -- location of passwords file for RAR archives (defaults to `/etc/strelka/passwords.dat`) |
| ScanRpm | Collects metadata and extracts files from RPM files | `tempfile_directory` -- location where `tempfile` will write temporary files (defaults to `/tmp/`) |
| ScanRtf | Extracts embedded files from RTF files | `limit` -- maximum number of files to extract (defaults to `1000`) |
Expand All @@ -808,7 +808,7 @@ The table below describes each scanner and its options. Each scanner has the hid
| ScanXml | Log metadata and extract files from XML files | `extract_tags` -- list of XML tags that will have their text extracted as child files (defaults to empty list)<br>`metadata_tags` -- list of XML tags that will have their text logged as metadata (defaults to empty list) |
| ScanYara | Scans files with YARA rules | `location` -- location of the YARA rules file or directory (defaults to `/etc/strelka/yara/`)<br>`compiled` -- Enable use of compiled YARA rules, as well as the path.<br>`store_offset` -- Stores file offset for YARA match<br>`offset_meta_key` -- YARA meta key that must exist in the YARA rule for the offset to be stored.<br>`offset_padding` -- Amount of data to be stored before and after offset for additional context. |
| ScanZip | Extracts files from zip archives | `limit` -- maximum number of files to extract (defaults to `1000`)<br>`password_file` -- location of passwords file for zip archives (defaults to `/etc/strelka/passwords.dat`) |
| ScanZlib | Decompresses gzip files | N/A
| ScanZlib | Decompresses gzip files | N/A

## Tests
As Strelka consists of many scanners and dependencies for those scanners. Pytests are particularly valuable for testing the ongoing functionality of Strelka and it's scanners. Tests allow users to write test cases that verify the correct behavior of Strelka scanners to ensure that the scanners remain reliable and accurate. Additionally, using pytests can help streamline the development process, allowing developers to focus on writing new features and improvements for the scanners. Strelka contains a set of standard test fixture files that represent the types of files Strelka ingests. Test fixtures can also be loaded remotely with the helper functions `get_remote_fixture` and `get_remote_fixture_archive` for scanner tests that need malicious samples.
Expand Down
69 changes: 24 additions & 45 deletions src/python/strelka/scanners/scan_qr.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import io
import logging
import re

from PIL import Image
from PIL import Image, ImageOps
from pyzbar.pyzbar import decode

from strelka import strelka
Expand All @@ -16,53 +15,33 @@ class ScanQr(strelka.Scanner):
"""

def scan(self, data, file, options, expire_at):
support_inverted = options.get("support_inverted", True)

self.event["data"] = []

barcode_data = []

try:
URL_REGEX = (
r"^((https?|ftp|smtp)://)?(www\.)?[a-z0-9]+\.[a-z]+(/[a-zA-Z0-9#]+/?)*"
)
barcodes = decode(Image.open(io.BytesIO(data)))
img = Image.open(io.BytesIO(data))
barcodes = decode(img)

if barcodes:
for barcode in barcodes:
barcode_data.append(barcode.data.decode("utf-8"))

if support_inverted:
img_inverted = ImageOps.invert(img)
barcodes = decode(img_inverted)

try:
if barcodes:
self.event["data"] = barcodes[0].data.decode("utf-8")
else:
return
except strelka.ScannerTimeout:
raise
except Exception:
self.flags.append("decode error")
return
self.flags.append("inverted")
for barcode in barcodes:
barcode_data.append(barcode.data.decode("utf-8"))

if barcode_data:
self.event["data"] = barcode_data

try:
# Type: Email
if any(qtype in self.event["data"] for qtype in ["MATMSG", "mailto"]):
self.event["type"] = "email"
# Type: Mobile
elif any(qtype in self.event["data"] for qtype in ["tel:", "sms:"]):
self.event["type"] = "mobile"
# Type: App
elif any(
qtype in self.event["data"]
for qtype in ["itunes.apple.com", "market://"]
):
self.event["type"] = "app"
# Type: Geo
elif "geo:" in self.event["data"]:
self.event["type"] = "geo"
# Type: WIFI
elif "WIFI" in self.event["data"]:
self.event["type"] = "wifi"
# Type: URL
elif re.match(URL_REGEX, self.event["data"]):
self.event["type"] = "url"
# Type: No Defined Match
else:
self.event["type"] = "undefined"
except strelka.ScannerTimeout:
raise
except Exception:
self.flags.append("parse error")
except strelka.ScannerTimeout:
raise
except Exception:
self.flags.append("general error")
self.flags.append("decode_error")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/python/strelka/tests/fixtures/test_qr_epc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/python/strelka/tests/fixtures/test_qr_sms.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/python/strelka/tests/fixtures/test_qr_url.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 5dfe332

Please sign in to comment.