-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #409 from target/iqy_scanner
Adding IQY Scanner
- Loading branch information
Showing
12 changed files
with
336 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,11 @@ | |
name = "strelka-worker" | ||
version = "0.23.10.19" | ||
description = "Strelka's backend Python worker" | ||
authors = ["[email protected]", "[email protected]", "[email protected]"] | ||
authors = [ | ||
"Paul Hutelmyer <[email protected]>", | ||
"Ryan Ohoro <[email protected]>", | ||
"Sara Kalupa <[email protected]>" | ||
] | ||
|
||
[tool.poetry.dependencies] | ||
python = ">=3.10,<=3.12" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Description # | ||
# This scanner is looking for iqy files used with excel. | ||
# | ||
# author: Tasha Taylor | ||
# date: 10/30/2023 | ||
|
||
import re | ||
|
||
from strelka import strelka | ||
|
||
|
||
class ScanIqy(strelka.Scanner): | ||
""" | ||
Extract URLs from IQY files. | ||
IQY files, or Excel Web Query Internet Inquire files, are typically created from a VBA Web Query output. | ||
The following is a typical format: | ||
WEB | ||
1 | ||
[URL] | ||
[optional parameters] | ||
Additional properties can be found at: https://learn.microsoft.com/en-us/office/vba/api/excel.querytable | ||
""" | ||
|
||
def scan(self, data, file, options, expire_at): | ||
try: | ||
# Regular expression for detecting a URL-like pattern | ||
address_pattern = re.compile( | ||
r"\b(?:http|https|ftp|ftps|file|smb)://\S+|" | ||
r"\\{2}\w+\\(?:[\w$]+\\)*[\w$]+", | ||
re.IGNORECASE, | ||
) | ||
|
||
# Attempt UTF-8 decoding first, fall back to latin-1 if necessary | ||
try: | ||
data = data.decode("utf-8") | ||
except UnicodeDecodeError: | ||
data = data.decode("latin-1") | ||
|
||
# Split lines to review each record separately | ||
data_lines = data.splitlines() | ||
|
||
addresses = set() | ||
# For each line, check if the line matches the address pattern. | ||
# In a typical IQY file, the "WEB" keyword is at the beginning of the file, | ||
# and what follows is usually just one URL with optional additional parameters. | ||
# However, because we are iterating lines anyway, lets check for additional addresses anyway. | ||
for entry in data_lines[1:]: | ||
match = address_pattern.search(entry) | ||
if match: | ||
address = match.group().strip() | ||
if address: | ||
addresses.add(address) | ||
|
||
# Evaluate if any addresses were found and assign the boolean result. | ||
self.event["address_found"] = bool(addresses) | ||
|
||
# Send all addresses to the IOC parser. | ||
self.add_iocs(list(addresses), self.type.url) | ||
|
||
except UnicodeDecodeError as e: | ||
self.flags.append(f"Unicode decoding error: {e}") | ||
except Exception as e: | ||
self.flags.append(f"Unexpected exception: {e}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
WEB | ||
1 | ||
https://github.com/target/strelka/blob/master/docs/index.html // Test case: Valid HTTPS URL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from pathlib import Path | ||
from unittest import TestCase, mock | ||
|
||
from strelka.scanners.scan_iqy import ScanIqy as ScanUnderTest | ||
from strelka.tests import run_test_scan | ||
|
||
|
||
def test_scan_iqy(mocker): | ||
""" | ||
Pass: Sample event matches output of scanner. | ||
Failure: Unable to load file or sample event fails to match. | ||
""" | ||
|
||
test_scan_event = { | ||
"elapsed": mock.ANY, | ||
"flags": [], | ||
"address_found": True, | ||
"iocs": [ | ||
{ | ||
"description": "", | ||
"ioc": "github.com", | ||
"ioc_type": "domain", | ||
"scanner": "ScanIqy", | ||
}, | ||
{ | ||
"description": "", | ||
"ioc": "https://github.com/target/strelka/blob/master/docs/index.html", | ||
"ioc_type": "url", | ||
"scanner": "ScanIqy", | ||
}, | ||
], | ||
} | ||
scanner_event = run_test_scan( | ||
mocker=mocker, | ||
scan_class=ScanUnderTest, | ||
fixture_path=Path(__file__).parent / "fixtures/test.iqy", | ||
) | ||
|
||
TestCase.maxDiff = None | ||
TestCase().assertDictEqual(test_scan_event, scanner_event) |
Oops, something went wrong.