Skip to content

Commit 4f14b46

Browse files
authored
Merge pull request carbonblack#179 from carbonblack/import-cb-response-feeds
Add example script to import CB Response feeds into CB Threat Hunter
2 parents 676cf2a + 6b46a77 commit 4f14b46

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#!/usr/bin/env python
2+
#
3+
import sys
4+
from cbapi.psc.threathunter import CbThreatHunterAPI
5+
from cbapi.psc.threathunter.models import Feed as FeedTH
6+
from cbapi.response.models import Feed, ThreatReport
7+
from cbapi.example_helpers import build_cli_parser, get_cb_response_object, get_object_by_name_or_id
8+
from cbapi.errors import ServerError
9+
from urllib.parse import unquote
10+
import logging
11+
12+
log = logging.getLogger(__name__)
13+
14+
"""
15+
Lists the feeds in CB Response
16+
"""
17+
def list_feeds(cb, parser, args):
18+
for f in cb.select(Feed):
19+
for fieldname in ["id", "category", "display_name", "enabled", "provider_url", "summary", "tech_data",
20+
"feed_url", "use_proxy", "validate_server_cert"]:
21+
print("%-20s: %s" % (fieldname, getattr(f, fieldname, "")))
22+
23+
if f.username:
24+
for fieldname in ["username", "password"]:
25+
print("%-20s: %s" % (fieldname, getattr(f, fieldname, "")))
26+
27+
if f.ssl_client_crt:
28+
for fieldname in ["ssl_client_crt", "ssl_client_key"]:
29+
print("%-20s: %s" % (fieldname, getattr(f, fieldname, "")))
30+
31+
print("\n")
32+
33+
"""
34+
Lists the reports in a feed from CB Response
35+
:param: id - The ID of a feed
36+
"""
37+
def list_reports(cb, parser, args):
38+
feed = cb.select(Feed, args.id, force_init=True)
39+
for report in feed.reports:
40+
print (report)
41+
print("\n")
42+
43+
"""
44+
Converts and copies a feed from CB Response to CB Threat Hunter
45+
:param: id - The ID of a feed from CB Response
46+
47+
Requires a credentials profile for both CB Response and CB Threat Hunter
48+
Ensure that your credentials for CB Threat Hunter have permissions to the Feed Manager APIs
49+
"""
50+
def convert_feed(cb, cb_th, parser, args):
51+
th_feed = { "feedinfo": {}, "reports": []}
52+
# Fetches the CB Response feed
53+
feed = cb.select(Feed, args.id, force_init=True)
54+
55+
th_feed["feedinfo"]["name"] = feed.name
56+
th_feed["feedinfo"]["provider_url"] = feed.provider_url
57+
th_feed["feedinfo"]["summary"] = feed.summary
58+
th_feed["feedinfo"]["category"] = feed.category
59+
th_feed["feedinfo"]["access"] = "private"
60+
61+
# Temporary values until refresh
62+
th_feed["feedinfo"]["owner"] = "org_key"
63+
th_feed["feedinfo"]["id"] = "id"
64+
65+
# Iterates the reports in the CB Response feed
66+
for report in feed.reports:
67+
th_report = {}
68+
th_report["id"] = report.id
69+
th_report["timestamp"] = report.timestamp
70+
th_report["title"] = report.title
71+
th_report["severity"] = (report.score % 10) + 1
72+
if hasattr(report, "description"):
73+
th_report["description"] = report.description
74+
else:
75+
th_report["description"] = ""
76+
if hasattr(report, "link"):
77+
th_report["link"] = report.link
78+
th_report["iocs"] = {}
79+
if report.iocs:
80+
if "md5" in report.iocs:
81+
th_report["iocs"]["md5"] = report.iocs["md5"]
82+
if "ipv4" in report.iocs:
83+
th_report["iocs"]["ipv4"] = report.iocs["ipv4"]
84+
if "ipv6" in report.iocs:
85+
th_report["iocs"]["ipv6"] = report.iocs["ipv6"]
86+
if "dns" in report.iocs:
87+
th_report["iocs"]["dns"] = report.iocs["dns"]
88+
89+
if "query" in report.iocs:
90+
th_report["iocs"]["query"] = []
91+
for query in report.iocs.get("query", []):
92+
try:
93+
search = query.get('search_query', "")
94+
if "q=" in search:
95+
params = search.split('&')
96+
for p in params:
97+
if "q=" in p:
98+
search = unquote(p[2:])
99+
# Converts the CB Response query to CB Threat Hunter
100+
th_query = cb_th.convert_query(search)
101+
if th_query:
102+
query["search_query"] = th_query
103+
th_report["iocs"]["query"].append(query)
104+
except ServerError as e:
105+
print ('Invalid query {}'.format(query.get('search_query', "")))
106+
107+
th_feed["reports"].append(th_report)
108+
109+
# Pushes the new feed to CB Threat Hunter
110+
new_feed = cb_th.create(FeedTH, th_feed)
111+
new_feed.save()
112+
print ("{}\n".format(new_feed))
113+
114+
def main():
115+
parser = build_cli_parser()
116+
parser.add_argument("-thp", "--threatprofile", help="Threat Hunter profile", default="default")
117+
commands = parser.add_subparsers(help="Feed commands", dest="command_name")
118+
119+
list_command = commands.add_parser("list", help="List all configured feeds")
120+
121+
list_reports_command = commands.add_parser("list-reports", help="List all configured reports for a feed")
122+
list_reports_command.add_argument("-i", "--id", type=str, help="Feed ID")
123+
124+
convert_feed_command = commands.add_parser("convert", help="Convert feed from CB Response to CB Threat Hunter")
125+
convert_feed_command.add_argument("-i", "--id", type=str, help="Feed ID")
126+
127+
args = parser.parse_args()
128+
cb = get_cb_response_object(args)
129+
cb_th = CbThreatHunterAPI(profile=args.threatprofile)
130+
131+
if args.command_name == "list":
132+
return list_feeds(cb, parser, args)
133+
if args.command_name == "list-reports":
134+
return list_reports(cb, parser, args)
135+
if args.command_name == "convert":
136+
return convert_feed(cb, cb_th, parser, args)
137+
138+
if __name__ == "__main__":
139+
sys.exit(main())

0 commit comments

Comments
 (0)