maco 1.2.1__py3-none-any.whl → 1.2.2__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.
- maco/base_test.py +1 -2
- maco/cli.py +12 -8
- maco/collector.py +21 -3
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/METADATA +1 -1
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/RECORD +12 -12
- model_setup/maco/base_test.py +1 -2
- model_setup/maco/cli.py +12 -8
- model_setup/maco/collector.py +21 -3
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/LICENSE.md +0 -0
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/WHEEL +0 -0
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/entry_points.txt +0 -0
- {maco-1.2.1.dist-info → maco-1.2.2.dist-info}/top_level.txt +0 -0
maco/base_test.py
CHANGED
|
@@ -46,8 +46,7 @@ class BaseTest(unittest.TestCase):
|
|
|
46
46
|
runs = self.c.match(stream)
|
|
47
47
|
if not runs:
|
|
48
48
|
raise NoHitException("no yara rule hit")
|
|
49
|
-
|
|
50
|
-
resp = self.c.extract(stream, hits, self.name)
|
|
49
|
+
resp = self.c.extract(stream, self.name)
|
|
51
50
|
return resp
|
|
52
51
|
|
|
53
52
|
def _get_location(self) -> str:
|
maco/cli.py
CHANGED
|
@@ -8,7 +8,7 @@ import json
|
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
|
-
from typing import BinaryIO, List
|
|
11
|
+
from typing import BinaryIO, List, Tuple
|
|
12
12
|
|
|
13
13
|
import cart
|
|
14
14
|
|
|
@@ -57,7 +57,7 @@ def process_file(
|
|
|
57
57
|
# run and store results for extractor
|
|
58
58
|
logger.info(f"run {extractor_name} extractor from rules {[x.rule for x in hits]}")
|
|
59
59
|
try:
|
|
60
|
-
resp = collected.extract(stream,
|
|
60
|
+
resp = collected.extract(stream, extractor_name)
|
|
61
61
|
except Exception as e:
|
|
62
62
|
logger.exception(f"extractor error with {path_file} ({e})")
|
|
63
63
|
resp = None
|
|
@@ -91,18 +91,22 @@ def process_filesystem(
|
|
|
91
91
|
force: bool,
|
|
92
92
|
include_base64: bool,
|
|
93
93
|
create_venv: bool = False,
|
|
94
|
-
):
|
|
94
|
+
) -> Tuple[int, int, int]:
|
|
95
|
+
"""Process filesystem with extractors and print results of extraction.
|
|
96
|
+
|
|
97
|
+
Returns total number of analysed files, yara hits and successful maco extractions.
|
|
98
|
+
"""
|
|
95
99
|
if force:
|
|
96
100
|
logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
|
|
97
101
|
collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
|
|
98
102
|
|
|
99
103
|
logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
|
|
100
104
|
for _, extractor in collected.extractors.items():
|
|
101
|
-
|
|
105
|
+
extractor_meta = extractor["metadata"]
|
|
102
106
|
logger.info(
|
|
103
|
-
f"{
|
|
104
|
-
f" {
|
|
105
|
-
f"\n{
|
|
107
|
+
f"{extractor_meta['family']} by {extractor_meta['author']}"
|
|
108
|
+
f" {extractor_meta['last_modified']} {extractor_meta['sharing']}"
|
|
109
|
+
f"\n{extractor_meta['description']}\n"
|
|
106
110
|
)
|
|
107
111
|
|
|
108
112
|
num_analysed = 0
|
|
@@ -144,7 +148,7 @@ def process_filesystem(
|
|
|
144
148
|
finally:
|
|
145
149
|
logger.info("")
|
|
146
150
|
logger.info(f"{num_analysed} analysed, {num_hits} hits, {num_extracted} extracted")
|
|
147
|
-
|
|
151
|
+
return num_analysed, num_hits, num_extracted
|
|
148
152
|
|
|
149
153
|
def main():
|
|
150
154
|
parser = argparse.ArgumentParser(description="Run extractors over samples.")
|
maco/collector.py
CHANGED
|
@@ -40,7 +40,11 @@ def _verify_response(resp: Union[BaseModel, dict]) -> Dict:
|
|
|
40
40
|
|
|
41
41
|
class Collector:
|
|
42
42
|
def __init__(
|
|
43
|
-
self,
|
|
43
|
+
self,
|
|
44
|
+
path_extractors: str,
|
|
45
|
+
include: List[str] = None,
|
|
46
|
+
exclude: List[str] = None,
|
|
47
|
+
create_venv: bool = False,
|
|
44
48
|
):
|
|
45
49
|
"""Discover and load extractors from file system."""
|
|
46
50
|
path_extractors = os.path.realpath(path_extractors)
|
|
@@ -72,6 +76,13 @@ class Collector:
|
|
|
72
76
|
module_path=module.__file__,
|
|
73
77
|
module_name=member.__module__,
|
|
74
78
|
extractor_class=member.__name__,
|
|
79
|
+
metadata={
|
|
80
|
+
"family": member.family,
|
|
81
|
+
"author": member.author,
|
|
82
|
+
"last_modified": member.last_modified,
|
|
83
|
+
"sharing": member.sharing,
|
|
84
|
+
"description": member.__doc__,
|
|
85
|
+
},
|
|
75
86
|
)
|
|
76
87
|
namespaced_rules[name] = member.yara_rule or extractor.DEFAULT_YARA_RULE.format(name=name)
|
|
77
88
|
|
|
@@ -116,7 +127,6 @@ class Collector:
|
|
|
116
127
|
def extract(
|
|
117
128
|
self,
|
|
118
129
|
stream: BinaryIO,
|
|
119
|
-
matches: List[yara.Match],
|
|
120
130
|
extractor_name: str,
|
|
121
131
|
) -> Dict[str, Any]:
|
|
122
132
|
"""Run extractor with stream and verify output matches the model."""
|
|
@@ -127,7 +137,15 @@ class Collector:
|
|
|
127
137
|
sample_path.write(stream.read())
|
|
128
138
|
sample_path.flush()
|
|
129
139
|
# enforce types and verify properties, and remove defaults
|
|
130
|
-
return _verify_response(
|
|
140
|
+
return _verify_response(
|
|
141
|
+
utils.run_extractor(
|
|
142
|
+
sample_path.name,
|
|
143
|
+
module_name=extractor["module_name"],
|
|
144
|
+
extractor_class=extractor["extractor_class"],
|
|
145
|
+
module_path=extractor["module_path"],
|
|
146
|
+
venv=extractor["venv"],
|
|
147
|
+
)
|
|
148
|
+
)
|
|
131
149
|
except Exception:
|
|
132
150
|
# caller can deal with the exception
|
|
133
151
|
raise
|
|
@@ -6,18 +6,18 @@ demo_extractors/complex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
6
6
|
demo_extractors/complex/complex.py,sha256=TkNmR9UUYo1f2JVpJhGasLG-5wHZI05JYxMIXj16GKM,2307
|
|
7
7
|
demo_extractors/complex/complex_utils.py,sha256=aec8kJsYUrMPo-waihkVLt-0QpiOPkw7dDqfT9MNuHk,123
|
|
8
8
|
maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
maco/base_test.py,sha256=
|
|
10
|
-
maco/cli.py,sha256=
|
|
11
|
-
maco/collector.py,sha256=
|
|
9
|
+
maco/base_test.py,sha256=pqet9ofMwFRTj3JHgPdh9WHwdyp8kxNMi1vJNUzkSNA,2518
|
|
10
|
+
maco/cli.py,sha256=1I3U54yPddTxqWclCtZ5Ma5hW6RoVTZMzLSFOjjfM1g,8008
|
|
11
|
+
maco/collector.py,sha256=sxP374lK16lzdi0lhm5e4GT3a5lzeyE1VCicE4m_E3k,6003
|
|
12
12
|
maco/extractor.py,sha256=4ZQd8OfvEQYUIkUS3LzZ5tcioembuLhT9_uRVNKSsyM,2750
|
|
13
13
|
maco/utils.py,sha256=lkZ4yb-LjkzjVpyY6INNWKyimYg5k3Y2N_Hr9CdrFbw,18232
|
|
14
14
|
maco/yara.py,sha256=vPzCqauVp52ivcTdt8zwrYqDdkLutGlesma9DhKPzHw,2925
|
|
15
15
|
maco/model/__init__.py,sha256=SJrwdn12wklUFm2KoIgWjX_KgvJxCM7Ca9ntXOneuzc,31
|
|
16
16
|
maco/model/model.py,sha256=ngen4ViyLdRo_z_TqZBjw2DN0NrRLpuxOy15-6QmtNw,23536
|
|
17
17
|
model_setup/maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
model_setup/maco/base_test.py,sha256=
|
|
19
|
-
model_setup/maco/cli.py,sha256=
|
|
20
|
-
model_setup/maco/collector.py,sha256=
|
|
18
|
+
model_setup/maco/base_test.py,sha256=pqet9ofMwFRTj3JHgPdh9WHwdyp8kxNMi1vJNUzkSNA,2518
|
|
19
|
+
model_setup/maco/cli.py,sha256=1I3U54yPddTxqWclCtZ5Ma5hW6RoVTZMzLSFOjjfM1g,8008
|
|
20
|
+
model_setup/maco/collector.py,sha256=sxP374lK16lzdi0lhm5e4GT3a5lzeyE1VCicE4m_E3k,6003
|
|
21
21
|
model_setup/maco/extractor.py,sha256=4ZQd8OfvEQYUIkUS3LzZ5tcioembuLhT9_uRVNKSsyM,2750
|
|
22
22
|
model_setup/maco/utils.py,sha256=lkZ4yb-LjkzjVpyY6INNWKyimYg5k3Y2N_Hr9CdrFbw,18232
|
|
23
23
|
model_setup/maco/yara.py,sha256=vPzCqauVp52ivcTdt8zwrYqDdkLutGlesma9DhKPzHw,2925
|
|
@@ -33,9 +33,9 @@ tests/extractors/basic_longer.py,sha256=1ClU2QD-Y0TOl_loNFvEqIEpTR5TSVJ6zg9ZmC-E
|
|
|
33
33
|
tests/extractors/test_basic.py,sha256=FLKekfSGM69HaiF7Vu_7D7KDXHZko-9hZkMO8_DoyYA,697
|
|
34
34
|
tests/extractors/bob/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
35
|
tests/extractors/bob/bob.py,sha256=Gy5p8KssJX87cwa9vVv8UBODF_ulbUteZXh15frW2hs,247
|
|
36
|
-
maco-1.2.
|
|
37
|
-
maco-1.2.
|
|
38
|
-
maco-1.2.
|
|
39
|
-
maco-1.2.
|
|
40
|
-
maco-1.2.
|
|
41
|
-
maco-1.2.
|
|
36
|
+
maco-1.2.2.dist-info/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
|
|
37
|
+
maco-1.2.2.dist-info/METADATA,sha256=uVpcgj3TeAXEyj7UZbLF2IuQqmKIgnuhqw2uIMuSpO8,15610
|
|
38
|
+
maco-1.2.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
39
|
+
maco-1.2.2.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
|
|
40
|
+
maco-1.2.2.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
|
|
41
|
+
maco-1.2.2.dist-info/RECORD,,
|
model_setup/maco/base_test.py
CHANGED
|
@@ -46,8 +46,7 @@ class BaseTest(unittest.TestCase):
|
|
|
46
46
|
runs = self.c.match(stream)
|
|
47
47
|
if not runs:
|
|
48
48
|
raise NoHitException("no yara rule hit")
|
|
49
|
-
|
|
50
|
-
resp = self.c.extract(stream, hits, self.name)
|
|
49
|
+
resp = self.c.extract(stream, self.name)
|
|
51
50
|
return resp
|
|
52
51
|
|
|
53
52
|
def _get_location(self) -> str:
|
model_setup/maco/cli.py
CHANGED
|
@@ -8,7 +8,7 @@ import json
|
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
|
-
from typing import BinaryIO, List
|
|
11
|
+
from typing import BinaryIO, List, Tuple
|
|
12
12
|
|
|
13
13
|
import cart
|
|
14
14
|
|
|
@@ -57,7 +57,7 @@ def process_file(
|
|
|
57
57
|
# run and store results for extractor
|
|
58
58
|
logger.info(f"run {extractor_name} extractor from rules {[x.rule for x in hits]}")
|
|
59
59
|
try:
|
|
60
|
-
resp = collected.extract(stream,
|
|
60
|
+
resp = collected.extract(stream, extractor_name)
|
|
61
61
|
except Exception as e:
|
|
62
62
|
logger.exception(f"extractor error with {path_file} ({e})")
|
|
63
63
|
resp = None
|
|
@@ -91,18 +91,22 @@ def process_filesystem(
|
|
|
91
91
|
force: bool,
|
|
92
92
|
include_base64: bool,
|
|
93
93
|
create_venv: bool = False,
|
|
94
|
-
):
|
|
94
|
+
) -> Tuple[int, int, int]:
|
|
95
|
+
"""Process filesystem with extractors and print results of extraction.
|
|
96
|
+
|
|
97
|
+
Returns total number of analysed files, yara hits and successful maco extractions.
|
|
98
|
+
"""
|
|
95
99
|
if force:
|
|
96
100
|
logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
|
|
97
101
|
collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
|
|
98
102
|
|
|
99
103
|
logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
|
|
100
104
|
for _, extractor in collected.extractors.items():
|
|
101
|
-
|
|
105
|
+
extractor_meta = extractor["metadata"]
|
|
102
106
|
logger.info(
|
|
103
|
-
f"{
|
|
104
|
-
f" {
|
|
105
|
-
f"\n{
|
|
107
|
+
f"{extractor_meta['family']} by {extractor_meta['author']}"
|
|
108
|
+
f" {extractor_meta['last_modified']} {extractor_meta['sharing']}"
|
|
109
|
+
f"\n{extractor_meta['description']}\n"
|
|
106
110
|
)
|
|
107
111
|
|
|
108
112
|
num_analysed = 0
|
|
@@ -144,7 +148,7 @@ def process_filesystem(
|
|
|
144
148
|
finally:
|
|
145
149
|
logger.info("")
|
|
146
150
|
logger.info(f"{num_analysed} analysed, {num_hits} hits, {num_extracted} extracted")
|
|
147
|
-
|
|
151
|
+
return num_analysed, num_hits, num_extracted
|
|
148
152
|
|
|
149
153
|
def main():
|
|
150
154
|
parser = argparse.ArgumentParser(description="Run extractors over samples.")
|
model_setup/maco/collector.py
CHANGED
|
@@ -40,7 +40,11 @@ def _verify_response(resp: Union[BaseModel, dict]) -> Dict:
|
|
|
40
40
|
|
|
41
41
|
class Collector:
|
|
42
42
|
def __init__(
|
|
43
|
-
self,
|
|
43
|
+
self,
|
|
44
|
+
path_extractors: str,
|
|
45
|
+
include: List[str] = None,
|
|
46
|
+
exclude: List[str] = None,
|
|
47
|
+
create_venv: bool = False,
|
|
44
48
|
):
|
|
45
49
|
"""Discover and load extractors from file system."""
|
|
46
50
|
path_extractors = os.path.realpath(path_extractors)
|
|
@@ -72,6 +76,13 @@ class Collector:
|
|
|
72
76
|
module_path=module.__file__,
|
|
73
77
|
module_name=member.__module__,
|
|
74
78
|
extractor_class=member.__name__,
|
|
79
|
+
metadata={
|
|
80
|
+
"family": member.family,
|
|
81
|
+
"author": member.author,
|
|
82
|
+
"last_modified": member.last_modified,
|
|
83
|
+
"sharing": member.sharing,
|
|
84
|
+
"description": member.__doc__,
|
|
85
|
+
},
|
|
75
86
|
)
|
|
76
87
|
namespaced_rules[name] = member.yara_rule or extractor.DEFAULT_YARA_RULE.format(name=name)
|
|
77
88
|
|
|
@@ -116,7 +127,6 @@ class Collector:
|
|
|
116
127
|
def extract(
|
|
117
128
|
self,
|
|
118
129
|
stream: BinaryIO,
|
|
119
|
-
matches: List[yara.Match],
|
|
120
130
|
extractor_name: str,
|
|
121
131
|
) -> Dict[str, Any]:
|
|
122
132
|
"""Run extractor with stream and verify output matches the model."""
|
|
@@ -127,7 +137,15 @@ class Collector:
|
|
|
127
137
|
sample_path.write(stream.read())
|
|
128
138
|
sample_path.flush()
|
|
129
139
|
# enforce types and verify properties, and remove defaults
|
|
130
|
-
return _verify_response(
|
|
140
|
+
return _verify_response(
|
|
141
|
+
utils.run_extractor(
|
|
142
|
+
sample_path.name,
|
|
143
|
+
module_name=extractor["module_name"],
|
|
144
|
+
extractor_class=extractor["extractor_class"],
|
|
145
|
+
module_path=extractor["module_path"],
|
|
146
|
+
venv=extractor["venv"],
|
|
147
|
+
)
|
|
148
|
+
)
|
|
131
149
|
except Exception:
|
|
132
150
|
# caller can deal with the exception
|
|
133
151
|
raise
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|