agentic-threat-hunting-framework 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentic-threat-hunting-framework
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Agentic Threat Hunting Framework - Memory and AI for threat hunters
5
5
  Author-email: Sydney Marrone <athf@nebulock.io>
6
6
  Maintainer-email: Sydney Marrone <athf@nebulock.io>
@@ -1,23 +1,23 @@
1
- agentic_threat_hunting_framework-0.2.0.dist-info/licenses/LICENSE,sha256=_KObErRfiKoolznt-DF0nJnr3U9Rdh7Z4Ba7G5qqckk,1071
1
+ agentic_threat_hunting_framework-0.2.1.dist-info/licenses/LICENSE,sha256=_KObErRfiKoolznt-DF0nJnr3U9Rdh7Z4Ba7G5qqckk,1071
2
2
  athf/__init__.py,sha256=OrjZe8P97_BTEkscapnwSsqKSjwXNP9d8-HtGr19Ni0,241
3
- athf/__version__.py,sha256=qT3kQNuJrw6IXvX9OpVNABZ8axShk7vcwAcufNBLlls,59
3
+ athf/__version__.py,sha256=JMSRfysx6Kj8rOPSF3-d9x_3-QAfDP47yKOeqdgkH1M,59
4
4
  athf/cli.py,sha256=XLNRXEs9kHPH6utJ7_SnzLFcldbGAnACPMTe0xMOkhQ,4492
5
5
  athf/commands/__init__.py,sha256=uDyr0bz-agpGO8fraXQl24wuQCxqbeCevZsJ2bDK29s,25
6
6
  athf/commands/context.py,sha256=nWETwEqPMTxxkUdsfVwH-K3Td41_EKQkxutdPbbIwos,11908
7
- athf/commands/env.py,sha256=Y1UZXn5sStpkRYMJ0ZMjr_ox3ve4ZuhqGGJPBo6Ytko,11828
7
+ athf/commands/env.py,sha256=AisRllJXbyCjK_2ii21qBBmCz9raxhBUemwM7BxqIYg,11859
8
8
  athf/commands/hunt.py,sha256=2KORNWAqEvLY-Wc1q-a894g8kOpcqw_iJfnenKJeTDI,23019
9
9
  athf/commands/init.py,sha256=L_29fvZF8SZ1BKh2D6NyDuacCC5JXOTezIxdBnnK88E,10941
10
10
  athf/commands/investigate.py,sha256=WjwPtafs9bOSu09RC1QW4CVFYJjdn2C96wRa9M_o2PI,24650
11
- athf/commands/similar.py,sha256=d8AArbknc08qlyGw8kTzF35q9Dk-qBXN4SMP5n0z4-I,11793
11
+ athf/commands/similar.py,sha256=sgCNwI1Ru0lbavNm_3fjOdcJjeRPVD827vGdMF2LMBM,11761
12
12
  athf/core/__init__.py,sha256=yG7C8ljx3UW4QZoYvDjUxsWHlbS8M-GLGB7Je7rRfqo,31
13
- athf/core/attack_matrix.py,sha256=Tp-519BLjjov8NAQ84iRvIv7STegLBtF09E5vf7jO9s,2958
13
+ athf/core/attack_matrix.py,sha256=ayr9StkOskgFTsNum8MwTuCd4Z7Rhy5NNCNx1ncLYKs,3232
14
14
  athf/core/hunt_manager.py,sha256=5fxGXbtRGfUR8B0E2jb62peSQhwISmim71SZPRrJRr0,11361
15
15
  athf/core/hunt_parser.py,sha256=FUj0yyBIcZnaS9aItMImeBDhegQwpkewIwUMNXW_ZWU,5122
16
16
  athf/core/investigation_parser.py,sha256=tZnUqrFGLMUif9rayu7hgb6sKBWIvui46siUdDokAAA,6797
17
17
  athf/core/template_engine.py,sha256=vNTVhlxIXZpxU7VmQyrqCSt6ORS0IVjAV54TOmUDMTE,5636
18
18
  athf/utils/__init__.py,sha256=aEAPI1xnAsowOtc036cCb9ZOek5nrrfevu8PElhbNgk,30
19
- agentic_threat_hunting_framework-0.2.0.dist-info/METADATA,sha256=4XD3KtzPLvRcA4a4lfjmRhLAuA5AAkQBF1IdXFM7ZvQ,15472
20
- agentic_threat_hunting_framework-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
- agentic_threat_hunting_framework-0.2.0.dist-info/entry_points.txt,sha256=GopR2iTiBs-yNMWiUZ2DaFIFglXxWJx1XPjTa3ePtfE,39
22
- agentic_threat_hunting_framework-0.2.0.dist-info/top_level.txt,sha256=Cxxg6SMLfawDJWBITsciRzq27XV8fiaAor23o9Byoes,5
23
- agentic_threat_hunting_framework-0.2.0.dist-info/RECORD,,
19
+ agentic_threat_hunting_framework-0.2.1.dist-info/METADATA,sha256=WMcuK9M13SlUPyRtud9frS8t4_7lFeRXiwevmicJMgk,15472
20
+ agentic_threat_hunting_framework-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ agentic_threat_hunting_framework-0.2.1.dist-info/entry_points.txt,sha256=GopR2iTiBs-yNMWiUZ2DaFIFglXxWJx1XPjTa3ePtfE,39
22
+ agentic_threat_hunting_framework-0.2.1.dist-info/top_level.txt,sha256=Cxxg6SMLfawDJWBITsciRzq27XV8fiaAor23o9Byoes,5
23
+ agentic_threat_hunting_framework-0.2.1.dist-info/RECORD,,
athf/__version__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Version information for ATHF."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.1"
athf/commands/env.py CHANGED
@@ -3,6 +3,7 @@
3
3
  import subprocess # nosec B404
4
4
  import sys
5
5
  from pathlib import Path
6
+ from typing import Union
6
7
 
7
8
  import click
8
9
  from rich.console import Console
@@ -280,7 +281,7 @@ def info() -> None:
280
281
 
281
282
  # Get installed packages count
282
283
  pip_path = python_path.parent / "pip"
283
- package_count: int | str
284
+ package_count: Union[int, str]
284
285
  try:
285
286
  result = subprocess.run(
286
287
  [str(pip_path), "list", "--format", "freeze"],
athf/commands/similar.py CHANGED
@@ -132,8 +132,8 @@ def _find_similar_hunts(
132
132
  ) -> List[Dict[str, Any]]:
133
133
  """Find similar hunts using TF-IDF similarity."""
134
134
  try:
135
- from sklearn.feature_extraction.text import TfidfVectorizer # type: ignore
136
- from sklearn.metrics.pairwise import cosine_similarity # type: ignore
135
+ from sklearn.feature_extraction.text import TfidfVectorizer
136
+ from sklearn.metrics.pairwise import cosine_similarity
137
137
  except ImportError:
138
138
  console.print("[red]Error: scikit-learn not installed[/red]")
139
139
  console.print("[dim]Install with: pip install scikit-learn[/dim]")
@@ -4,9 +4,20 @@ This module contains reference data for the MITRE ATT&CK Enterprise matrix,
4
4
  including tactic ordering and technique counts.
5
5
  """
6
6
 
7
+ from typing import Dict, TypedDict
8
+
9
+
10
+ class TacticInfo(TypedDict):
11
+ """Type definition for tactic information."""
12
+
13
+ name: str
14
+ technique_count: int
15
+ order: int
16
+
17
+
7
18
  # MITRE ATT&CK Enterprise Matrix v14 (January 2024)
8
19
  # Approximate technique counts per tactic (includes sub-techniques)
9
- ATTACK_TACTICS = {
20
+ ATTACK_TACTICS: Dict[str, TacticInfo] = {
10
21
  "reconnaissance": {
11
22
  "name": "Reconnaissance",
12
23
  "technique_count": 10,
@@ -92,7 +103,9 @@ def get_tactic_display_name(tactic_key: str) -> str:
92
103
  Returns:
93
104
  Display name (e.g., "Credential Access")
94
105
  """
95
- return ATTACK_TACTICS.get(tactic_key, {}).get("name", tactic_key.replace("-", " ").title())
106
+ if tactic_key in ATTACK_TACTICS:
107
+ return ATTACK_TACTICS[tactic_key]["name"]
108
+ return tactic_key.replace("-", " ").title()
96
109
 
97
110
 
98
111
  def get_tactic_technique_count(tactic_key: str) -> int:
@@ -104,7 +117,9 @@ def get_tactic_technique_count(tactic_key: str) -> int:
104
117
  Returns:
105
118
  Total technique count for the tactic
106
119
  """
107
- return ATTACK_TACTICS.get(tactic_key, {}).get("technique_count", 0)
120
+ if tactic_key in ATTACK_TACTICS:
121
+ return ATTACK_TACTICS[tactic_key]["technique_count"]
122
+ return 0
108
123
 
109
124
 
110
125
  def get_sorted_tactics() -> list[str]: