assemblyline-v4-service 4.4.0.24__py3-none-any.whl → 4.4.0.26__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.

Potentially problematic release.


This version of assemblyline-v4-service might be problematic. Click here for more details.

Files changed (42) hide show
  1. assemblyline_v4_service/VERSION +1 -1
  2. assemblyline_v4_service/common/api.py +3 -2
  3. assemblyline_v4_service/common/base.py +3 -4
  4. assemblyline_v4_service/common/helper.py +1 -2
  5. assemblyline_v4_service/common/{extractor/ocr.py → ocr.py} +0 -1
  6. assemblyline_v4_service/common/ontology_helper.py +7 -8
  7. assemblyline_v4_service/common/request.py +4 -5
  8. assemblyline_v4_service/common/result.py +3 -3
  9. assemblyline_v4_service/common/task.py +3 -3
  10. assemblyline_v4_service/common/utils.py +2 -2
  11. assemblyline_v4_service/updater/helper.py +4 -0
  12. {assemblyline_v4_service-4.4.0.24.dist-info → assemblyline_v4_service-4.4.0.26.dist-info}/METADATA +1 -1
  13. assemblyline_v4_service-4.4.0.26.dist-info/RECORD +28 -0
  14. assemblyline_v4_service/common/balbuzard/__init__.py +0 -0
  15. assemblyline_v4_service/common/balbuzard/balbuzard.py +0 -656
  16. assemblyline_v4_service/common/balbuzard/bbcrack.py +0 -830
  17. assemblyline_v4_service/common/balbuzard/patterns.py +0 -650
  18. assemblyline_v4_service/common/dynamic_service_helper.py +0 -3631
  19. assemblyline_v4_service/common/extractor/__init__.py +0 -1
  20. assemblyline_v4_service/common/extractor/base64.py +0 -86
  21. assemblyline_v4_service/common/extractor/pe_file.py +0 -51
  22. assemblyline_v4_service/common/icap.py +0 -149
  23. assemblyline_v4_service/common/keytool_parse.py +0 -66
  24. assemblyline_v4_service/common/pestudio/__init__.py +0 -0
  25. assemblyline_v4_service/common/pestudio/xml/__init__.py +0 -0
  26. assemblyline_v4_service/common/pestudio/xml/features.xml +0 -5607
  27. assemblyline_v4_service/common/pestudio/xml/functions.xml +0 -5824
  28. assemblyline_v4_service/common/pestudio/xml/languages.xml +0 -375
  29. assemblyline_v4_service/common/pestudio/xml/resources.xml +0 -511
  30. assemblyline_v4_service/common/pestudio/xml/signatures.xml +0 -29105
  31. assemblyline_v4_service/common/pestudio/xml/strings.xml +0 -2379
  32. assemblyline_v4_service/common/safelist_helper.py +0 -73
  33. assemblyline_v4_service/common/section_reducer.py +0 -43
  34. assemblyline_v4_service/common/tag_helper.py +0 -117
  35. assemblyline_v4_service/common/tag_reducer.py +0 -242
  36. assemblyline_v4_service/testing/__init__.py +0 -0
  37. assemblyline_v4_service/testing/helper.py +0 -463
  38. assemblyline_v4_service/testing/regenerate_results.py +0 -37
  39. assemblyline_v4_service-4.4.0.24.dist-info/RECORD +0 -53
  40. {assemblyline_v4_service-4.4.0.24.dist-info → assemblyline_v4_service-4.4.0.26.dist-info}/LICENCE.md +0 -0
  41. {assemblyline_v4_service-4.4.0.24.dist-info → assemblyline_v4_service-4.4.0.26.dist-info}/WHEEL +0 -0
  42. {assemblyline_v4_service-4.4.0.24.dist-info → assemblyline_v4_service-4.4.0.26.dist-info}/top_level.txt +0 -0
@@ -1,86 +0,0 @@
1
- """
2
- Base 64 encoded text
3
- """
4
-
5
- import binascii
6
- import regex as re
7
- import warnings
8
-
9
- from typing import Dict, List, Tuple
10
-
11
- HTML_ESCAPE_RE = rb'&#(?:x[a-fA-F0-9]{1,4}|\d{1,4});'
12
- BASE64_RE = rb'(?:[A-Za-z0-9+/]{4,}(?:<\x00 \x00)?(?:&#13;|&#xD;)?(?:&#10;|&#xA)?\r?\n?){5,}' \
13
- rb'[A-Za-z0-9+/]{2,}={0,2}'
14
-
15
- CAMEL_RE = rb'(?i)[a-z]+'
16
- HEX_RE = rb'(?i)[a-f0-9]+'
17
- MIN_B64_CHARS = 6
18
-
19
-
20
- def base64_search(text: bytes) -> Dict[bytes, bytes]:
21
- """
22
- Find all base64 encoded sections in a text.
23
- Args:
24
- text: The text to search.
25
- Returns:
26
- A dictionary with the original base64 encoded sections as keys
27
- and the corresponding decoded data as values.
28
- """
29
- warnings.warn("base64_search is depricated, use find_base64 instead", DeprecationWarning)
30
- b64_matches = {}
31
- for b64_match in re.findall(BASE64_RE, text):
32
- if b64_match in b64_matches:
33
- continue
34
- b64_string = re.sub(HTML_ESCAPE_RE, b'', b64_match).replace(b'\n', b'').replace(b'\r', b'') \
35
- .replace(b'<\x00 \x00', b'')
36
- if re.fullmatch(HEX_RE, b64_string):
37
- # Hexadecimal characters are a subset of base64
38
- # Hashes commonly are hex and have multiple of 4 lengths
39
- continue
40
- if re.fullmatch(CAMEL_RE, b64_string):
41
- # Camel case text can be confused for base64
42
- # It is common in scripts as names
43
- continue
44
- uniq_char = set(b64_string)
45
- if len(uniq_char) > MIN_B64_CHARS and len(b64_string) % 4 == 0:
46
- try:
47
- b64_result = binascii.a2b_base64(b64_string)
48
- b64_matches[b64_match] = b64_result
49
- except binascii.Error:
50
- pass
51
- return b64_matches
52
-
53
-
54
- def find_base64(data: bytes) -> List[Tuple[bytes, int, int]]:
55
- """
56
- Find all base64 encoded sections in some data.
57
-
58
- Args:
59
- data: The data to search.
60
- Returns:
61
- A list of decoded base64 sections and the location indexes of the section
62
- in the original data.
63
- """
64
- b64_matches = []
65
- for b64_match in re.finditer(BASE64_RE, data):
66
- b64_string = re.sub(HTML_ESCAPE_RE, b'', b64_match.group()).replace(b'\n', b'').replace(b'\r', b'') \
67
- .replace(b'<\x00 \x00', b'')
68
- if len(b64_string) % 4 != 0 or len(set(b64_string)) <= MIN_B64_CHARS:
69
- continue
70
- if re.fullmatch(HEX_RE, b64_string):
71
- # Hexadecimal characters are a subset of base64
72
- # Hashes commonly are hex and have multiple of 4 lengths
73
- continue
74
- if re.fullmatch(CAMEL_RE, b64_string):
75
- # Camel case text can be confused for base64
76
- # It is common in scripts as names
77
- continue
78
- if b64_string.count(b'/')/len(b64_string) > 3/32:
79
- # If there are a lot of / it as more likely a path
80
- continue
81
- try:
82
- b64_result = binascii.a2b_base64(b64_string)
83
- b64_matches.append((b64_result, b64_match.start(), b64_match.end()))
84
- except binascii.Error:
85
- pass
86
- return b64_matches
@@ -1,51 +0,0 @@
1
- import regex as re
2
-
3
- from typing import List, Tuple
4
-
5
- import pefile
6
-
7
- EXEDOS_RE = rb'(?s)This program cannot be run in DOS mode'
8
- EXEHEADER_RE = rb'(?s)MZ.{32,1024}PE\000\000'
9
-
10
-
11
- def _find_pe_files_with_offset(data: bytes) -> List[Tuple[bytes, int, int]]:
12
- """
13
- Searches for any PE files within data
14
-
15
- Args:
16
- data: The data to search
17
- Returns:
18
- A list tuples containing: The found PE file, the starting offset and the end offset
19
- """
20
- pe_files: List[Tuple[bytes, int, int]] = []
21
- offset = 0
22
- while offset < len(data):
23
- match = re.search(EXEHEADER_RE, data)
24
- if not match:
25
- return pe_files
26
- pe_data = data[offset:]
27
- if not re.search(EXEDOS_RE, pe_data):
28
- return pe_files
29
- try:
30
- pe = pefile.PE(data=pe_data)
31
- size = max(section.PointerToRawData + section.SizeOfRawData for section in pe.sections)
32
- if size == 0:
33
- return pe_files
34
- end = offset+size
35
- pe_files.append((data[offset:end], offset, end))
36
- offset = end
37
- except Exception:
38
- return pe_files
39
- return pe_files
40
-
41
-
42
- def find_pe_files(data: bytes) -> List[bytes]:
43
- """
44
- Searches for any PE files within data
45
-
46
- Args:
47
- data: The data to search
48
- Returns:
49
- A list of found PE files
50
- """
51
- return [pe[0] for pe in _find_pe_files_with_offset(data)]
@@ -1,149 +0,0 @@
1
- import os
2
- import socket
3
-
4
- from assemblyline.common.str_utils import safe_str
5
-
6
- ICAP_OK = b'ICAP/1.0 200 OK'
7
-
8
-
9
- # noinspection PyBroadException
10
- class IcapClient(object):
11
- """
12
- A limited Internet Content Adaptation Protocol client.
13
-
14
- Currently only supports RESPMOD as that is all that is required to interop
15
- with most ICAP based AV servers.
16
- """
17
-
18
- RESP_CHUNK_SIZE = 65565
19
- MAX_RETRY = 3
20
-
21
- def __init__(self, host, port, respmod_service="av/respmod", action="", timeout=30, number_of_retries=MAX_RETRY):
22
- self.host = host
23
- self.port = port
24
- self.service = respmod_service
25
- self.action = action
26
- self.socket = None
27
- self.timeout = timeout
28
- self.kill = False
29
- self.number_of_retries = number_of_retries
30
- self.successful_connection = False
31
-
32
- def scan_data(self, data, name=None):
33
- return self._do_respmod(name or 'filetoscan', data)
34
-
35
- def scan_local_file(self, filepath):
36
- filename = os.path.basename(filepath)
37
- with open(filepath, 'r') as f:
38
- data = f.read()
39
- return self.scan_data(data, filename)
40
-
41
- def options_respmod(self):
42
- request = f"OPTIONS icap://{self.host}:{self.port}/{self.service} ICAP/1.0\r\n\r\n"
43
-
44
- for i in range(self.number_of_retries):
45
- if self.kill:
46
- self.kill = False
47
- return
48
- try:
49
- if not self.socket:
50
- self.socket = socket.create_connection((self.host, self.port), timeout=self.timeout)
51
- self.successful_connection = True
52
- self.socket.sendall(request.encode())
53
- response = temp_resp = self.socket.recv(self.RESP_CHUNK_SIZE)
54
- while len(temp_resp) == self.RESP_CHUNK_SIZE:
55
- temp_resp = self.socket.recv(self.RESP_CHUNK_SIZE)
56
- response += temp_resp
57
- if not response or not response.startswith(ICAP_OK):
58
- raise Exception(f"Unexpected OPTIONS response: {response}")
59
- return response.decode()
60
- except Exception:
61
- self.successful_connection = False
62
- try:
63
- self.socket.close()
64
- except Exception:
65
- pass
66
- self.socket = None
67
- if i == (self.number_of_retries-1):
68
- raise
69
-
70
- raise Exception("Icap server refused to respond.")
71
-
72
- @staticmethod
73
- def chunk_encode(data):
74
- chunk_size = 8160
75
- out = b""
76
- offset = 0
77
- while len(data) < offset * chunk_size:
78
- out += "1FEO\r\n"
79
- out += data[offset * chunk_size:(offset + 1) * chunk_size]
80
- out += "\r\n"
81
- offset += 1
82
-
83
- out += b"%X\r\n" % len(data[offset * chunk_size:])
84
- out += data[offset * chunk_size:]
85
- out += b"\r\n0\r\n\r\n"
86
-
87
- return out
88
-
89
- def _do_respmod(self, filename, data):
90
- encoded = self.chunk_encode(data)
91
-
92
- # ICAP RESPMOD req-hdr is the start of the original HTTP request.
93
- respmod_req_hdr = "GET /{FILENAME} HTTP/1.1\r\n\r\n".format(FILENAME=safe_str(filename))
94
-
95
- # ICAP RESPMOD res-hdr is the start of the HTTP response for above request.
96
- respmod_res_hdr = (
97
- "HTTP/1.1 200 OK\r\n"
98
- "Transfer-Encoding: chunked\r\n\r\n")
99
-
100
- res_hdr_offset = len(respmod_req_hdr)
101
- res_bdy_offset = len(respmod_res_hdr) + res_hdr_offset
102
-
103
- # The ICAP RESPMOD header. Note:
104
- # res-hdr offset should match the start of the GET request above.
105
- # res-body offset should match the start of the response above.
106
-
107
- respmod_icap_hdr = (
108
- f"RESPMOD icap://{self.host}:{self.port}/{self.service}{self.action} ICAP/1.0\r\n"
109
- f"Host: {self.host}:{self.port}\r\n"
110
- "Allow: 204\r\n"
111
- f"Encapsulated: req-hdr=0, res-hdr={res_hdr_offset}, res-body={res_bdy_offset}\r\n\r\n"
112
- )
113
-
114
- serialized_request = b"%s%s%s%s" % (respmod_icap_hdr.encode(), respmod_req_hdr.encode(),
115
- respmod_res_hdr.encode(), encoded)
116
-
117
- for i in range(self.number_of_retries):
118
- if self.kill:
119
- self.kill = False
120
- return
121
- try:
122
- if not self.socket:
123
- self.socket = socket.create_connection((self.host, self.port), timeout=self.timeout)
124
- self.successful_connection = True
125
- self.socket.sendall(serialized_request)
126
- response = temp_resp = self.socket.recv(self.RESP_CHUNK_SIZE)
127
- while len(temp_resp) == self.RESP_CHUNK_SIZE:
128
- temp_resp = self.socket.recv(self.RESP_CHUNK_SIZE)
129
- response += temp_resp
130
-
131
- return response.decode()
132
- except Exception:
133
- self.successful_connection = False
134
- try:
135
- self.socket.close()
136
- except Exception:
137
- pass
138
- self.socket = None
139
- if i == (self.number_of_retries-1):
140
- raise
141
-
142
- raise Exception("Icap server refused to respond.")
143
-
144
- def close(self):
145
- self.kill = True
146
- try:
147
- self.socket.close()
148
- except Exception:
149
- pass
@@ -1,66 +0,0 @@
1
- from re import split
2
- from subprocess import Popen, PIPE
3
- from assemblyline.common.str_utils import safe_str
4
- from typing import List
5
-
6
-
7
- class Certificate():
8
- def __init__(self):
9
- self.raw = ""
10
- self.issuer = ""
11
- self.owner = ""
12
- self.country = ""
13
- self.valid_from = ""
14
- self.valid_to = ""
15
-
16
-
17
- def keytool_printcert(cert_path: str) -> None:
18
- """
19
- This function runs the 'keytool -printcert' command against a provided file
20
-
21
- :param cert_path: A path to a certificate
22
- :return: the string output of 'keytool -printcert' or None
23
- """
24
- stdout, _ = Popen(["keytool", "-printcert", "-file", cert_path],
25
- stderr=PIPE, stdout=PIPE).communicate()
26
- stdout = safe_str(stdout)
27
-
28
- if stdout and "keytool error" not in stdout:
29
- return stdout
30
-
31
- return None
32
-
33
-
34
- def certificate_chain_from_printcert(printcert: str) -> List[Certificate]:
35
- """
36
- This function parses the output of 'keytool -printcert' and creates a list of Certificate objects.
37
- The input to this function is the output of keytool_printcert
38
-
39
- :param printcert: the string output of 'keytool -printcert'
40
- :return: a list of the parsed out certificates. If only one certificate
41
- is present and not a chain, then the list will have one element.
42
- """
43
- certs: List[Certificate] = []
44
-
45
- for cert_str in split(r'Certificate\[\d+\]:', printcert): # split printcert output in case of certificate chain
46
- if cert_str == '':
47
- continue
48
- cert = Certificate()
49
- cert.raw = cert_str.strip()
50
- for line in cert_str.splitlines():
51
- if "Owner:" in line:
52
- cert.owner = line.split(": ", 1)[1]
53
- country = cert.owner.split("C=")
54
- if len(country) != 1:
55
- cert.country = country[1]
56
-
57
- elif "Issuer:" in line:
58
- cert.issuer = line.split(": ", 1)[1]
59
-
60
- elif "Valid from:" in line:
61
- cert.valid_from = line.split(": ", 1)[1].split(" until:")[0]
62
- cert.valid_to = line.rsplit(": ", 1)[1]
63
-
64
- certs.append(cert)
65
-
66
- return certs
File without changes
File without changes