Skip to content

Commit c1bd2fd

Browse files
Add advanced module
1 parent 9d6721c commit c1bd2fd

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed

ReversingLabs/SDK/advanced.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import io
2+
3+
import requests
4+
5+
from ReversingLabs.SDK.helper import DEFAULT_USER_AGENT, WrongInputError
6+
from ReversingLabs.SDK.ticloud import FileAnalysis, DynamicAnalysis, AdvancedSearch, FileDownload
7+
from ReversingLabs.SDK.a1000 import A1000
8+
9+
10+
class AdvancedActions(object):
11+
"""A class containing advanced and combined actions
12+
utilizing various different classes."""
13+
14+
def __init__(self, host, username, password, verify=True, proxies=None, user_agent=DEFAULT_USER_AGENT,
15+
allow_none_return=False):
16+
17+
self._rldata_client = FileAnalysis(
18+
host=host,
19+
username=username,
20+
password=password,
21+
verify=verify,
22+
user_agent=user_agent,
23+
proxies=proxies,
24+
allow_none_return=allow_none_return
25+
)
26+
27+
self._da_client = DynamicAnalysis(
28+
host=host,
29+
username=username,
30+
password=password,
31+
verify=verify,
32+
user_agent=user_agent,
33+
proxies=proxies,
34+
allow_none_return=allow_none_return
35+
)
36+
37+
def enriched_file_analysis(self, sample_hash):
38+
"""Accepts a sample hash and returns a TCA-0104 File Analysis report enriched with a TCA-0106 Dynamic Analysis
39+
report.
40+
:param sample_hash: sample hash
41+
:type sample_hash: str
42+
:return: file analysis report enriched with dynamic analysis
43+
:rtype: dict
44+
"""
45+
da_response = self._da_client.get_dynamic_analysis_results(
46+
sample_hash=sample_hash
47+
)
48+
49+
rldata_response = self._rldata_client.get_analysis_results(
50+
hash_input=sample_hash
51+
)
52+
53+
da_report = da_response.json().get("rl", {}).get("report")
54+
if da_report:
55+
rldata_report = rldata_response.json()
56+
try:
57+
rldata_report["rl"]["sample"]["dynamic_analysis"]["report"] = da_report
58+
except KeyError:
59+
rldata_report["rl"]["sample"]["dynamic_analysis"] = {}
60+
rldata_report["rl"]["sample"]["dynamic_analysis"]["report"] = da_report
61+
62+
return rldata_report
63+
64+
return {}
65+
66+
67+
class SpectraAssureScenarios(object):
68+
"""A class for scenarios that include RL Spectra Assure and other RL services from the RLSDK."""
69+
70+
def __init__(self, spectra_assure_client, verify_certs=True):
71+
72+
self._spectra_assure_client = spectra_assure_client
73+
self.verify_certs = verify_certs
74+
75+
def a1000_upload_to_assure(self, a1000_host, a1000_token, file_hash, filename, project, package, version):
76+
a1000_client = A1000(
77+
host=a1000_host,
78+
token=a1000_token,
79+
user_agent=DEFAULT_USER_AGENT,
80+
verify=self.verify_certs
81+
)
82+
83+
file_content = a1000_client.download_sample(sample_hash=file_hash).content
84+
85+
response = self._spectra_assure_client.submit_package(
86+
file=file_content,
87+
filename=filename,
88+
project=project,
89+
package=package,
90+
version=version
91+
)
92+
93+
return response
94+
95+
def ticloud_upload_to_assure(self, ticloud_host, ticloud_username, ticloud_password, file_hash, filename, project,
96+
package, version):
97+
download_client = FileDownload(
98+
host=ticloud_host,
99+
username=ticloud_username,
100+
password=ticloud_password,
101+
user_agent=DEFAULT_USER_AGENT,
102+
verify=self.verify_certs
103+
)
104+
105+
file_content = download_client.download_sample(hash_input=file_hash).content
106+
107+
response = self._spectra_assure_client.submit_package(
108+
file=file_content,
109+
filename=filename,
110+
project=project,
111+
package=package,
112+
version=version
113+
)
114+
115+
return response
116+
117+
118+
class SpectraAssureClient(object):
119+
def __init__(self, host, token, organization, group, user_agent=DEFAULT_USER_AGENT, verify=True):
120+
self._host = host
121+
self._headers = {
122+
"Authorization": f"Bearer {token}",
123+
"User-Agent": user_agent
124+
}
125+
self._organization = organization
126+
self._group = group
127+
self._verify = verify
128+
129+
def submit_package(self, file, filename, project, package, version):
130+
url = f"{self._host}/api/public/v1/scan/{self._organization}/{self._group}/pkg:rl/{project}/{package}@{version}"
131+
132+
if isinstance(file, str):
133+
file_handle = open(file, "rb")
134+
135+
elif isinstance(file, bytes) or isinstance(file, io.IOBase):
136+
file_handle = file
137+
138+
else:
139+
raise WrongInputError(f"The file parameter must either be {str}, {bytes} or {io.IOBase} type.")
140+
141+
self._headers["Content-Disposition"] = f"attachment; filename={filename}"
142+
self._headers["Content-Type"] = "application/octet-stream"
143+
144+
response = requests.post(
145+
url=url,
146+
headers=self._headers,
147+
data=file_handle,
148+
verify=self._verify
149+
)
150+
151+
if hasattr(file_handle, "read"):
152+
file_handle.close()
153+
154+
return response
155+
156+
def get_analysis_status(self, project, package, version):
157+
url = (f"{self._host}/api/public/v1/status/{self._organization}/{self._group}/"
158+
f"pkg:rl/{project}/{package}@{version}")
159+
160+
response = requests.get(
161+
url=url,
162+
headers=self._headers,
163+
verify=self._verify
164+
)
165+
166+
return response
167+
168+
def get_analysis_report(self, report_type, project, package, version):
169+
url = (f"{self._host}/api/public/v1/report/{self._organization}/{self._group}/{report_type}/"
170+
f"pkg:rl/{project}/{package}@{version}")
171+
172+
response = requests.get(
173+
url=url,
174+
headers=self._headers,
175+
verify=self._verify
176+
)
177+
178+
return response
179+
180+
181+
182+

0 commit comments

Comments
 (0)