Skip to content

Commit 13c79c1

Browse files
evilcel3riPandora
authored andcommitted
[feat] adding analyse from URL
1 parent 8a18722 commit 13c79c1

5 files changed

Lines changed: 102 additions & 6 deletions

File tree

bazaar/core/api_view.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import logging
2+
import hashlib
3+
import requests
24

35
from django.conf import settings
46
from django.core.files.storage import default_storage
@@ -15,6 +17,9 @@
1517
from bazaar.core.utils import get_sha256_of_file
1618
from bazaar.front.utils import transform_hl_results
1719

20+
from androguard.core.androconf import is_android
21+
from tempfile import NamedTemporaryFile
22+
1823

1924
@api_view(['GET', 'POST'])
2025
@authentication_classes([TokenAuthentication])
@@ -37,6 +42,38 @@ def apk_upload(request):
3742
return Response({"file_sha256": sha256})
3843

3944

45+
@api_view(['GET'])
46+
@authentication_classes([TokenAuthentication])
47+
@permission_classes([IsAuthenticated])
48+
def url_download(request):
49+
if not request.user.is_authenticated:
50+
return Response({"user": "is_authenticated"})
51+
else:
52+
res = requests.get(request.data['url'])
53+
54+
if res.status_code not in [200, 301, 302]:
55+
return Response({"url": "URL is not available."})
56+
57+
sha256_hash = hashlib.sha256()
58+
with NamedTemporaryFile() as tmp:
59+
for chunk in res.iter_content(chunk_size=16 * 1024):
60+
tmp.write(chunk)
61+
sha256_hash.update(chunk)
62+
63+
sha256 = str(sha256_hash.hexdigest()).lower()
64+
if is_android(tmp.name) != 'APK':
65+
return Response({"apk": "not a valid APK"})
66+
67+
sha256 = get_sha256_of_file(tmp)
68+
if default_storage.exists(sha256):
69+
# analyze(sha256, force=True)
70+
return Response({"file_sha256": sha256})
71+
else:
72+
default_storage.save(sha256, tmp)
73+
analyze(sha256)
74+
return Response({"file_sha256": sha256})
75+
76+
4077
@api_view(['GET'])
4178
@authentication_classes([TokenAuthentication])
4279
@permission_classes([IsAuthenticated])

bazaar/front/forms.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ class BasicUploadForm(forms.Form):
104104
apk = forms.FileField()
105105

106106

107+
class BasicUrlDownloadForm(forms.Form):
108+
url = forms.URLField()
109+
110+
107111
class YaraCreateForm(ModelForm):
108112
class Meta:
109113
model = Yara

bazaar/front/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from bazaar.front.view import HomeView, ReportView, basic_upload_view, similarity_search_view, export_report_view, \
44
download_sample_view, my_rules_view, my_rule_edit_view, my_rule_create_view, my_rule_delete_view, og_card_view, \
5-
my_retrohunt_view, get_andgrocfg_code, get_genom
5+
my_retrohunt_view, get_andgrocfg_code, get_genom, basic_url_download_view
66

77
app_name = "front"
88
urlpatterns = [
@@ -11,6 +11,7 @@
1111
path("report/<str:sha256>/json", view=export_report_view, name="export_report"),
1212
path("report/<str:sha256>/card", view=og_card_view, name="og_card"),
1313
path("apk/", view=basic_upload_view, name="basic_upload"),
14+
path("url/", view=basic_url_download_view, name="basic_url_download"),
1415
path("apk/<str:sha256>", view=download_sample_view, name="download_sample"),
1516
path("similar/", view=similarity_search_view, name="similarity_search"),
1617
path("similar/<str:sha256>", view=similarity_search_view, name="similarity_search"),

bazaar/front/view.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import logging
22
from tempfile import NamedTemporaryFile
3+
import requests
4+
import hashlib
35

46
from androguard.core.androconf import is_android
57
from django.conf import settings
@@ -28,7 +30,7 @@
2830
from bazaar.core.models import Yara
2931
from bazaar.core.tasks import analyze, retrohunt
3032
from bazaar.core.utils import get_sha256_of_file, get_matching_items_by_dexofuzzy
31-
from bazaar.front.forms import SearchForm, BasicUploadForm, SimilaritySearchForm
33+
from bazaar.front.forms import SearchForm, BasicUploadForm, SimilaritySearchForm, BasicUrlDownloadForm
3234
from bazaar.front.og import generate_og_card
3335
from bazaar.front.utils import transform_results, get_similarity_matrix, compute_status, generate_world_map, \
3436
transform_hl_results, get_sample_timeline, get_andro_cfg_storage_path
@@ -150,6 +152,37 @@ def get(self, request, *args, **kwargs):
150152
return redirect(reverse_lazy('front:home'))
151153

152154

155+
def basic_url_download_view(request):
156+
if request.method == 'POST':
157+
form = BasicUrlDownloadForm(request.POST)
158+
if form.is_valid():
159+
url = form.cleaned_data.get('url')
160+
res = requests.get(url, stream=True)
161+
162+
if res.status_code not in [200, 301, 302]:
163+
messages.warning(request, 'URL is not available.')
164+
return redirect(reverse_lazy('front:home'))
165+
166+
sha256_hash = hashlib.sha256()
167+
with NamedTemporaryFile() as tmp:
168+
for chunk in res.iter_content(chunk_size=16 * 1024):
169+
tmp.write(chunk)
170+
sha256_hash.update(chunk)
171+
172+
sha256 = str(sha256_hash.hexdigest()).lower()
173+
if is_android(tmp.name) != 'APK':
174+
messages.warning(request, 'Submitted file is not a valid APK.')
175+
176+
if default_storage.exists(sha256):
177+
return redirect(reverse_lazy('front:report', [sha256]))
178+
else:
179+
default_storage.save(sha256, tmp)
180+
analyze(sha256)
181+
return redirect(reverse_lazy('front:report', [sha256]))
182+
183+
return redirect(reverse_lazy('front:home'))
184+
185+
153186
def basic_upload_view(request):
154187
if request.method == 'POST':
155188
form = BasicUploadForm(request.POST, request.FILES)
@@ -414,15 +447,14 @@ def get_andgrocfg_code(request, sha256, foo):
414447
out = default_storage.open(f'{storage_path}/{foo}').read()
415448

416449
if f'{storage_path}/{foo}'.endswith('.raw'):
417-
out_formatted = highlight(out,JavaLexer(), HtmlFormatter(style=U39bStyle, noclasses=True))
450+
out_formatted = highlight(out, JavaLexer(), HtmlFormatter(style=U39bStyle, noclasses=True))
418451
return HttpResponse(out_formatted, content_type="text/html")
419452
elif f'{storage_path}/{foo}'.endswith('.png'):
420453
return HttpResponse(out, content_type='image/bmp')
421454
else:
422455
return HttpResponse(out, content_type="image/bmp")
423456

424457

425-
426458
def get_genom(request):
427459
es = Elasticsearch(settings.ELASTICSEARCH_HOSTS)
428460
entire_genom = []
@@ -436,7 +468,8 @@ def get_genom(request):
436468
threat = 'unknown'
437469
try:
438470
genom = report.get('_source').get('andro_cfg').get('genom')
439-
threat = report.get('_source').get('vt_report').get('attributes').get('popular_threat_classification').get('suggested_threat_label')
471+
threat = report.get('_source').get('vt_report').get('attributes').get(
472+
'popular_threat_classification').get('suggested_threat_label')
440473
except Exception:
441474
pass
442475
if genom:

bazaar/templates/front/index.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ <h3 class=" text-white">Mobile threat intelligence for the masses</h3>
1717

1818
{# Search form #}
1919
<div class="row justify-content-center mt-2">
20-
<div class="col-md-6 mt-2 mb-2">
20+
<div class="col-md-12 mt-2 mb-2">
2121
<form class="form-horizontal text-center" method="get">
2222
<div class="input-group">
2323
{% if q %}
@@ -39,6 +39,8 @@ <h3 class=" text-white">Mobile threat intelligence for the masses</h3>
3939
</div>
4040
</form>
4141
</div>
42+
</div>
43+
<div class="row justify-content-center mt-2">
4244
<div class="col-md-6 mt-2 mb-2">
4345
<form class="form-horizontal text-center" method="post" action="{% url "front:basic_upload" %}"
4446
enctype="multipart/form-data">{% csrf_token %}
@@ -59,6 +61,25 @@ <h3 class=" text-white">Mobile threat intelligence for the masses</h3>
5961
</div>
6062
</form>
6163
</div>
64+
<div class="row justify-content-center mt-2">
65+
<div class="col-md-6 mt-2 mb-2">
66+
<form class="form-horizontal text-center" method="post" action="{% url "front:basic_url_download" %}"
67+
enctype="multipart/form-data">{% csrf_token %}
68+
<div class="custom-url">
69+
<input type="text" id="url" name="url">
70+
<label for="url">URL to the APK</label>
71+
</div>
72+
<div class="control-group mt-1">
73+
<div class="controls">
74+
<button type="submit" class="btn btn-primary">
75+
Analyze
76+
</button>
77+
</div>
78+
</div>
79+
</form>
80+
</div>
81+
82+
</div>
6283
</div>
6384

6485

0 commit comments

Comments
 (0)