From b65345b8c43ecd51dc47a3e8acca026460bee237 Mon Sep 17 00:00:00 2001 From: ackatz Date: Mon, 16 Oct 2023 17:34:45 -0600 Subject: [PATCH] Add YARAify --- README.md | 3 ++- pyproject.toml | 2 +- seclook/cli.py | 4 ++++ seclook/lookups/yaraify_lookup.py | 10 ++++++++++ seclook/tests/test_missing_value.py | 7 +++++++ seclook/tests/test_valid_service_value.py | 8 +++++++- 6 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 seclook/lookups/yaraify_lookup.py diff --git a/README.md b/README.md index c145652..f6ae3d1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ You can look up information using commands like `seclook [service] [value]`, whe 2. Copy [config.ini.sample](https://github.com/ackatz/seclook/blob/main/config.ini.sample) from this directory and place it in `~/.seclook/config.ini` 3. Open `~/.seclook/config.ini` and add in your own API keys for the services you want to use. -> Some services (e.g., GreyNoise, ThreatFox) _don't require API keys_, but may be rate-limited more quickly without one or have other limitations. +> Some services (e.g., GreyNoise, ThreatFox) _don't require API keys_, but may be rate-limited more quickly without one or have other limitations. Others (e.g., YARAify) do not need an API key at all and will not be referenced in the config file. ## Usage @@ -62,6 +62,7 @@ seclook virustotal 44d88612fea8a8f36de82e1278abb02f | grep malicious - [x] [GreyNoise](https://www.greynoise.io/) - [x] [ThreatFox](https://threatfox.abuse.ch/) - [x] [Pulsedive](https://pulsedive.com/) +- [x] [Yaraify](https://yaraify.abuse.ch/) You can also view supported services by passing `list` as the service name: diff --git a/pyproject.toml b/pyproject.toml index 2a7be30..fccf397 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "seclook" -version = "0.5.3" +version = "0.6.0" description = "Simple security lookups via CLI" authors = ["ackatz "] license = "MIT" diff --git a/seclook/cli.py b/seclook/cli.py index c578480..a527e5a 100755 --- a/seclook/cli.py +++ b/seclook/cli.py @@ -9,6 +9,7 @@ greynoise_lookup, threatfox_lookup, pulsedive_lookup, + yaraify_lookup, ) from seclook.openai import gpt4_summarize import json @@ -37,6 +38,7 @@ def main(service, value, export, gpt4): "greynoise", "threatfox", "pulsedive", + "yaraify", ] if not service: @@ -70,6 +72,8 @@ def main(service, value, export, gpt4): result = threatfox_lookup.search(value) elif service.lower() == "pulsedive": result = pulsedive_lookup.search(value) + elif service.lower() == "yaraify": + result = yaraify_lookup.search(value) if export: desktop = os.path.join(os.path.expanduser("~"), "Desktop") diff --git a/seclook/lookups/yaraify_lookup.py b/seclook/lookups/yaraify_lookup.py new file mode 100644 index 0000000..3ae1aa8 --- /dev/null +++ b/seclook/lookups/yaraify_lookup.py @@ -0,0 +1,10 @@ +import requests + +base_url = "https://yaraify-api.abuse.ch/api/v1/" + + +def search(value): + data = {"query": "lookup_hash", "search_term": f"{value}"} + headers = {"Content-Type": "application/json"} + response = requests.post(base_url, headers=headers, json=data) + return response.json() diff --git a/seclook/tests/test_missing_value.py b/seclook/tests/test_missing_value.py index d1f177e..dbde709 100644 --- a/seclook/tests/test_missing_value.py +++ b/seclook/tests/test_missing_value.py @@ -9,6 +9,13 @@ def test_threatfox_missing_value(): assert "Missing value argument for 'threatfox'." in result.output +def test_yaraify_missing_value(): + runner = CliRunner() + result = runner.invoke(main, ["yaraify"]) + assert result.exit_code != 0 + assert "Missing value argument for 'yaraify'." in result.output + + def test_pulsedive_missing_value(): runner = CliRunner() result = runner.invoke(main, ["pulsedive"]) diff --git a/seclook/tests/test_valid_service_value.py b/seclook/tests/test_valid_service_value.py index eded257..920ebae 100644 --- a/seclook/tests/test_valid_service_value.py +++ b/seclook/tests/test_valid_service_value.py @@ -8,6 +8,12 @@ def test_threatfox_valid_value(): assert result.exit_code == 0 +def test_yaraify_valid_value(): + runner = CliRunner() + result = runner.invoke(main, ["yaraify", "asdf"]) + assert result.exit_code == 0 + + def test_pulsedive_valid_value(): runner = CliRunner() result = runner.invoke(main, ["pulsedive", "1.1.1.1"]) @@ -28,7 +34,7 @@ def test_virustotal_valid_value(): def test_emailrep_valid_value(): runner = CliRunner() - result = runner.invoke(main, ["emailrep", "andrew@akatz.org"]) + result = runner.invoke(main, ["emailrep", "example@example.org"]) assert result.exit_code == 0