maco 1.2.17__py3-none-any.whl → 1.2.19__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.
@@ -0,0 +1,129 @@
1
+ """yara-python facade that uses yara-x."""
2
+
3
+ import re
4
+ from collections import namedtuple
5
+ from itertools import cycle
6
+ from typing import Dict, List, Union
7
+
8
+ import yara_x
9
+
10
+ from maco.exceptions import SyntaxError
11
+
12
+ RULE_ID_RE = re.compile("(\w+)? ?rule (\w+)")
13
+
14
+
15
+ # Create interfaces that resembles yara-python (but is running yara-x under the hood)
16
+ class StringMatchInstance:
17
+ """Instance of a string match."""
18
+
19
+ def __init__(self, match: yara_x.Match, file_content: bytes):
20
+ """Initializes StringMatchInstance."""
21
+ self.matched_data = file_content[match.offset : match.offset + match.length]
22
+ self.matched_length = match.length
23
+ self.offset = match.offset
24
+ self.xor_key = match.xor_key
25
+
26
+ def plaintext(self) -> bytes:
27
+ """Plaintext of the matched data.
28
+
29
+ Returns:
30
+ (bytes): Plaintext of the matched cipher text
31
+ """
32
+ if not self.xor_key:
33
+ # No need to XOR the matched data
34
+ return self.matched_data
35
+ else:
36
+ return bytes(c ^ k for c, k in zip(self.matched_data, cycle(self.xor_key)))
37
+
38
+
39
+ class StringMatch:
40
+ """String match."""
41
+
42
+ def __init__(self, pattern: yara_x.Pattern, file_content: bytes):
43
+ """Initializes StringMatch."""
44
+ self.identifier = pattern.identifier
45
+ self.instances = [StringMatchInstance(match, file_content) for match in pattern.matches]
46
+ self._is_xor = any([match.xor_key for match in pattern.matches])
47
+
48
+ def is_xor(self):
49
+ """Checks if string match is xor'd.
50
+
51
+ Returns:
52
+ (bool): True if match is xor'd
53
+ """
54
+ return self._is_xor
55
+
56
+
57
+ class Match:
58
+ """Match."""
59
+
60
+ def __init__(self, rule: yara_x.Rule, file_content: bytes):
61
+ """Initializes Match."""
62
+ self.rule = rule.identifier
63
+ self.namespace = rule.namespace
64
+ self.tags = list(rule.tags) or []
65
+ self.meta = dict()
66
+ # Ensure metadata doesn't get overwritten
67
+ for k, v in rule.metadata:
68
+ self.meta.setdefault(k, []).append(v)
69
+ self.strings = [StringMatch(pattern, file_content) for pattern in rule.patterns]
70
+
71
+
72
+ class Rules:
73
+ """Rules."""
74
+
75
+ def __init__(self, source: str = None, sources: Dict[str, str] = None):
76
+ """Initializes Rules.
77
+
78
+ Raises:
79
+ SyntaxError: Raised when there's a syntax error in the YARA rule.
80
+ """
81
+ Rule = namedtuple("Rule", "identifier namespace is_global")
82
+ if source:
83
+ sources = {"default": source}
84
+
85
+ try:
86
+ self._rules = []
87
+ compiler = yara_x.Compiler(relaxed_re_syntax=True)
88
+ for namespace, source in sources.items():
89
+ compiler.new_namespace(namespace)
90
+ for rule_type, id in RULE_ID_RE.findall(source):
91
+ is_global = True if rule_type == "global" else False
92
+ self._rules.append(Rule(namespace=namespace, identifier=id, is_global=is_global))
93
+ compiler.add_source(source)
94
+ self.scanner = yara_x.Scanner(compiler.build())
95
+ except yara_x.CompileError as e:
96
+ raise SyntaxError(e)
97
+
98
+ def __iter__(self):
99
+ """Iterate over rules.
100
+
101
+ Yields:
102
+ YARA rules
103
+ """
104
+ for rule in self._rules:
105
+ yield rule
106
+
107
+ def match(self, filepath: str = None, data: Union[bytes, bytearray] = None) -> List[Match]:
108
+ """Performs a scan to check for YARA rules matches based on the file, either given by path or buffer.
109
+
110
+ Returns:
111
+ (List[Match]): A list of YARA matches.
112
+ """
113
+ if filepath:
114
+ with open(filepath, "rb") as fp:
115
+ data = fp.read()
116
+
117
+ if isinstance(data, bytearray):
118
+ data = bytes(data)
119
+
120
+ return [Match(m, data) for m in self.scanner.scan(data).matching_rules]
121
+
122
+
123
+ def compile(source: str = None, sources: Dict[str, str] = None) -> Rules:
124
+ """Compiles YARA rules from source or from sources.
125
+
126
+ Returns:
127
+ (Rules): a Rules object
128
+ """
129
+ return Rules(source, sources)
maco/collector.py CHANGED
@@ -122,6 +122,7 @@ class Collector:
122
122
  "author": member.author,
123
123
  "last_modified": member.last_modified,
124
124
  "sharing": member.sharing,
125
+ "result_sharing": member.result_sharing,
125
126
  "description": member.__doc__,
126
127
  },
127
128
  )
maco/extractor.py CHANGED
@@ -25,7 +25,8 @@ class Extractor:
25
25
  family: Union[str, List[str]] = None # family or families of malware that is detected by the extractor
26
26
  author: str = None # author of the extractor (name@organisation)
27
27
  last_modified: str = None # last modified date (YYYY-MM-DD)
28
- sharing: str = "TLP:WHITE" # who can this be shared with?
28
+ sharing: str = "TLP:CLEAR" # who can this be shared with?
29
+ result_sharing: str = sharing # who can the results be shared with? (defaults to sharing)
29
30
  yara_rule: str = None # yara rule that we filter inputs with
30
31
  reference: str = None # link to malware report or other reference information
31
32
  logger: logging.Logger = None # logger for use when debugging
maco/utils.py CHANGED
@@ -280,8 +280,8 @@ def _install_required_packages(create_venv: bool, directories: List[str], python
280
280
 
281
281
  install_command.extend(pyproject_command)
282
282
 
283
- # always require maco to be installed
284
- install_command.append("maco")
283
+ # Always require maco-extractor to be installed
284
+ install_command.append("maco-extractor")
285
285
  logger.debug(f"Install command: {' '.join(install_command)} [{dir}]")
286
286
  # this uses VIRTUAL_ENV to control usage of a virtual environment
287
287
  p = subprocess.run(
@@ -1,6 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maco
3
- Version: 1.2.17
3
+ Version: 1.2.19
4
+ Summary: Maco is a framework for creating and using malware configuration extractors.
4
5
  Author: sl-govau
5
6
  Maintainer: cccs-rs
6
7
  License: MIT License
@@ -8,28 +8,38 @@ demo_extractors/terminator.py,sha256=nxoZYRteYDQS7wp-aAsCaxCSJ9FSE54jPrW3fJpRVho
8
8
  demo_extractors/complex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  demo_extractors/complex/complex.py,sha256=GYKmPOD8-fyVHxwjZb-3t1IghKVMuLtdUvCs5C5yPe0,2625
10
10
  demo_extractors/complex/complex_utils.py,sha256=5kdMl-niSH9d-d3ChuItpmlPT4U-S9g-iyBZlR4tfmQ,296
11
+ extractor_setup/maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ extractor_setup/maco/base_test.py,sha256=DrVE7vOazeLQpOQeIDwBYK1WtlmdJrRe50JOqP5t4Y0,3198
13
+ extractor_setup/maco/cli.py,sha256=nrSukAJAthbstZT3-lQNPz4zOOMcBhvfYQqLh_B5Jdk,9457
14
+ extractor_setup/maco/collector.py,sha256=I0Nidf4-xcvoe6X0bbCsAXjr66iPf00JDO6ocKkaZLc,8309
15
+ extractor_setup/maco/exceptions.py,sha256=XBHUrs1kr1ZayPI9B_W-WejKgVmC8sWL_o4RL0b4DQE,745
16
+ extractor_setup/maco/extractor.py,sha256=nqIfUcrc_l57FicKZc6HLtN223-_zkYWL1AYMy1WAmA,3007
17
+ extractor_setup/maco/utils.py,sha256=yNm5CiHc9033ONX_gFwg9Lng5IYFujLDtw6FfiJkAao,23425
18
+ extractor_setup/maco/yara.py,sha256=y141t8NqDDXHY23uE1d6BDPeNmSuUuohR6Yr_LKa7GI,4067
19
+ extractor_setup/maco/model/__init__.py,sha256=ULdyHx8R5D2ICHZo3VoCk1YTlewTok36TYIpwx__pNY,45
20
+ extractor_setup/maco/model/model.py,sha256=DBHTmZXMzjpVq0s2mzZv3VCzPhwPnv7sH6u_QZCTcA4,24484
11
21
  maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
22
  maco/base_test.py,sha256=DrVE7vOazeLQpOQeIDwBYK1WtlmdJrRe50JOqP5t4Y0,3198
13
23
  maco/cli.py,sha256=nrSukAJAthbstZT3-lQNPz4zOOMcBhvfYQqLh_B5Jdk,9457
14
- maco/collector.py,sha256=R3zw-fUJBlwmcSqvkQ-PnoJdHfRm2V0JAOl7N8MTAbY,8240
24
+ maco/collector.py,sha256=I0Nidf4-xcvoe6X0bbCsAXjr66iPf00JDO6ocKkaZLc,8309
15
25
  maco/exceptions.py,sha256=XBHUrs1kr1ZayPI9B_W-WejKgVmC8sWL_o4RL0b4DQE,745
16
- maco/extractor.py,sha256=s36aGcsXSc-9iCik6iihVt5G1a1DZUA7TquvWYQNwdE,2912
17
- maco/utils.py,sha256=7Xf-kWCDm1DdpBCGOvecEb_hqKoRgNJi0M_OYsJeSrM,23405
26
+ maco/extractor.py,sha256=nqIfUcrc_l57FicKZc6HLtN223-_zkYWL1AYMy1WAmA,3007
27
+ maco/utils.py,sha256=yNm5CiHc9033ONX_gFwg9Lng5IYFujLDtw6FfiJkAao,23425
18
28
  maco/yara.py,sha256=y141t8NqDDXHY23uE1d6BDPeNmSuUuohR6Yr_LKa7GI,4067
19
29
  maco/model/__init__.py,sha256=ULdyHx8R5D2ICHZo3VoCk1YTlewTok36TYIpwx__pNY,45
20
30
  maco/model/model.py,sha256=DBHTmZXMzjpVq0s2mzZv3VCzPhwPnv7sH6u_QZCTcA4,24484
21
- maco-1.2.17.dist-info/licenses/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
31
+ maco-1.2.19.dist-info/licenses/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
22
32
  model_setup/maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
33
  model_setup/maco/base_test.py,sha256=DrVE7vOazeLQpOQeIDwBYK1WtlmdJrRe50JOqP5t4Y0,3198
24
34
  model_setup/maco/cli.py,sha256=nrSukAJAthbstZT3-lQNPz4zOOMcBhvfYQqLh_B5Jdk,9457
25
- model_setup/maco/collector.py,sha256=R3zw-fUJBlwmcSqvkQ-PnoJdHfRm2V0JAOl7N8MTAbY,8240
35
+ model_setup/maco/collector.py,sha256=I0Nidf4-xcvoe6X0bbCsAXjr66iPf00JDO6ocKkaZLc,8309
26
36
  model_setup/maco/exceptions.py,sha256=XBHUrs1kr1ZayPI9B_W-WejKgVmC8sWL_o4RL0b4DQE,745
27
- model_setup/maco/extractor.py,sha256=s36aGcsXSc-9iCik6iihVt5G1a1DZUA7TquvWYQNwdE,2912
28
- model_setup/maco/utils.py,sha256=7Xf-kWCDm1DdpBCGOvecEb_hqKoRgNJi0M_OYsJeSrM,23405
37
+ model_setup/maco/extractor.py,sha256=nqIfUcrc_l57FicKZc6HLtN223-_zkYWL1AYMy1WAmA,3007
38
+ model_setup/maco/utils.py,sha256=yNm5CiHc9033ONX_gFwg9Lng5IYFujLDtw6FfiJkAao,23425
29
39
  model_setup/maco/yara.py,sha256=y141t8NqDDXHY23uE1d6BDPeNmSuUuohR6Yr_LKa7GI,4067
30
40
  model_setup/maco/model/__init__.py,sha256=ULdyHx8R5D2ICHZo3VoCk1YTlewTok36TYIpwx__pNY,45
31
41
  model_setup/maco/model/model.py,sha256=DBHTmZXMzjpVq0s2mzZv3VCzPhwPnv7sH6u_QZCTcA4,24484
32
- pipelines/publish.yaml,sha256=xt3WNU-5kIICJgKIiiE94M3dWjS3uEiun-n4OmIssK8,1471
42
+ pipelines/publish.yaml,sha256=BfsbDsg2ijtXF8lhRUjzkenw3zi2mL7ESNv3KuC1cVE,1626
33
43
  pipelines/test.yaml,sha256=btJVI-R39UBeYosGu7TOpU6V9ogFW3FT3ROtWygQGQ0,1472
34
44
  tests/data/example.txt.cart,sha256=j4ZdDnFNVq7lb-Qi4pY4evOXKQPKG-GSg-n-uEqPhV0,289
35
45
  tests/data/trigger_complex.txt,sha256=uqnLSrnyDGCmXwuPmZ2s8vdhH0hJs8DxvyaW_tuYY24,64
@@ -42,8 +52,8 @@ tests/extractors/bob/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
42
52
  tests/extractors/bob/bob.py,sha256=4fpqy_O6NDinJImghyW5OwYgnaB05aY4kgoIS_C3c_U,253
43
53
  tests/extractors/import_rewriting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
54
  tests/extractors/import_rewriting/importer.py,sha256=wqF1AG2zXXuj9EMt9qlDorab-UD0GYuFggtrCuz4sf0,289735
45
- maco-1.2.17.dist-info/METADATA,sha256=7NtcX0tJ94BxrswwvqTQO9Ou-UVURL5-j0nBOSGoWQY,15224
46
- maco-1.2.17.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
- maco-1.2.17.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
48
- maco-1.2.17.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
49
- maco-1.2.17.dist-info/RECORD,,
55
+ maco-1.2.19.dist-info/METADATA,sha256=bcX2cXg2jbw6epAkczHoP9WOlcRTKcFtutfrVAc3mIg,15310
56
+ maco-1.2.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
57
+ maco-1.2.19.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
58
+ maco-1.2.19.dist-info/top_level.txt,sha256=xiVS11ZoyN8ChHJQGpOzTH4ZyQ3YJe1qT3Yt4gcKGUk,65
59
+ maco-1.2.19.dist-info/RECORD,,
@@ -1,4 +1,5 @@
1
1
  demo_extractors
2
+ extractor_setup
2
3
  maco
3
4
  model_setup
4
5
  pipelines
@@ -122,6 +122,7 @@ class Collector:
122
122
  "author": member.author,
123
123
  "last_modified": member.last_modified,
124
124
  "sharing": member.sharing,
125
+ "result_sharing": member.result_sharing,
125
126
  "description": member.__doc__,
126
127
  },
127
128
  )
@@ -25,7 +25,8 @@ class Extractor:
25
25
  family: Union[str, List[str]] = None # family or families of malware that is detected by the extractor
26
26
  author: str = None # author of the extractor (name@organisation)
27
27
  last_modified: str = None # last modified date (YYYY-MM-DD)
28
- sharing: str = "TLP:WHITE" # who can this be shared with?
28
+ sharing: str = "TLP:CLEAR" # who can this be shared with?
29
+ result_sharing: str = sharing # who can the results be shared with? (defaults to sharing)
29
30
  yara_rule: str = None # yara rule that we filter inputs with
30
31
  reference: str = None # link to malware report or other reference information
31
32
  logger: logging.Logger = None # logger for use when debugging
model_setup/maco/utils.py CHANGED
@@ -280,8 +280,8 @@ def _install_required_packages(create_venv: bool, directories: List[str], python
280
280
 
281
281
  install_command.extend(pyproject_command)
282
282
 
283
- # always require maco to be installed
284
- install_command.append("maco")
283
+ # Always require maco-extractor to be installed
284
+ install_command.append("maco-extractor")
285
285
  logger.debug(f"Install command: {' '.join(install_command)} [{dir}]")
286
286
  # this uses VIRTUAL_ENV to control usage of a virtual environment
287
287
  p = subprocess.run(
pipelines/publish.yaml CHANGED
@@ -64,6 +64,13 @@ jobs:
64
64
  ls ../dist
65
65
  displayName: Build (Model Only)
66
66
 
67
+ - script: |
68
+ set -x
69
+ cd extractor_setup
70
+ python -m build --outdir ../dist
71
+ ls ../dist
72
+ displayName: Build (Extractor Essentials)
73
+
67
74
  - script: |
68
75
  set -xv # Echo commands before they are run
69
76
  sudo env "PATH=$PATH" python -m pip install --no-cache-dir twine
File without changes