Skip to content

Commit

Permalink
upload url refactoring (#693)
Browse files Browse the repository at this point in the history
* refactor upload

* code QA

* fixed return data

* add vscode gitignore
  • Loading branch information
sydowma authored and ajinabraham committed Aug 23, 2018
1 parent 7dd288d commit 5119d43
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 179 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ MobSF/windows_vm_priv_key.asc
# C extensions
*.so

.vscode/

# Distribution / packaging
.Python
venv/
Expand Down
25 changes: 25 additions & 0 deletions MobSF/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,28 @@

class UploadFileForm(forms.Form):
file = forms.FileField()


class FormUtil(object):

def __init__(self, form):
self.form = form

@staticmethod
def errors_message(form):
"""
:param form forms.Form
form.errors.get_json_data() django 2.0 or higher
:return
example { "error": "file This field is required." }
"""
errors_messages = []
for k, value in form.errors.get_json_data().items():
errors_messages.append(
(k + ' ' + ' , '.join([i['message'] for i in value])))
return '; '.join(errors_messages)

@staticmethod
def errors(form):
return form.errors.items()
18 changes: 8 additions & 10 deletions MobSF/rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from .forms import UploadFileForm
from MobSF.views import (
upload,
Upload,
delete_scan
)
from MobSF.utils import (
Expand All @@ -18,9 +18,10 @@
from StaticAnalyzer.views.ios.static_analyzer import static_analyzer_ios
from StaticAnalyzer.views.windows import staticanalyzer_windows

from django.http import HttpResponse
from django.http import HttpResponse, JsonResponse, HttpResponseBadRequest, HttpResponseNotAllowed
from django.views.decorators.csrf import csrf_exempt

POST = 'POST'

def make_api_response(data, status=200):
"""Make API Response"""
Expand All @@ -41,15 +42,12 @@ def api_auth(meta):
@csrf_exempt
def api_upload(request):
"""POST - Upload API"""
if request.method == 'POST':
resp = upload(request, True)
if "error" in resp:
response = make_api_response(resp, 500)
else:
response = make_api_response(resp)
if request.method == POST:
upload = Upload(request)
return upload.upload_api()
else:
response = make_api_response({"error": "Method Not Allowed"}, 405)
return response
return HttpResponseNotAllowed([POST])



@csrf_exempt
Expand Down
119 changes: 119 additions & 0 deletions MobSF/scanning.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@

# from MobSF.views import handle_uploaded_file, add_to_recent_scan
import hashlib
import os

from django.conf import settings
from django.utils import timezone

from MobSF.utils import PrintException
from StaticAnalyzer.models import RecentScansDB


def add_to_recent_scan(name, md5, url):
"""
Add Entry to Database under Recent Scan
"""
try:
db_obj = RecentScansDB.objects.filter(MD5=md5)
if not db_obj.exists():
new_db_obj = RecentScansDB(
NAME=name, MD5=md5, URL=url, TS=timezone.now())
new_db_obj.save()
except:
PrintException("[ERROR] Adding Scan URL to Database")


def handle_uploaded_file(filecnt, typ):
"""
Write Uploaded File
"""
md5 = hashlib.md5() # modify if crash for large
for chunk in filecnt.chunks():
md5.update(chunk)
md5sum = md5.hexdigest()
anal_dir = os.path.join(settings.UPLD_DIR, md5sum + '/')
if not os.path.exists(anal_dir):
os.makedirs(anal_dir)
with open(anal_dir + md5sum + typ, 'wb+') as destination:
for chunk in filecnt.chunks():
destination.write(chunk)
return md5sum



class Scanning(object):

def __init__(self, request):
self.request = request
self.file = request.FILES['file']
self.file_name = request.FILES['file'].name

def scan_apk(self):
"""
"""
# APK
md5 = handle_uploaded_file(self.file, '.apk')
data = {
'url': 'StaticAnalyzer/?name={}&type=apk&checksum={}'.format(self.file_name, md5),
'status': 'success',
'hash': md5,
'scan_type': 'apk',
'file_name': self.file_name
}

add_to_recent_scan(self.file_name, md5, data['url'])

print("\n[INFO] Performing Static Analysis of Android APK")
return data

def scan_zip(self):
"""
"""
# Android /iOS Zipped Source
md5 = handle_uploaded_file(self.file, '.zip')

data = {
'url': 'StaticAnalyzer/?name={}&type=zip&checksum={}'.format(self.file_name, md5),
'status': 'success',
'hash': md5,
'scan_type': 'zip',
'file_name': self.file_name
}

add_to_recent_scan(self.file_name, md5, data['url'])
print("\n[INFO] Performing Static Analysis of Android/iOS Source Code")
return data

def scan_ipa(self):
"""
iOS Binary
"""
md5 = handle_uploaded_file(self.file, '.ipa')
data = {
'hash': md5,
'scan_type': 'ipa',
'file_name': self.file_name,
'url': 'StaticAnalyzer_iOS/?name={}&type=ipa&checksum={}'.format(self.file_name, md5),
'status': 'success'
}

add_to_recent_scan(self.file_name, md5, data['url'])
print("\n[INFO] Performing Static Analysis of iOS IPA")
return data

def scan_appx(self):
"""
"""
md5 = handle_uploaded_file(self.file, '.appx')
data = {
'hash': md5,
'scan_type': 'appx',
'file_name': self.file_name,
'url': 'StaticAnalyzer_Windows/?name={}&type=appx&checksum={}'.format(self.file_name, md5),
'status': 'success'
}

add_to_recent_scan(self.file_name, md5, data['url'])
print("\n[INFO] Performing Static Analysis of Windows APP")
return data
2 changes: 1 addition & 1 deletion MobSF/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
urlpatterns = [
# Examples:
url(r'^$', MobSF.views.index),
url(r'^upload/$', MobSF.views.upload),
url(r'^upload/$', MobSF.views.Upload.as_view),
url(r'^download/', MobSF.views.download),
url(r'^about$', MobSF.views.about),
url(r'^api_docs$', MobSF.views.api_docs),
Expand Down
25 changes: 25 additions & 0 deletions MobSF/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,28 @@ def check_basic_env():
JAVA_DIRECTORY = "/usr/bin/"
''')
os.kill(os.getpid(), signal.SIGTERM)



class FileType(object):
def __init__(self, file_type, file_name_lower):
self.file_type = file_type
self.file_name_lower = file_name_lower

def is_allow_file(self):
"""
return bool
"""
if self.is_apk() or self.is_zip() or self.is_ipa() or self.is_appx():
return True
return False

def is_apk(self):
return (self.file_type in settings.APK_MIME) and self.file_name_lower.endswith('.apk')

def is_zip(self):
return (self.file_type in settings.ZIP_MIME) and self.file_name_lower.endswith('.zip')
def is_ipa(self):
return (self.file_type in settings.IPA_MIME) and self.file_name_lower.endswith('.ipa')
def is_appx(self):
return (self.file_type in settings.APPX_MIME) and self.file_name_lower.endswith('.appx')
Loading

0 comments on commit 5119d43

Please sign in to comment.