diff --git a/bazaar/core/services/search.py b/bazaar/core/services/search.py index e84861f..54409f0 100644 --- a/bazaar/core/services/search.py +++ b/bazaar/core/services/search.py @@ -87,9 +87,87 @@ def similarity_search(search_hash, algorithm, ignore_sha=''): ) case 'func_hash': results = get_matching_items_by_ssdeep_func( - search_hash, 25, settings.ELASTICSEARCH_APK_INDEX, ignore_sha + search_hash, 25, settings.ELASTICSEARCH_APK_INDEX ) except Exception as e: logging.error(e) return results + + +def compare_search(left_sha, right_sha): + shas = [] + shas.append(left_sha) + shas.append(right_sha) + + results = [] + for sha in shas: + query = { + "query": { + "query_string": { + "default_field": "sha256", + "query": sha, + } + }, + "highlight": { + "fields": { + "*": {"pre_tags": [""], "post_tags": [""]} + } + }, + "aggs": { + "permissions": { + "terms": {"field": "permissions.keyword"} + }, + "domains": { + "terms": {"field": "domains_analysis._name.keyword"} + }, + "android_features": { + "terms": {"field": "features.keyword"} + } + }, + "sort": {"analysis_date": "desc"}, + "_source": [ + "uaid", + "signatures", + "is_signed", + "is_signed_v1", + "is_signed_v2", + "is_signed_v3", + "certificates", + "dexofuzzy", + "apkid", + "manifest_analysis", + "browsable_activities", + "niap_analysis", + "code_analysis", + "detailed_permissions", + "trackers", + "quark.crimes", + "android_api_analysis", + "ssdeep", + "version_name", + "apk_hash", + "app_name", + "dexofuzzy.apk", + "features" + "frosting_data.is_frosted", + "handle", + "is_signed", + "md5", + "quark.threat_level", + "sha1", + "sha256", + "size", + "uploaded_at", + "version_code", + ], + "size": 1, + } + es = Elasticsearch(settings.ELASTICSEARCH_HOSTS) + try: + raw_results = es.search(index=settings.ELASTICSEARCH_APK_INDEX, body=query) + results.append(transform_hl_results(raw_results)) + except Exception: + return [] + + return results diff --git a/bazaar/core/utils.py b/bazaar/core/utils.py index 7d0e07c..3a58925 100644 --- a/bazaar/core/utils.py +++ b/bazaar/core/utils.py @@ -306,7 +306,7 @@ def get_matching_items_by_ssdeep(ssdeep_value, threshold_grade, index, sha256): return sha256_list_to_return -def get_matching_items_by_ssdeep_func(ssdeep_value, threshold_grade, index, sha256): +def get_matching_items_by_ssdeep_func(ssdeep_value, threshold_grade, index): chunksize, chunk, double_chunk = ssdeep_value.split(':') chunksize = int(chunksize) es = Elasticsearch( diff --git a/bazaar/front/forms.py b/bazaar/front/forms.py index 345c090..5c8141b 100644 --- a/bazaar/front/forms.py +++ b/bazaar/front/forms.py @@ -63,3 +63,14 @@ class Meta: "rows": 5, }), } + + +class CompareSearchForm(forms.Form): + left_sha = forms.CharField(required=False) + right_sha = forms.CharField(required=False) + + def do_search(self): + return SearchService.compare_search( + self.cleaned_data['left_sha'], + self.cleaned_data['right_sha'] + ) diff --git a/bazaar/front/urls.py b/bazaar/front/urls.py index febe0b6..9671d4d 100644 --- a/bazaar/front/urls.py +++ b/bazaar/front/urls.py @@ -5,7 +5,7 @@ download_sample_view, my_rule_edit_view, my_rule_create_view, my_rule_delete_view, og_card_view, \ my_retrohunt_view, get_andgrocfg_code, get_genom, basic_url_download_view, report_status_view, instance_status, \ remove_bookmark_sample_view, add_bookmark_sample_view, workspace_view, add_comment_view, delete_comment_view, \ - notifications_view, notification_delete_view, dl_hidden + notifications_view, notification_delete_view, dl_hidden, compare_analysis_view app_name = "front" urlpatterns = [ @@ -36,5 +36,7 @@ path("comment//add", view=add_comment_view, name="add_comment"), path("comment//delete", view=delete_comment_view, name="delete_comment"), path("notifications", view=notifications_view, name="notifications_url"), - path("notifications//delete", view=notification_delete_view, name="notifications_url") + path("notifications//delete", view=notification_delete_view, name="notifications_url"), + path("compare/", view=compare_analysis_view, name="compare_analysis"), + path("compare//to/", view=compare_analysis_view, name="compare_analysis") ] diff --git a/bazaar/front/view.py b/bazaar/front/view.py index 480527c..69bc8bf 100644 --- a/bazaar/front/view.py +++ b/bazaar/front/view.py @@ -34,7 +34,8 @@ from bazaar.core.models import Yara, Bookmark, Comment, Notification from bazaar.core.modules.pithus import retrohunt from bazaar.core.utils import get_matching_items_by_dexofuzzy -from bazaar.front.forms import SearchForm, BasicUploadForm, SimilaritySearchForm, BasicUrlDownloadForm, CommentForm +from bazaar.front.forms import SearchForm, BasicUploadForm, SimilaritySearchForm, \ + BasicUrlDownloadForm, CommentForm, CompareSearchForm from bazaar.front.og import generate_og_card from bazaar.front.utils import get_similarity_matrix, generate_world_map, \ get_sample_timeline, get_andro_cfg_storage_path @@ -853,3 +854,44 @@ def get_genom(request): def instance_status(request): return render(request, 'front/instance_status.html') + + +def compare_analysis_view(request, *args, **kwargs): + + if request.method == 'GET': + left_sha = kwargs.get('left_sha') or request.GET.get('left_sha', '') + right_sha = kwargs.get('right_sha') or request.GET.get('right_sha', '') + + f = CompareSearchForm(initial={ + 'left_sha': left_sha, + 'right_sha': right_sha, + }) + + res = [] + left_res = None + right_res = None + + if left_sha and right_sha: + f = CompareSearchForm({ + 'left_sha': left_sha, + 'right_sha': right_sha, + }) + + if f.is_valid(): + res = f.do_search() + if res: + left_res = res[0][0]['source'] + right_res = res[1][0]['source'] + else: + return render(request, 'front/compare_analysis.html') + + print(res) + return render( + request, + 'front/compare_analysis.html', + context={ + 'form': f, + 'left_analysis': left_res, + 'right_analysis': right_res + } + ) diff --git a/bazaar/static/css/project.css b/bazaar/static/css/project.css index 235a931..4d7394c 100644 --- a/bazaar/static/css/project.css +++ b/bazaar/static/css/project.css @@ -7330,3 +7330,27 @@ samp { background-color: #dc3545; border-radius: 50%; border: 2px solid #fff; } + +.comparison-table { + width: 100%; + overflow: hidden; } + +.comparison-table-inner { + width: 100%; + table-layout: fixed; } + +.comparison-table-inner th:first-child, +.comparison-table-inner td:first-child { + width: 120px; } + +.comparison-table-inner th:nth-child(2), +.comparison-table-inner th:nth-child(3), +.comparison-table-inner td:nth-child(2), +.comparison-table-inner td:nth-child(3) { + width: auto; + overflow-wrap: break-word; } + +.comparison-cell { + width: 100%; + overflow-x: auto; + white-space: nowrap; } diff --git a/bazaar/static/sass/project.scss b/bazaar/static/sass/project.scss index 97a7de9..5263e5f 100644 --- a/bazaar/static/sass/project.scss +++ b/bazaar/static/sass/project.scss @@ -84,7 +84,6 @@ samp { color: $gray-600; } - .notification-bell { position: relative; display: inline-block; @@ -100,3 +99,32 @@ samp { border-radius: 50%; border: 2px solid #fff; } + +.comparison-table { + width: 100%; + overflow: hidden; +} + +.comparison-table-inner { + width: 100%; + table-layout: fixed; +} + +.comparison-table-inner th:first-child, +.comparison-table-inner td:first-child { + width: 120px; +} + +.comparison-table-inner th:nth-child(2), +.comparison-table-inner th:nth-child(3), +.comparison-table-inner td:nth-child(2), +.comparison-table-inner td:nth-child(3) { + width: auto; + overflow-wrap: break-word; +} + +.comparison-cell { + width: 100%; + overflow-x: auto; + white-space: nowrap; +} \ No newline at end of file diff --git a/bazaar/templates/front/compare_analysis.html b/bazaar/templates/front/compare_analysis.html new file mode 100644 index 0000000..d76a32f --- /dev/null +++ b/bazaar/templates/front/compare_analysis.html @@ -0,0 +1,328 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} +{% load get %} +{% load comma_to_br %} + +{% block whole_content %} +
+
+
+
+

Compare two analysis

+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ + {% if left_analysis and right_analysis %} +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% if left_analysis.manifest_analysis or right_analysis.manifest_analysis %} + + + + + + {% endif %} + + {% if left_analysis.browsable_activities and right_analysis.browsable_activities %} + + + + + + {% endif %} + + {% if left_analysis.niap_analysis and right_analysis.niap_analysis %} + + + + + + {% endif %} + + {% if left_analysis.code_analysis and right_analysis.code_analysis %} + + + + + + {% endif %} + + {% if left_analysis.detailed_permissions and right_analysis.detailed_permissions %} + + + + + + {% endif %} + + {% if left_analysis.trackers and right_analysis.trackers %} + + + + + + {% endif %} + + {% if left_analysis.quark.crimes and right_analysis.quark.crimes %} + + + + + + {% endif %} + + {% if left_analysis.android_api_analysis and right_analysis.android_api_analysis %} + + + + + + {% endif %} + + +
{{left_analysis.sha256}}{{right_analysis.sha256}} +
+

File sums

+
+
+ {% include "front/report/m_file.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_file.html" with d=rigt_analysis %} +
+
+

APKiD

+

Information computed with APKiD. +

+
+
+ {% include "front/report/m_apkid.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_apkid.html" with d=right_analysis %} +
+
+

SSdeep

+

Information computed with ssdeep. +

+
+
+ {% include "front/report/m_ssdeep.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_ssdeep.html" with d=right_analysis %} +
+
+

Dexofuzzy

+
+
+ {% include "front/report/m_dexofuzzy.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_dexofuzzy.html" with d=right_analysis %} +
+
+

APK details

+

Information computed with AndroGuard + and Pithus. +

+
+
+ {% include "front/report/m_apk.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_apk.html" with d=right_analysis %} +
+
+

Certificate

+

Information computed with AndroGuard. +

+
+
+ {% include "front/report/m_certificate.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_certificate.html" with d=right_analysis %} +
+
+

Manifest

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_manifest.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_manifest.html" with d=right_analysis %} +
+
+

Browsable activities

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_browsable_activities.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_browsable_activities.html" with d=right_analysis %} +
+
+

NIAP analysis

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_niap.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_niap.html" with d=right_analysis %} +
+
+

Code analysis

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_code.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_code.html" with d=right_analysis %} +
+
+

Permissions analysis

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_permissions.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_permissions.html" with d=right_analysis %} +
+
+

Tracking analysis

+

Information computed with Exodus-core. +

+
+
+ {% include "front/report/m_trackers.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_trackers.html" with d=right_analysis %} +
+
+

Threat analysis

+

Information computed with Quark-Engine. +

+
+
+ {% include "front/report/m_quark.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_quark.html" with d=right_analysis %} +
+
+

Behavior analysis

+

Information computed with MobSF. +

+
+
+ {% include "front/report/m_api.html" with d=left_analysis %} +
+
+
+ {% include "front/report/m_api.html" with d=right_analysis %} +
+
+ {% endif %} +
+
+{% endblock whole_content %} \ No newline at end of file diff --git a/bazaar/templates/front/m_similarities.html b/bazaar/templates/front/m_similarities.html index 25dc9c3..41aad5b 100644 --- a/bazaar/templates/front/m_similarities.html +++ b/bazaar/templates/front/m_similarities.html @@ -39,6 +39,11 @@ + +
+ Compare +
+ {% endif %} {% endfor %} diff --git a/bazaar/templates/front/report.html b/bazaar/templates/front/report.html index 18e4817..00d9afc 100644 --- a/bazaar/templates/front/report.html +++ b/bazaar/templates/front/report.html @@ -40,14 +40,18 @@ data-toggle="tooltip" data-placement="top" title="Export the report in JSON"> {% if is_bookmarked %} - {% else %} - {% endif %} + + + {% endif %}