Skip to content

Commit f863ea8

Browse files
author
pranavshukla
committed
Fix Hybrid Analysis hash GET analyzer
1 parent 987765d commit f863ea8

File tree

1 file changed

+90
-25
lines changed
  • api_app/analyzers_manager/observable_analyzers

1 file changed

+90
-25
lines changed

api_app/analyzers_manager/observable_analyzers/ha_get.py

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from api_app.analyzers_manager.classes import ObservableAnalyzer
77
from api_app.analyzers_manager.exceptions import AnalyzerRunException
88
from api_app.choices import Classification
9-
from tests.mock_utils import MockUpResponse, if_mock_connections, patch
109

1110

1211
class HybridAnalysisGet(ObservableAnalyzer):
@@ -31,53 +30,119 @@ def run(self):
3130
if obs_clsfn == Classification.DOMAIN:
3231
data = {"domain": self.observable_name}
3332
uri = "search/terms"
33+
response = requests.post(self.api_url + uri, data=data, headers=headers)
3434
elif obs_clsfn == Classification.IP:
3535
data = {"host": self.observable_name}
3636
uri = "search/terms"
37+
response = requests.post(self.api_url + uri, data=data, headers=headers)
3738
elif obs_clsfn == Classification.URL:
3839
data = {"url": self.observable_name}
3940
uri = "search/terms"
41+
response = requests.post(self.api_url + uri, data=data, headers=headers)
4042
elif obs_clsfn == Classification.HASH:
41-
data = {"hash": self.observable_name}
4243
uri = "search/hash"
44+
params = {"hash": self.observable_name}
45+
response = requests.get(self.api_url + uri, params=params, headers=headers)
4346
else:
4447
raise AnalyzerRunException(
4548
f"not supported observable type {obs_clsfn}. "
4649
"Supported are: hash, ip, domain and url"
4750
)
4851

49-
response = requests.post(self.api_url + uri, data=data, headers=headers)
5052
response.raise_for_status()
51-
5253
result = response.json()
53-
# adding permalink to results
54-
if isinstance(result, list):
55-
for job in result:
56-
sha256 = job.get("sha256", "")
57-
job_id = job.get("job_id", "")
58-
if sha256:
59-
job["permalink"] = f"{self.sample_url}/{sha256}"
60-
if job_id:
61-
job["permalink"] += f"/{job_id}"
54+
55+
if obs_clsfn == Classification.HASH and isinstance(result, list):
56+
detailed_results = []
57+
for item in result:
58+
if isinstance(item, dict) and (
59+
item.get("job_id") or item.get("verdict") or item.get("threat_score")
60+
):
61+
sha256 = item.get("sha256", "")
62+
job_id = item.get("job_id", "")
63+
if sha256:
64+
item["permalink"] = f"{self.sample_url}/{sha256}"
65+
if job_id:
66+
item["permalink"] += f"/{job_id}"
67+
detailed_results.append(item)
68+
else:
69+
sha256 = item if isinstance(item, str) else item.get("sha256") or item.get("hash")
70+
if sha256:
71+
overview_uri = f"overview/{sha256}"
72+
try:
73+
overview_response = requests.get(
74+
self.api_url + overview_uri, headers=headers
75+
)
76+
overview_response.raise_for_status()
77+
sample_summary = overview_response.json()
78+
job_id = sample_summary.get("job_id", "")
79+
sample_summary["permalink"] = f"{self.sample_url}/{sha256}"
80+
if job_id:
81+
sample_summary["permalink"] += f"/{job_id}"
82+
detailed_results.append(sample_summary)
83+
except requests.RequestException:
84+
if isinstance(item, dict):
85+
item["permalink"] = f"{self.sample_url}/{sha256}"
86+
detailed_results.append(item)
87+
elif isinstance(item, str):
88+
detailed_results.append(
89+
{
90+
"sha256": sha256,
91+
"permalink": f"{self.sample_url}/{sha256}",
92+
}
93+
)
94+
result = detailed_results if detailed_results else result
95+
else:
96+
if isinstance(result, list):
97+
for job in result:
98+
sha256 = job.get("sha256", "")
99+
job_id = job.get("job_id", "")
100+
if sha256:
101+
job["permalink"] = f"{self.sample_url}/{sha256}"
102+
if job_id:
103+
job["permalink"] += f"/{job_id}"
62104

63105
return result
106+
<<<<<<< HEAD
107+
=======
64108

65109
@classmethod
66110
def _monkeypatch(cls):
111+
def side_effect(*args, **kwargs):
112+
url = args[0] if args else kwargs.get("url", "")
113+
# Mock GET /search/hash response (returns list of hashes)
114+
if "search/hash" in url and kwargs.get("params"):
115+
return MockUpResponse(
116+
["abcdefgh"],
117+
200,
118+
)
119+
# Mock GET /overview/{sha256} response (returns full SampleSummary)
120+
elif "overview/" in url:
121+
return MockUpResponse(
122+
{
123+
"job_id": "1",
124+
"sha256": "abcdefgh",
125+
"verdict": "malicious",
126+
},
127+
200,
128+
)
129+
# Mock POST /search/terms response (for domain, IP, URL)
130+
else:
131+
return MockUpResponse(
132+
[
133+
{
134+
"job_id": "1",
135+
"sha256": "abcdefgh",
136+
}
137+
],
138+
200,
139+
)
140+
67141
patches = [
68142
if_mock_connections(
69-
patch(
70-
"requests.post",
71-
return_value=MockUpResponse(
72-
[
73-
{
74-
"job_id": "1",
75-
"sha256": "abcdefgh",
76-
}
77-
],
78-
200,
79-
),
80-
),
143+
patch("requests.get", side_effect=side_effect),
144+
patch("requests.post", side_effect=side_effect),
81145
)
82146
]
83147
return super()._monkeypatch(patches=patches)
148+
>>>>>>> 781a8a22 (Initial sync before fix)

0 commit comments

Comments
 (0)