Skip to content

Commit 36af8a9

Browse files
authored
Merge pull request #67 from carbonblack/develop
Release v1.1.0
2 parents 0d900e2 + 58eb0c2 commit 36af8a9

19 files changed

+287
-284
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2019 Carbon Black
3+
Copyright (c) 2020 Carbon Black
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
[![Coverage Status](https://coveralls.io/repos/github/carbonblack/cbc-binary-toolkit/badge.svg?branch=develop)](https://coveralls.io/github/carbonblack/cbc-binary-toolkit?branch=develop)
33
# Carbon Black Cloud Binary Toolkit
44

5-
**Latest Version:** 1.0.0
5+
**Latest Version:** 1.1.0
66
<br>
7-
**Release Date:** 06/30/2020
7+
**Release Date:** 11/20/2020
88

99
The Carbon Black Cloud Binary Toolkit provides a system of processing incoming SHA256 hashes by integrating with the Unified Binary Store (UBS) on the Carbon Black Cloud (CBC).
1010

@@ -26,7 +26,7 @@ Use of the Carbon Black API is governed by the license found in [LICENSE](LICENS
2626

2727
## Requirements
2828

29-
The Carbon Black Cloud Binary Toolkit is design to work on Python 3.6 and above.
29+
The Carbon Black Cloud Binary Toolkit is designed to work on Python 3.6 and above.
3030

3131
All requirements are installed as part of `pip install cbc-binary-toolkit` or if you're planning on pushing changes to the Carbon Black Cloud Binary Toolkit, the following can be used after cloning the repo `pip install -r requirements.txt`
3232

@@ -48,7 +48,7 @@ OpenSUSE/SUSE | `zypper install python3-devel`
4848

4949
### Python Packages
5050
* argparse
51-
* cbapi
51+
* carbon-black-cloud-sdk
5252
* python-dateutil
5353
* pyyaml
5454
* requests

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0
1+
1.1.0

env.encrypted

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
codeship:v2
2-
kRPdF6MGTXFNXnwojAVVvbtNZpYRFC+3Q6IzrLEBsJQfipQQSOlLcvisv61Ai118QXo8Z5A4AggZLUlWsXS2wWNtpmQ5+volm+RBlt6ov7LLQTLLfe+CXP5av6CG1uEexozw9QnbDw==
2+
G3bfaQluHoG25wGmaLA5W7B8j0eIf7ALa9LPIAspND4T4kpoFCs7QUUjXyzAkelIhd9ENpM/4HmhcLOu3x752pyIGwzWgnqBnm0fjXo3yfyQwq3a9mrf1rt9RGRO74MlDlXKj76srg==

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Package dependencies
2-
cbapi
2+
carbon-black-cloud-sdk
33
python-dateutil
44
pyyaml
55
requests

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def read(fname):
1111

1212

1313
install_reqs = [
14-
"cbapi",
14+
"carbon-black-cloud-sdk",
1515
"python-dateutil",
1616
"pyyaml",
1717
"requests",

src/cbc_binary_toolkit/engine_results.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
from schema import SchemaError
2626
from .schemas import EngineResponseSchema, IOCv2SEVSchema
27-
from cbapi.psc.threathunter import Report
28-
from cbapi.errors import ObjectNotFoundError
27+
from cbc_sdk.enterprise_edr import Report
28+
from cbc_sdk.errors import ObjectNotFoundError
2929

3030
log = logging.getLogger(__name__)
3131

@@ -37,7 +37,7 @@ class EngineResults:
3737
Require Properties:
3838
engine_name (str): The name of the engine analysis is coming from
3939
state_manager (cbc_binary_toolkit.state.manager): State management component
40-
cbth (CbThreatHunterAPI): CBAPI ThreatHunter API to push reports to Carbon Black Cloud
40+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API to push reports to Carbon Black Cloud
4141
4242
Description:
4343
Validates an EngineResponse
@@ -52,7 +52,7 @@ class EngineResults:
5252
Args:
5353
engine_name (str): The name of the engine analysis is coming from.
5454
state_manager (cbc_binary_toolkit.state.builtin.SQLiteBasedPersistor): State management object.
55-
cbth (cbapi.CbThreatHunterAPI): CBAPI ThreatHunter API to push reports to Carbon Black Cloud.
55+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API to push reports to Carbon Black Cloud.
5656
5757
Attributes:
5858
SEVERITY_RANGE (int): Highest severity value expected from Analysis Engine for an IOC.
@@ -62,11 +62,11 @@ class EngineResults:
6262

6363
SEVERITY_RANGE = 10
6464

65-
def __init__(self, engine_name, state_manager, cbth):
65+
def __init__(self, engine_name, state_manager, cbc_api):
6666
"""Engine Results Handler Constructor"""
6767
self.engine_name = engine_name
6868
self.state_manager = state_manager
69-
self.cbth = cbth
69+
self.cbc_api = cbc_api
7070
# Create range of report levels
7171
self.iocs = list(list() for i in range(self.SEVERITY_RANGE))
7272

@@ -219,7 +219,7 @@ def _send_reports(self, feed_id):
219219
"iocs_v2": self.iocs[sev]
220220
}
221221

222-
report = Report(self.cbth, initial_data=report_meta, feed_id=feed_id)
222+
report = Report(self.cbc_api, initial_data=report_meta, feed_id=feed_id)
223223
report.update()
224224
log.info(f"Report ({report_meta['title']}) sent to feed {feed_id}")
225225
# Clear report items from the database

src/cbc_binary_toolkit/ingestion_component.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class IngestionComponent:
3232
3333
Args:
3434
config (Config): Config object.
35-
cb_threat_hunter (cbapi.CbThreatHunterAPI): Carbon Black ThreatHunter API object.
35+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
3636
state_manager (cbc_binary_toolkit.state.builtin.SQLiteBasedPersistor): State management object.
3737
3838
Attributes:
@@ -42,10 +42,10 @@ class IngestionComponent:
4242
"""
4343
DEFAULT_EXPIRATION = 3600
4444

45-
def __init__(self, config, cb_threat_hunter, state_manager):
45+
def __init__(self, config, cbc_api, state_manager):
4646
"""Constructor"""
4747
self.config = config
48-
self.cb_threat_hunter = cb_threat_hunter
48+
self.cbc_api = cbc_api
4949
self.state_manager = state_manager
5050

5151
def reload(self):
@@ -107,7 +107,7 @@ def fetch_metadata(self, hashes):
107107
hashes_copy = copy.deepcopy(hashes)
108108
# Fetch download url from UBS
109109
while hashes_copy != []:
110-
found.extend(download_hashes(self.cb_threat_hunter,
110+
found.extend(download_hashes(self.cbc_api,
111111
hashes_copy[:100],
112112
self.config.get("carbonblackcloud.expiration_seconds",
113113
self.DEFAULT_EXPIRATION)))
@@ -118,7 +118,7 @@ def fetch_metadata(self, hashes):
118118

119119
# Fetch metadata from UBS
120120
for download_data in found:
121-
metadata = get_metadata(self.cb_threat_hunter, download_data)
121+
metadata = get_metadata(self.cbc_api, download_data)
122122

123123
# Save hash entry to state manager
124124
if metadata:

src/cbc_binary_toolkit/ubs.py

+25-25
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
"""Functions to retrieve binaries from Unified Binary Store"""
1515

16-
from cbapi.psc.threathunter.models import Binary, Downloads
16+
from cbc_sdk.enterprise_edr import Binary, Downloads
1717
import logging
1818
import copy
1919

@@ -25,7 +25,7 @@ class RedownloadHashes:
2525
Values and function to redownload any hashes that experienced an error during the initial download attempt.
2626
2727
Args:
28-
cbth (cbapi.CbThreatHunterAPI): Carbon Black ThreatHunter object.
28+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
2929
shas (List[str]): hashes to be redownloaded.
3030
expiration_seconds (int): Desired timeout for AWS links to binaries.
3131
@@ -40,9 +40,9 @@ class RedownloadHashes:
4040

4141
RETRY_LIMIT = 5
4242

43-
def __init__(self, cbth, shas, expiration_seconds):
43+
def __init__(self, cbc_api, shas, expiration_seconds):
4444
"""Redownload Hashes constructor"""
45-
self.cb = cbth
45+
self.cbc_api = cbc_api
4646
self.shas = shas
4747
self.expiration_seconds = expiration_seconds
4848
self.found = []
@@ -55,8 +55,8 @@ def redownload(self):
5555
"sha256": self.shas,
5656
"expiration_seconds": self.expiration_seconds,
5757
}
58-
url = self.urlobject.format(self.cb.credentials.org_key)
59-
download = self.cb.post_object(url, body).json()
58+
url = self.urlobject.format(self.cbc_api.credentials.org_key)
59+
download = self.cbc_api.post_object(url, body).json()
6060
self.attempt_num += 1
6161
# save any hashes found on the first retry
6262
if download["found"]:
@@ -67,7 +67,7 @@ def redownload(self):
6767

6868
while download["error"] and self.attempt_num < self.RETRY_LIMIT:
6969
body["sha256"] = copy.deepcopy(download["error"])
70-
download = self.cb.post_object(url, body).json()
70+
download = self.cbc_api.post_object(url, body).json()
7171

7272
if download["found"]:
7373
self.found.extend(copy.deepcopy(download["found"]))
@@ -85,12 +85,12 @@ def redownload(self):
8585
f"the Unified Binary Store: {self.not_found}")
8686

8787

88-
def _download_hashes(cbth, hashes, expiration_seconds):
88+
def _download_hashes(cbc_api, hashes, expiration_seconds):
8989
"""
9090
Download hashes from Unified Binary Store.
9191
9292
Args:
93-
cbth (cbapi.CbThreatHunterAPI): Carbon Black ThreatHunter object.
93+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
9494
hashes (List[str]): hashes to be downloaded from Unified Binary Store.
9595
expiration_seconds (int): Desired timeout for AWS links to binaries.
9696
@@ -101,19 +101,19 @@ def _download_hashes(cbth, hashes, expiration_seconds):
101101
"""
102102
try:
103103
log.debug("Downloading hashes from Unified Binary Store")
104-
downloads = Downloads(cbth, hashes, expiration_seconds)
104+
downloads = Downloads(cbc_api, hashes, expiration_seconds)
105105
return downloads
106106
except Exception as err:
107107
log.error(f"Error downloading hashes from Unified Binary Store: {err}")
108108
return None
109109

110110

111-
def _download_binary_metadata(cbth, found_binary):
111+
def _download_binary_metadata(cbc_api, found_binary):
112112
"""
113113
Retrieve metadata for a binary found in the Unified Binary Store.
114114
115115
Args:
116-
cbth (cbapi.CbThreatHunterAPI): Carbon BlackThreatHunter object.
116+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
117117
found_binary (Dict): Dictionary with "sha256" and "url" values.
118118
119119
Returns:
@@ -125,7 +125,7 @@ def _download_binary_metadata(cbth, found_binary):
125125
try:
126126
log.debug("Downloading metadata information")
127127
binary_metadata = {"url": found_binary["url"]}
128-
th_binary = cbth.select(Binary, found_binary["sha256"])
128+
th_binary = cbc_api.select(Binary, found_binary["sha256"])
129129
if isinstance(th_binary, Binary):
130130
binary_metadata.update(th_binary._info)
131131
return binary_metadata
@@ -137,13 +137,13 @@ def _download_binary_metadata(cbth, found_binary):
137137
return {}
138138

139139

140-
def _validate_download(cbth, download, expiration_seconds):
140+
def _validate_download(cbc_api, download, expiration_seconds):
141141
"""
142142
Verifies the presence of Downloads.FoundItem. Retries downloading if there are errors during download.
143143
144144
Args:
145-
cbth (CbThreatHunterAPI): Carbon BlackThreatHunter object.
146-
download (ThreatHunter.Downloads): May contain found, not_found, and error attributes.
145+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
146+
download (cbc_sdk.enterprise_edr.Downloads): May contain found, not_found, and error attributes.
147147
expiration_seconds (int): Desired timeout for AWS links to binaries.
148148
149149
Returns:
@@ -167,7 +167,7 @@ def _validate_download(cbth, download, expiration_seconds):
167167
log.warning(f"{len(download.error)} hashes experienced an error while"
168168
f" downloading: {download.error}. Retrying download.")
169169

170-
redownload = RedownloadHashes(cbth, [download.error], expiration_seconds)
170+
redownload = RedownloadHashes(cbc_api, [download.error], expiration_seconds)
171171

172172
redownload.redownload()
173173

@@ -176,12 +176,12 @@ def _validate_download(cbth, download, expiration_seconds):
176176
return download_found, redownload
177177

178178

179-
def download_hashes(cbth, hashes, expiration_seconds=3600):
179+
def download_hashes(cbc_api, hashes, expiration_seconds=3600):
180180
"""
181181
Initiates download of hashes
182182
183183
Args:
184-
cbth (cbapi.CbThreatHunterAPI): Carbon BlackThreatHunter object.
184+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
185185
hashes (List[str]): hashes to be downloaded from Unified Binary Store.
186186
expiration_seconds (int, optional): Desired timeout for AWS links to binaries.
187187
@@ -190,15 +190,15 @@ def download_hashes(cbth, hashes, expiration_seconds=3600):
190190
Empty list if an error occurred during download.
191191
192192
Examples:
193-
>>> download_hashes(cbth, ["0995f71c34f613207bc39ed4fcc1bbbee396a543fa1739656f7ddf70419309fc"])
193+
>>> download_hashes(cbc_api, ["0995f71c34f613207bc39ed4fcc1bbbee396a543fa1739656f7ddf70419309fc"])
194194
195195
"""
196196
if not hashes:
197197
log.error("No hashes supplied to download_hashes.")
198198
return list()
199-
download = _download_hashes(cbth, hashes, expiration_seconds)
199+
download = _download_hashes(cbc_api, hashes, expiration_seconds)
200200

201-
checked_download, retried_download = _validate_download(cbth, download, expiration_seconds)
201+
checked_download, retried_download = _validate_download(cbc_api, download, expiration_seconds)
202202

203203
if not checked_download:
204204
log.error("Unable to retrieve binaries from the Unified Binary Store.")
@@ -213,12 +213,12 @@ def download_hashes(cbth, hashes, expiration_seconds=3600):
213213
return found_hashes
214214

215215

216-
def get_metadata(cbth, binary):
216+
def get_metadata(cbc_api, binary):
217217
"""
218218
Initiates download of binary metadata from Unified Binary Store.
219219
220220
Args:
221-
cbth (cbapi.CbThreatHunterAPI): Carbon Black ThreatHunter object.
221+
cbc_api (cbc_sdk.CBCloudAPI): Carbon Black Cloud API object.
222222
binary (Dict): Dictionary with "sha256" and "url" values.
223223
224224
Returns:
@@ -230,7 +230,7 @@ def get_metadata(cbth, binary):
230230
return {}
231231
else:
232232
try:
233-
return _download_binary_metadata(cbth, binary)
233+
return _download_binary_metadata(cbc_api, binary)
234234
except Exception as err:
235235
log.error(f"Failed to download metadata: {err}")
236236
return {}

src/cbc_binary_toolkit_examples/tools/analysis_util.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from cbc_binary_toolkit.engine import LocalEngineManager
3434
from cbc_binary_toolkit.state import StateManager
3535

36-
from cbapi import CbThreatHunterAPI
36+
from cbc_sdk import CBCloudAPI
3737

3838
DEFAULT_LOG_LEVEL = "INFO"
3939

@@ -54,7 +54,7 @@ def __init__(self, default_install):
5454
"""Constructor for the analysis utility class"""
5555
self.default_install = default_install
5656
self.config = None
57-
self.cbapi = None
57+
self.cbc_api = None
5858

5959
# Create argument parser
6060
self._parser = argparse.ArgumentParser()
@@ -98,17 +98,17 @@ def _init_components(self):
9898
log.debug(traceback.format_exc())
9999
state_manager = None
100100

101-
cbth = self.cbapi
102-
if cbth is None:
103-
cbth = CbThreatHunterAPI(url=self.config.get("carbonblackcloud.url"),
104-
org_key=self.config.get("carbonblackcloud.org_key"),
105-
token=self.config.get("carbonblackcloud.api_token"),
106-
ssl_verify=self.config.get("carbonblackcloud.ssl_verify"))
101+
cbc_api = self.cbc_api
102+
if cbc_api is None:
103+
cbc_api = CBCloudAPI(url=self.config.get("carbonblackcloud.url"),
104+
org_key=self.config.get("carbonblackcloud.org_key"),
105+
token=self.config.get("carbonblackcloud.api_token"),
106+
ssl_verify=self.config.get("carbonblackcloud.ssl_verify"))
107107

108108
deduplicate = DeduplicationComponent(self.config, state_manager)
109-
ingest = IngestionComponent(self.config, cbth, state_manager)
109+
ingest = IngestionComponent(self.config, cbc_api, state_manager)
110110

111-
results_engine = EngineResults(self.config.get("engine.name"), state_manager, cbth)
111+
results_engine = EngineResults(self.config.get("engine.name"), state_manager, cbc_api)
112112
if self.config.get("engine.type") == "local":
113113
try:
114114
engine_manager = LocalEngineManager(self.config)

0 commit comments

Comments
 (0)