mirror of
https://github.com/MobSF/Mobile-Security-Framework-MobSF.git
synced 2026-10-12 02:06:59 +00:00
Standard API, Cert Analysis QA, URL Schemes, ATS Analysis QA, Removed Dupplicate Code
This commit is contained in:
@@ -4,7 +4,9 @@
|
||||
.dockerignore
|
||||
.sonarcloud.properties
|
||||
.travis.yml
|
||||
.pyup.yml
|
||||
tox.ini
|
||||
db.sqlite3
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
setup.bat
|
||||
|
||||
@@ -90,7 +90,7 @@ def get_screenshots(md5_hash, download_dir):
|
||||
expact_imgs.append(img)
|
||||
else:
|
||||
imgs.append(img)
|
||||
exported_act = python_list(sadb[0].EXPORTED_ACT)
|
||||
exported_act = python_list(sadb[0].EXPORTED_ACTIVITIES)
|
||||
act_desc = python_list(sadb[0].ACTIVITIES)
|
||||
if act_imgs:
|
||||
if len(act_imgs) == len(act_desc):
|
||||
|
||||
@@ -34,7 +34,7 @@ def dynamic_analysis(request):
|
||||
"""Android Dynamic Analysis Entry point."""
|
||||
try:
|
||||
apks = StaticAnalyzerAndroid.objects.filter(
|
||||
ZIPPED='apk').order_by('-id')
|
||||
APP_TYPE='apk').order_by('-id')
|
||||
try:
|
||||
identifier = get_device()
|
||||
except Exception:
|
||||
|
||||
@@ -237,7 +237,7 @@ class Environment:
|
||||
elif comp == 'libraries':
|
||||
resp = python_list(anddb[0].LIBRARIES)
|
||||
elif comp == 'exported_activities':
|
||||
resp = python_list(anddb[0].EXPORTED_ACT)
|
||||
resp = python_list(anddb[0].EXPORTED_ACTIVITIES)
|
||||
return '\n'.join(resp)
|
||||
|
||||
def get_android_version(self):
|
||||
|
||||
@@ -50,7 +50,7 @@ def activity_tester(request):
|
||||
if test == 'exported':
|
||||
iden = 'Exported '
|
||||
logger.info('Exported activity tester')
|
||||
activities = python_list(static_android_db[0].EXPORTED_ACT)
|
||||
activities = python_list(static_android_db[0].EXPORTED_ACTIVITIES)
|
||||
else:
|
||||
logger.info('Activity tester')
|
||||
activities = python_list(static_android_db[0].ACTIVITIES)
|
||||
|
||||
+2
-1
@@ -12,7 +12,7 @@ from MobSF.views import home
|
||||
from MobSF.views.api import rest_api
|
||||
|
||||
from StaticAnalyzer import tests
|
||||
from StaticAnalyzer.views import shared_func, windows
|
||||
from StaticAnalyzer.views import shared_func
|
||||
from StaticAnalyzer.views.android import (
|
||||
find,
|
||||
generate_downloads,
|
||||
@@ -21,6 +21,7 @@ from StaticAnalyzer.views.android import (
|
||||
smali,
|
||||
view_source,
|
||||
)
|
||||
from StaticAnalyzer.views.windows import windows
|
||||
from StaticAnalyzer.views.android import static_analyzer as android_sa
|
||||
from StaticAnalyzer.views.ios import static_analyzer as ios_sa
|
||||
from StaticAnalyzer.views.ios import view_source as io_view_source
|
||||
|
||||
@@ -13,7 +13,7 @@ from StaticAnalyzer.views.android.static_analyzer import static_analyzer
|
||||
from StaticAnalyzer.views.ios import view_source as ios_view_source
|
||||
from StaticAnalyzer.views.ios.static_analyzer import static_analyzer_ios
|
||||
from StaticAnalyzer.views.shared_func import pdf
|
||||
from StaticAnalyzer.views.windows import staticanalyzer_windows
|
||||
from StaticAnalyzer.views.windows import windows
|
||||
|
||||
BAD_REQUEST = 400
|
||||
OK = 200
|
||||
@@ -85,7 +85,7 @@ def api_scan(request):
|
||||
response = make_api_response(resp, 200)
|
||||
# APPX
|
||||
elif scan_type == 'appx':
|
||||
resp = staticanalyzer_windows(request, True)
|
||||
resp = windows.staticanalyzer_windows(request, True)
|
||||
if 'error' in resp:
|
||||
response = make_api_response(resp, 500)
|
||||
else:
|
||||
|
||||
+5
-5
@@ -20,8 +20,9 @@ from MobSF.utils import (api_key, is_dir_exists, is_file_exists,
|
||||
from MobSF.views.helpers import FileType
|
||||
from MobSF.views.scanning import Scanning
|
||||
|
||||
from StaticAnalyzer.models import (RecentScansDB, StaticAnalyzerAndroid,
|
||||
StaticAnalyzerIOSZIP, StaticAnalyzerIPA,
|
||||
from StaticAnalyzer.models import (RecentScansDB,
|
||||
StaticAnalyzerAndroid,
|
||||
StaticAnalyzerIOS,
|
||||
StaticAnalyzerWindows)
|
||||
|
||||
LINUX_PLATFORM = ['Darwin', 'Linux']
|
||||
@@ -218,7 +219,7 @@ def recent_scans(request):
|
||||
android = StaticAnalyzerAndroid.objects.all()
|
||||
package_mapping = {}
|
||||
for item in android:
|
||||
package_mapping[item.MD5] = item.PACKAGENAME
|
||||
package_mapping[item.MD5] = item.PACKAGE_NAME
|
||||
for entry in db_obj:
|
||||
if entry['MD5'] in package_mapping.keys():
|
||||
entry['PACKAGE'] = package_mapping[entry['MD5']]
|
||||
@@ -287,8 +288,7 @@ def delete_scan(request, api=False):
|
||||
if scan.exists():
|
||||
RecentScansDB.objects.filter(MD5=md5_hash).delete()
|
||||
StaticAnalyzerAndroid.objects.filter(MD5=md5_hash).delete()
|
||||
StaticAnalyzerIPA.objects.filter(MD5=md5_hash).delete()
|
||||
StaticAnalyzerIOSZIP.objects.filter(MD5=md5_hash).delete()
|
||||
StaticAnalyzerIOS.objects.filter(MD5=md5_hash).delete()
|
||||
StaticAnalyzerWindows.objects.filter(MD5=md5_hash).delete()
|
||||
# Delete Upload Dir Contents
|
||||
app_upload_dir = os.path.join(settings.UPLD_DIR, md5_hash)
|
||||
|
||||
+56
-100
@@ -10,136 +10,92 @@ class RecentScansDB(models.Model):
|
||||
|
||||
|
||||
class StaticAnalyzerAndroid(models.Model):
|
||||
TITLE = models.CharField(max_length=50)
|
||||
APP_NAME = models.CharField(max_length=260)
|
||||
REAL_NAME = models.CharField(max_length=255)
|
||||
FILE_NAME = models.CharField(max_length=260)
|
||||
APP_NAME = models.CharField(max_length=255)
|
||||
APP_TYPE = models.TextField()
|
||||
SIZE = models.CharField(max_length=50)
|
||||
MD5 = models.CharField(max_length=32)
|
||||
SHA1 = models.CharField(max_length=40)
|
||||
SHA256 = models.CharField(max_length=64)
|
||||
PACKAGENAME = models.CharField(max_length=40)
|
||||
MAINACTIVITY = models.CharField(max_length=300)
|
||||
TARGET_SDK = models.CharField(max_length=50)
|
||||
MAX_SDK = models.CharField(max_length=50)
|
||||
MIN_SDK = models.CharField(max_length=50)
|
||||
ANDROVERNAME = models.CharField(max_length=100)
|
||||
ANDROVER = models.CharField(max_length=50)
|
||||
MANIFEST_ANAL = models.TextField()
|
||||
PERMISSIONS = models.TextField()
|
||||
BIN_ANALYSIS = models.TextField()
|
||||
FILES = models.TextField()
|
||||
CERTZ = models.TextField()
|
||||
ICON_HIDDEN = models.BooleanField(default=False)
|
||||
ICON_FOUND = models.BooleanField(default=False)
|
||||
PACKAGE_NAME = models.CharField(max_length=40)
|
||||
MAIN_ACTIVITY = models.CharField(max_length=300)
|
||||
EXPORTED_ACTIVITIES = models.TextField()
|
||||
BROWSABLE_ACTIVITIES = models.TextField()
|
||||
ACTIVITIES = models.TextField()
|
||||
RECEIVERS = models.TextField()
|
||||
PROVIDERS = models.TextField()
|
||||
SERVICES = models.TextField()
|
||||
LIBRARIES = models.TextField()
|
||||
BROWSABLE = models.TextField()
|
||||
CNT_ACT = models.CharField(max_length=50)
|
||||
CNT_PRO = models.CharField(max_length=50)
|
||||
CNT_SER = models.CharField(max_length=50)
|
||||
CNT_BRO = models.CharField(max_length=50)
|
||||
CERT_INFO = models.TextField()
|
||||
ISSUED = models.CharField(max_length=10)
|
||||
SHA256DIGEST = models.BooleanField(default=False)
|
||||
API = models.TextField()
|
||||
DANG = models.TextField()
|
||||
TARGET_SDK = models.CharField(max_length=50)
|
||||
MAX_SDK = models.CharField(max_length=50)
|
||||
MIN_SDK = models.CharField(max_length=50)
|
||||
VERSION_NAME = models.CharField(max_length=100)
|
||||
VERSION_CODE = models.CharField(max_length=50)
|
||||
ICON_HIDDEN = models.BooleanField(default=False)
|
||||
ICON_FOUND = models.BooleanField(default=False)
|
||||
PERMISSIONS = models.TextField()
|
||||
CERTIFICATE_ANALYSIS = models.TextField()
|
||||
MANIFEST_ANALYSIS = models.TextField()
|
||||
BINARY_ANALYSIS = models.TextField()
|
||||
FILE_ANALYSIS = models.TextField()
|
||||
ANDROID_API = models.TextField()
|
||||
CODE_ANALYSIS = models.TextField()
|
||||
URLS = models.TextField()
|
||||
DOMAINS = models.TextField()
|
||||
EMAILS = models.TextField()
|
||||
STRINGS = models.TextField()
|
||||
ZIPPED = models.TextField()
|
||||
MANI = models.TextField()
|
||||
EXPORTED_ACT = models.TextField()
|
||||
E_ACT = models.CharField(max_length=50)
|
||||
E_SER = models.CharField(max_length=50)
|
||||
E_BRO = models.CharField(max_length=50)
|
||||
E_CNT = models.CharField(max_length=50)
|
||||
APK_ID = models.TextField()
|
||||
PLAY_DETAILS = models.TextField(default={})
|
||||
FIREBASE = models.TextField(default=[])
|
||||
FIREBASE_URLS = models.TextField(default=[])
|
||||
FILES = models.TextField()
|
||||
EXPORTED_COUNT = models.TextField(default={})
|
||||
APKID = models.TextField(default={})
|
||||
TRACKERS = models.TextField(default={})
|
||||
PLAYSTORE_DETAILS = models.TextField(default={})
|
||||
|
||||
|
||||
class StaticAnalyzerIPA(models.Model):
|
||||
TITLE = models.CharField(max_length=50)
|
||||
class StaticAnalyzerIOS(models.Model):
|
||||
FILE_NAME = models.CharField(max_length=255)
|
||||
APP_NAME = models.CharField(max_length=255)
|
||||
APP_TYPE = models.CharField(max_length=20, default='')
|
||||
SIZE = models.CharField(max_length=50)
|
||||
MD5 = models.CharField(max_length=32)
|
||||
SHA1 = models.CharField(max_length=40)
|
||||
SHA256 = models.CharField(max_length=64)
|
||||
INFOPLIST = models.TextField()
|
||||
MACHOINFO = models.TextField(default={})
|
||||
# bundle_id
|
||||
BINNAME = models.CharField(max_length=160)
|
||||
IDF = models.TextField()
|
||||
BUILD = models.TextField()
|
||||
VERSION = models.CharField(max_length=100)
|
||||
SDK = models.CharField(max_length=50)
|
||||
PLTFM = models.CharField(max_length=50)
|
||||
MINX = models.CharField(max_length=50)
|
||||
BIN_ANAL = models.TextField()
|
||||
LIBS = models.TextField()
|
||||
FILES = models.TextField()
|
||||
SFILESX = models.TextField()
|
||||
STRINGS = models.TextField()
|
||||
PERMISSIONS = models.TextField()
|
||||
INSECCON = models.TextField()
|
||||
BUNDLE_NAME = models.CharField(max_length=20)
|
||||
BUNDLE_URL_TYPES = models.TextField()
|
||||
APP_VERSION = models.CharField(max_length=100)
|
||||
SDK_NAME = models.CharField(max_length=50)
|
||||
PLATFORM = models.CharField(max_length=50)
|
||||
MIN_OS_VERSION = models.CharField(max_length=50)
|
||||
BUNDLE_ID = models.TextField()
|
||||
BUNDLE_URL_TYPES = models.TextField(default=[])
|
||||
BUNDLE_SUPPORTED_PLATFORMS = models.CharField(max_length=50)
|
||||
BUNDLE_LOCALIZATIONS = models.TextField()
|
||||
BINTYPE = models.CharField(max_length=20, default='')
|
||||
INFO_PLIST = models.TextField()
|
||||
MACHO_INFO = models.TextField(default={})
|
||||
PERMISSIONS = models.TextField(default=[])
|
||||
ATS_ANALYSIS = models.TextField(default=[])
|
||||
BINARY_ANALYSIS = models.TextField(default=[])
|
||||
IOS_API = models.TextField(default={})
|
||||
CODE_ANALYSIS = models.TextField(default={})
|
||||
FILE_ANALYSIS = models.TextField(default=[])
|
||||
LIBRARIES = models.TextField(default=[])
|
||||
FILES = models.TextField(default=[])
|
||||
URLS = models.TextField(default=[])
|
||||
DOMAINS = models.TextField(default={})
|
||||
EMAILS = models.TextField(default=[])
|
||||
STRINGS = models.TextField(default=[])
|
||||
FIREBASE_URLS = models.TextField(default=[])
|
||||
APPSTORE_DETAILS = models.TextField(default={})
|
||||
|
||||
|
||||
class StaticAnalyzerIOSZIP(models.Model):
|
||||
TITLE = models.CharField(max_length=50)
|
||||
FILE_NAME = models.CharField(max_length=260)
|
||||
SIZE = models.CharField(max_length=50)
|
||||
MD5 = models.CharField(max_length=32)
|
||||
SHA1 = models.CharField(max_length=40)
|
||||
SHA256 = models.CharField(max_length=64)
|
||||
INFOPLIST = models.TextField()
|
||||
BINNAME = models.CharField(max_length=160)
|
||||
IDF = models.TextField()
|
||||
BUILD = models.TextField()
|
||||
VERSION = models.CharField(max_length=100)
|
||||
SDK = models.CharField(max_length=50)
|
||||
PLTFM = models.CharField(max_length=50)
|
||||
MINX = models.CharField(max_length=50)
|
||||
BIN_ANAL = models.TextField()
|
||||
LIBS = models.TextField()
|
||||
FILES = models.TextField()
|
||||
SFILESX = models.TextField()
|
||||
API = models.TextField()
|
||||
CODEANAL = models.TextField()
|
||||
URLnFile = models.TextField()
|
||||
DOMAINS = models.TextField()
|
||||
EmailnFile = models.TextField()
|
||||
PERMISSIONS = models.TextField()
|
||||
INSECCON = models.TextField()
|
||||
BUNDLE_NAME = models.CharField(max_length=20)
|
||||
BUNDLE_URL_TYPES = models.TextField()
|
||||
BUNDLE_SUPPORTED_PLATFORMS = models.CharField(max_length=50)
|
||||
BUNDLE_LOCALIZATIONS = models.TextField()
|
||||
APPSTORE_DETAILS = models.TextField(default={})
|
||||
FIREBASE = models.TextField(default=[])
|
||||
|
||||
|
||||
class StaticAnalyzerWindows(models.Model):
|
||||
TITLE = models.CharField(max_length=260)
|
||||
FILE_NAME = models.CharField(max_length=260)
|
||||
APP_NAME = models.CharField(max_length=260)
|
||||
PUB_NAME = models.TextField()
|
||||
PUBLISHER_NAME = models.TextField()
|
||||
SIZE = models.CharField(max_length=50)
|
||||
MD5 = models.CharField(max_length=32)
|
||||
SHA1 = models.CharField(max_length=40)
|
||||
SHA256 = models.CharField(max_length=64)
|
||||
BINNAME = models.CharField(max_length=260)
|
||||
VERSION = models.TextField()
|
||||
ARCH = models.TextField()
|
||||
APP_VERSION = models.TextField()
|
||||
ARCHITECTURE = models.TextField()
|
||||
COMPILER_VERSION = models.TextField()
|
||||
VISUAL_STUDIO_VERSION = models.TextField()
|
||||
VISUAL_STUDIO_EDITION = models.TextField()
|
||||
@@ -150,5 +106,5 @@ class StaticAnalyzerWindows(models.Model):
|
||||
TARGET_RUN = models.TextField()
|
||||
FILES = models.TextField()
|
||||
STRINGS = models.TextField()
|
||||
BIN_AN_RESULTS = models.TextField()
|
||||
BIN_AN_WARNINGS = models.TextField()
|
||||
BINARY_ANALYSIS = models.TextField()
|
||||
BINARY_WARNINGS = models.TextField()
|
||||
|
||||
@@ -47,8 +47,9 @@ def cert_info(app_dir, app_file):
|
||||
"""Return certificate information."""
|
||||
try:
|
||||
logger.info('Reading Code Signing Certificate')
|
||||
issued = ''
|
||||
status = ''
|
||||
manidat = ''
|
||||
cert_info = ''
|
||||
certlist = []
|
||||
cert_path = os.path.join(app_dir, 'META-INF/')
|
||||
|
||||
@@ -103,25 +104,36 @@ def cert_info(app_dir, app_file):
|
||||
certlist.append('Bit Size: {}'.format(x509_public_key.bit_size))
|
||||
certlist.append('Fingerprint: {}'.format(
|
||||
binascii.hexlify(x509_public_key.fingerprint).decode('utf-8')))
|
||||
certlist = '\n'.join(certlist)
|
||||
if a.is_signed():
|
||||
issued = 'good'
|
||||
else:
|
||||
issued = 'missing'
|
||||
if re.findall(r'CN=Android Debug', certlist):
|
||||
issued = 'bad'
|
||||
if re.findall(r'Hash Algorithm: sha1', certlist):
|
||||
issued = 'bad hash'
|
||||
cert_info = '\n'.join(certlist)
|
||||
if 'MANIFEST.MF' in files:
|
||||
manifestfile = os.path.join(cert_path, 'MANIFEST.MF')
|
||||
if manifestfile:
|
||||
with open(manifestfile, 'r', encoding='utf-8') as manifile:
|
||||
manidat = manifile.read()
|
||||
sha256_digest = bool(re.findall(r'SHA-256-Digest', manidat))
|
||||
if a.is_signed():
|
||||
status = 'good'
|
||||
desc = 'Certificate looks good.'
|
||||
else:
|
||||
status = 'missing'
|
||||
desc = 'Certificate is not found'
|
||||
if re.findall(r'CN=Android Debug', cert_info):
|
||||
status = 'bad'
|
||||
desc = ('This is a debug certificate. Production application'
|
||||
' must not be shipped with a debug certificate.')
|
||||
if re.findall(r'Hash Algorithm: sha1', cert_info):
|
||||
status = 'bad'
|
||||
desc = ('The app is signed with SHA1withRSA. SHA1 hash algorithm'
|
||||
' is known to have collision issues.')
|
||||
if sha256_digest:
|
||||
status = 'warning'
|
||||
desc += ('The manifest indicates SHA256withRSA is in use. '
|
||||
'Please verify this manually.')
|
||||
|
||||
cert_dic = {
|
||||
'cert_info': certlist,
|
||||
'issued': issued,
|
||||
'sha256Digest': sha256_digest,
|
||||
'certificate_info': cert_info,
|
||||
'certificate_status': status,
|
||||
'description': desc,
|
||||
}
|
||||
return cert_dic
|
||||
except Exception:
|
||||
|
||||
@@ -18,59 +18,51 @@ def get_context_from_db_entry(db_entry: QuerySet) -> dict:
|
||||
"""Return the context for APK/ZIP from DB."""
|
||||
try:
|
||||
logger.info('Analysis is already Done. Fetching data from the DB...')
|
||||
|
||||
context = {
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': db_entry[0].TITLE,
|
||||
'name': db_entry[0].APP_NAME,
|
||||
'real_name': db_entry[0].REAL_NAME,
|
||||
'title': 'Static Analysis',
|
||||
'file_name': db_entry[0].FILE_NAME,
|
||||
'app_name': db_entry[0].APP_NAME,
|
||||
'app_type': db_entry[0].APP_TYPE,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'packagename': db_entry[0].PACKAGENAME,
|
||||
'mainactivity': db_entry[0].MAINACTIVITY,
|
||||
'targetsdk': db_entry[0].TARGET_SDK,
|
||||
'maxsdk': db_entry[0].MAX_SDK,
|
||||
'minsdk': db_entry[0].MIN_SDK,
|
||||
'androvername': db_entry[0].ANDROVERNAME,
|
||||
'androver': db_entry[0].ANDROVER,
|
||||
'manifest': python_list(db_entry[0].MANIFEST_ANAL),
|
||||
'permissions': python_dict(db_entry[0].PERMISSIONS),
|
||||
'binary_analysis': python_list(db_entry[0].BIN_ANALYSIS),
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'certz': python_list(db_entry[0].CERTZ),
|
||||
'icon_hidden': db_entry[0].ICON_HIDDEN,
|
||||
'icon_found': db_entry[0].ICON_FOUND,
|
||||
'package_name': db_entry[0].PACKAGE_NAME,
|
||||
'main_activity': db_entry[0].MAIN_ACTIVITY,
|
||||
'exported_activities': db_entry[0].EXPORTED_ACTIVITIES,
|
||||
'browsable_activities': python_dict(
|
||||
db_entry[0].BROWSABLE_ACTIVITIES),
|
||||
'activities': python_list(db_entry[0].ACTIVITIES),
|
||||
'receivers': python_list(db_entry[0].RECEIVERS),
|
||||
'providers': python_list(db_entry[0].PROVIDERS),
|
||||
'services': python_list(db_entry[0].SERVICES),
|
||||
'libraries': python_list(db_entry[0].LIBRARIES),
|
||||
'browsable_activities': python_dict(db_entry[0].BROWSABLE),
|
||||
'act_count': db_entry[0].CNT_ACT,
|
||||
'prov_count': db_entry[0].CNT_PRO,
|
||||
'serv_count': db_entry[0].CNT_SER,
|
||||
'bro_count': db_entry[0].CNT_BRO,
|
||||
'certinfo': db_entry[0].CERT_INFO,
|
||||
'issued': db_entry[0].ISSUED,
|
||||
'sha256Digest': db_entry[0].SHA256DIGEST,
|
||||
'api': python_dict(db_entry[0].API),
|
||||
'findings': python_dict(db_entry[0].DANG),
|
||||
'target_sdk': db_entry[0].TARGET_SDK,
|
||||
'max_sdk': db_entry[0].MAX_SDK,
|
||||
'min_sdk': db_entry[0].MIN_SDK,
|
||||
'version_name': db_entry[0].VERSION_NAME,
|
||||
'version_code': db_entry[0].VERSION_CODE,
|
||||
'icon_hidden': db_entry[0].ICON_HIDDEN,
|
||||
'icon_found': db_entry[0].ICON_FOUND,
|
||||
'permissions': python_dict(db_entry[0].PERMISSIONS),
|
||||
'certificate_analysis': python_dict(
|
||||
db_entry[0].CERTIFICATE_ANALYSIS),
|
||||
'manifest_analysis': python_list(db_entry[0].MANIFEST_ANALYSIS),
|
||||
'binary_analysis': python_list(db_entry[0].BINARY_ANALYSIS),
|
||||
'file_analysis': python_list(db_entry[0].FILE_ANALYSIS),
|
||||
'android_api': python_dict(db_entry[0].ANDROID_API),
|
||||
'code_analysis': python_dict(db_entry[0].CODE_ANALYSIS),
|
||||
'urls': python_list(db_entry[0].URLS),
|
||||
'domains': python_dict(db_entry[0].DOMAINS),
|
||||
'emails': python_list(db_entry[0].EMAILS),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'zipped': db_entry[0].ZIPPED,
|
||||
'mani': db_entry[0].MANI,
|
||||
'e_act': db_entry[0].E_ACT,
|
||||
'e_ser': db_entry[0].E_SER,
|
||||
'e_bro': db_entry[0].E_BRO,
|
||||
'e_cnt': db_entry[0].E_CNT,
|
||||
'apkid': python_dict(db_entry[0].APK_ID),
|
||||
'play_details': python_dict(db_entry[0].PLAY_DETAILS),
|
||||
'firebase': python_list(db_entry[0].FIREBASE),
|
||||
'firebase_urls': python_list(db_entry[0].FIREBASE_URLS),
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'exported_count': python_dict(db_entry[0].EXPORTED_COUNT),
|
||||
'apkid': python_dict(db_entry[0].APKID),
|
||||
'trackers': python_dict(db_entry[0].TRACKERS),
|
||||
'playstore_details': python_dict(db_entry[0].PLAYSTORE_DETAILS),
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
@@ -88,194 +80,111 @@ def get_context_from_analysis(app_dic,
|
||||
"""Get the context for APK/ZIP from analysis results."""
|
||||
try:
|
||||
context = {
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': 'Static Analysis',
|
||||
'name': app_dic['app_name'],
|
||||
'real_name': app_dic['real_name'],
|
||||
'version': settings.MOBSF_VER,
|
||||
'file_name': app_dic['app_name'],
|
||||
'app_name': app_dic['real_name'],
|
||||
'app_type': app_dic['zipped'],
|
||||
'size': app_dic['size'],
|
||||
'md5': app_dic['md5'],
|
||||
'sha1': app_dic['sha1'],
|
||||
'sha256': app_dic['sha256'],
|
||||
'packagename': man_data_dic['packagename'],
|
||||
'mainactivity': man_data_dic['mainactivity'],
|
||||
'targetsdk': man_data_dic['target_sdk'],
|
||||
'maxsdk': man_data_dic['max_sdk'],
|
||||
'minsdk': man_data_dic['min_sdk'],
|
||||
'androvername': man_data_dic['androvername'],
|
||||
'androver': man_data_dic['androver'],
|
||||
'manifest': man_an_dic['manifest_anal'],
|
||||
'permissions': man_an_dic['permissons'],
|
||||
'binary_analysis': bin_anal,
|
||||
'files': app_dic['files'],
|
||||
'certz': app_dic['certz'],
|
||||
'icon_hidden': app_dic['icon_hidden'],
|
||||
'icon_found': app_dic['icon_found'],
|
||||
'package_name': man_data_dic['packagename'],
|
||||
'main_activity': man_data_dic['mainactivity'],
|
||||
'exported_activities': man_an_dic['exported_act'],
|
||||
'browsable_activities': man_an_dic['browsable_activities'],
|
||||
'activities': man_data_dic['activities'],
|
||||
'receivers': man_data_dic['receivers'],
|
||||
'providers': man_data_dic['providers'],
|
||||
'services': man_data_dic['services'],
|
||||
'libraries': man_data_dic['libraries'],
|
||||
'browsable_activities': man_an_dic['browsable_activities'],
|
||||
'act_count': man_an_dic['cnt_act'],
|
||||
'prov_count': man_an_dic['cnt_pro'],
|
||||
'serv_count': man_an_dic['cnt_ser'],
|
||||
'bro_count': man_an_dic['cnt_bro'],
|
||||
'certinfo': cert_dic['cert_info'],
|
||||
'issued': cert_dic['issued'],
|
||||
'sha256Digest': cert_dic['sha256Digest'],
|
||||
'api': code_an_dic['api'],
|
||||
'findings': code_an_dic['findings'],
|
||||
'target_sdk': man_data_dic['target_sdk'],
|
||||
'max_sdk': man_data_dic['max_sdk'],
|
||||
'min_sdk': man_data_dic['min_sdk'],
|
||||
'version_name': man_data_dic['androvername'],
|
||||
'version_code': man_data_dic['androver'],
|
||||
'icon_hidden': app_dic['icon_hidden'],
|
||||
'icon_found': app_dic['icon_found'],
|
||||
'certificate_analysis': cert_dic,
|
||||
'permissions': man_an_dic['permissons'],
|
||||
'manifest_analysis': man_an_dic['manifest_anal'],
|
||||
'binary_analysis': bin_anal,
|
||||
'file_analysis': app_dic['certz'],
|
||||
'android_api': code_an_dic['api'],
|
||||
'code_analysis': code_an_dic['findings'],
|
||||
'urls': code_an_dic['urls'],
|
||||
'domains': code_an_dic['domains'],
|
||||
'emails': code_an_dic['emails'],
|
||||
'strings': app_dic['strings'],
|
||||
'zipped': app_dic['zipped'],
|
||||
'mani': app_dic['mani'],
|
||||
'e_act': man_an_dic['exported_cnt']['act'],
|
||||
'e_ser': man_an_dic['exported_cnt']['ser'],
|
||||
'e_bro': man_an_dic['exported_cnt']['bro'],
|
||||
'e_cnt': man_an_dic['exported_cnt']['cnt'],
|
||||
'firebase_urls': code_an_dic['firebase'],
|
||||
'files': app_dic['files'],
|
||||
'exported_count': man_an_dic['exported_cnt'],
|
||||
'apkid': apk_id,
|
||||
'play_details': app_dic['playstore'],
|
||||
'firebase': code_an_dic['firebase'],
|
||||
'trackers': trackers,
|
||||
'playstore_details': app_dic['playstore'],
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Rendering to Template')
|
||||
|
||||
|
||||
def update_db_entry(app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
code_an_dic,
|
||||
cert_dic,
|
||||
bin_anal,
|
||||
apk_id,
|
||||
trackers) -> None:
|
||||
"""Update an APK/ZIP DB entry."""
|
||||
def save_or_update(update_type,
|
||||
app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
code_an_dic,
|
||||
cert_dic,
|
||||
bin_anal,
|
||||
apk_id,
|
||||
trackers) -> None:
|
||||
"""Save/Update an APK/ZIP DB entry."""
|
||||
try:
|
||||
# pylint: disable=E1101
|
||||
StaticAnalyzerAndroid.objects.filter(MD5=app_dic['md5']).update(
|
||||
TITLE='Static Analysis',
|
||||
APP_NAME=app_dic['app_name'],
|
||||
REAL_NAME=app_dic['real_name'],
|
||||
SIZE=app_dic['size'],
|
||||
MD5=app_dic['md5'],
|
||||
SHA1=app_dic['sha1'],
|
||||
SHA256=app_dic['sha256'],
|
||||
PACKAGENAME=man_data_dic['packagename'],
|
||||
MAINACTIVITY=man_data_dic['mainactivity'],
|
||||
TARGET_SDK=man_data_dic['target_sdk'],
|
||||
MAX_SDK=man_data_dic['max_sdk'],
|
||||
MIN_SDK=man_data_dic['min_sdk'],
|
||||
ANDROVERNAME=man_data_dic['androvername'],
|
||||
ANDROVER=man_data_dic['androver'],
|
||||
MANIFEST_ANAL=man_an_dic['manifest_anal'],
|
||||
PERMISSIONS=man_an_dic['permissons'],
|
||||
BIN_ANALYSIS=bin_anal,
|
||||
FILES=app_dic['files'],
|
||||
CERTZ=app_dic['certz'],
|
||||
ICON_HIDDEN=app_dic['icon_hidden'],
|
||||
ICON_FOUND=app_dic['icon_found'],
|
||||
ACTIVITIES=man_data_dic['activities'],
|
||||
RECEIVERS=man_data_dic['receivers'],
|
||||
PROVIDERS=man_data_dic['providers'],
|
||||
SERVICES=man_data_dic['services'],
|
||||
LIBRARIES=man_data_dic['libraries'],
|
||||
BROWSABLE=man_an_dic['browsable_activities'],
|
||||
CNT_ACT=man_an_dic['cnt_act'],
|
||||
CNT_PRO=man_an_dic['cnt_pro'],
|
||||
CNT_SER=man_an_dic['cnt_ser'],
|
||||
CNT_BRO=man_an_dic['cnt_bro'],
|
||||
CERT_INFO=cert_dic['cert_info'],
|
||||
ISSUED=cert_dic['issued'],
|
||||
SHA256DIGEST=cert_dic['sha256Digest'],
|
||||
API=code_an_dic['api'],
|
||||
DANG=code_an_dic['findings'],
|
||||
URLS=code_an_dic['urls'],
|
||||
DOMAINS=code_an_dic['domains'],
|
||||
EMAILS=code_an_dic['emails'],
|
||||
STRINGS=app_dic['strings'],
|
||||
ZIPPED=app_dic['zipped'],
|
||||
MANI=app_dic['mani'],
|
||||
EXPORTED_ACT=man_an_dic['exported_act'],
|
||||
E_ACT=man_an_dic['exported_cnt']['act'],
|
||||
E_SER=man_an_dic['exported_cnt']['ser'],
|
||||
E_BRO=man_an_dic['exported_cnt']['bro'],
|
||||
E_CNT=man_an_dic['exported_cnt']['cnt'],
|
||||
APK_ID=apk_id,
|
||||
PLAY_DETAILS=app_dic['playstore'],
|
||||
FIREBASE=code_an_dic['firebase'],
|
||||
TRACKERS=trackers,
|
||||
)
|
||||
values = {
|
||||
'FILE_NAME': app_dic['app_name'],
|
||||
'APP_NAME': app_dic['real_name'],
|
||||
'APP_TYPE': app_dic['zipped'],
|
||||
'SIZE': app_dic['size'],
|
||||
'MD5': app_dic['md5'],
|
||||
'SHA1': app_dic['sha1'],
|
||||
'SHA256': app_dic['sha256'],
|
||||
'PACKAGE_NAME': man_data_dic['packagename'],
|
||||
'MAIN_ACTIVITY': man_data_dic['mainactivity'],
|
||||
'EXPORTED_ACTIVITIES': man_an_dic['exported_act'],
|
||||
'BROWSABLE_ACTIVITIES': man_an_dic['browsable_activities'],
|
||||
'ACTIVITIES': man_data_dic['activities'],
|
||||
'RECEIVERS': man_data_dic['receivers'],
|
||||
'PROVIDERS': man_data_dic['providers'],
|
||||
'SERVICES': man_data_dic['services'],
|
||||
'LIBRARIES': man_data_dic['libraries'],
|
||||
'TARGET_SDK': man_data_dic['target_sdk'],
|
||||
'MAX_SDK': man_data_dic['max_sdk'],
|
||||
'MIN_SDK': man_data_dic['min_sdk'],
|
||||
'VERSION_NAME': man_data_dic['androvername'],
|
||||
'VERSION_CODE': man_data_dic['androver'],
|
||||
'ICON_HIDDEN': app_dic['icon_hidden'],
|
||||
'ICON_FOUND': app_dic['icon_found'],
|
||||
'CERTIFICATE_ANALYSIS': cert_dic,
|
||||
'PERMISSIONS': man_an_dic['permissons'],
|
||||
'MANIFEST_ANALYSIS': man_an_dic['manifest_anal'],
|
||||
'BINARY_ANALYSIS': bin_anal,
|
||||
'FILE_ANALYSIS': app_dic['certz'],
|
||||
'ANDROID_API': code_an_dic['api'],
|
||||
'CODE_ANALYSIS': code_an_dic['findings'],
|
||||
'URLS': code_an_dic['urls'],
|
||||
'DOMAINS': code_an_dic['domains'],
|
||||
'EMAILS': code_an_dic['emails'],
|
||||
'STRINGS': app_dic['strings'],
|
||||
'FIREBASE_URLS': code_an_dic['firebase'],
|
||||
'FILES': app_dic['files'],
|
||||
'EXPORTED_COUNT': man_an_dic['exported_cnt'],
|
||||
'APKID': apk_id,
|
||||
'TRACKERS': trackers,
|
||||
'PLAYSTORE_DETAILS': app_dic['playstore'],
|
||||
}
|
||||
if update_type == 'save':
|
||||
StaticAnalyzerAndroid.objects.create(**values)
|
||||
else:
|
||||
StaticAnalyzerAndroid.objects.filter(
|
||||
MD5=app_dic['md5']).update(**values)
|
||||
except Exception:
|
||||
logger.exception('Updating DB')
|
||||
|
||||
|
||||
def create_db_entry(app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
code_an_dic,
|
||||
cert_dic,
|
||||
bin_anal,
|
||||
apk_id,
|
||||
trackers) -> None:
|
||||
"""Create a new DB-Entry for APK/ZIP."""
|
||||
try:
|
||||
static_db = StaticAnalyzerAndroid(
|
||||
TITLE='Static Analysis',
|
||||
APP_NAME=app_dic['app_name'],
|
||||
REAL_NAME=app_dic['real_name'],
|
||||
SIZE=app_dic['size'],
|
||||
MD5=app_dic['md5'],
|
||||
SHA1=app_dic['sha1'],
|
||||
SHA256=app_dic['sha256'],
|
||||
PACKAGENAME=man_data_dic['packagename'],
|
||||
MAINACTIVITY=man_data_dic['mainactivity'],
|
||||
TARGET_SDK=man_data_dic['target_sdk'],
|
||||
MAX_SDK=man_data_dic['max_sdk'],
|
||||
MIN_SDK=man_data_dic['min_sdk'],
|
||||
ANDROVERNAME=man_data_dic['androvername'],
|
||||
ANDROVER=man_data_dic['androver'],
|
||||
MANIFEST_ANAL=man_an_dic['manifest_anal'],
|
||||
PERMISSIONS=man_an_dic['permissons'],
|
||||
BIN_ANALYSIS=bin_anal,
|
||||
FILES=app_dic['files'],
|
||||
CERTZ=app_dic['certz'],
|
||||
ICON_HIDDEN=app_dic['icon_hidden'],
|
||||
ICON_FOUND=app_dic['icon_found'],
|
||||
ACTIVITIES=man_data_dic['activities'],
|
||||
RECEIVERS=man_data_dic['receivers'],
|
||||
PROVIDERS=man_data_dic['providers'],
|
||||
SERVICES=man_data_dic['services'],
|
||||
LIBRARIES=man_data_dic['libraries'],
|
||||
BROWSABLE=man_an_dic['browsable_activities'],
|
||||
CNT_ACT=man_an_dic['cnt_act'],
|
||||
CNT_PRO=man_an_dic['cnt_pro'],
|
||||
CNT_SER=man_an_dic['cnt_ser'],
|
||||
CNT_BRO=man_an_dic['cnt_bro'],
|
||||
CERT_INFO=cert_dic['cert_info'],
|
||||
ISSUED=cert_dic['issued'],
|
||||
SHA256DIGEST=cert_dic['sha256Digest'],
|
||||
API=code_an_dic['api'],
|
||||
DANG=code_an_dic['findings'],
|
||||
URLS=code_an_dic['urls'],
|
||||
DOMAINS=code_an_dic['domains'],
|
||||
EMAILS=code_an_dic['emails'],
|
||||
STRINGS=app_dic['strings'],
|
||||
ZIPPED=app_dic['zipped'],
|
||||
MANI=app_dic['mani'],
|
||||
EXPORTED_ACT=man_an_dic['exported_act'],
|
||||
E_ACT=man_an_dic['exported_cnt']['act'],
|
||||
E_SER=man_an_dic['exported_cnt']['ser'],
|
||||
E_BRO=man_an_dic['exported_cnt']['bro'],
|
||||
E_CNT=man_an_dic['exported_cnt']['cnt'],
|
||||
APK_ID=apk_id,
|
||||
PLAY_DETAILS=app_dic['playstore'],
|
||||
FIREBASE=code_an_dic['firebase'],
|
||||
TRACKERS=trackers,
|
||||
)
|
||||
static_db.save()
|
||||
except Exception:
|
||||
logger.exception('Saving to DB')
|
||||
|
||||
@@ -796,16 +796,18 @@ def manifest_analysis(mfxml, man_data_dic):
|
||||
'description': permisson[2],
|
||||
})
|
||||
# Prepare return dict
|
||||
exported_comp = {
|
||||
'exported_activities': exp_count['act'],
|
||||
'exported_services': exp_count['ser'],
|
||||
'exported_receivers': exp_count['bro'],
|
||||
'exported_providers': exp_count['cnt'],
|
||||
}
|
||||
man_an_dic = {
|
||||
'manifest_anal': ret_value,
|
||||
'exported_act': exported,
|
||||
'exported_cnt': exp_count,
|
||||
'exported_cnt': exported_comp,
|
||||
'browsable_activities': browsable_activities,
|
||||
'permissons': permissons,
|
||||
'cnt_act': len(man_data_dic['activities']),
|
||||
'cnt_pro': len(man_data_dic['providers']),
|
||||
'cnt_ser': len(man_data_dic['services']),
|
||||
'cnt_bro': len(man_data_dic['receivers']),
|
||||
'icon_hidden': icon_hidden,
|
||||
}
|
||||
return man_an_dic
|
||||
|
||||
@@ -27,8 +27,7 @@ from StaticAnalyzer.views.android.cert_analysis import (
|
||||
from StaticAnalyzer.views.android.code_analysis import code_analysis
|
||||
from StaticAnalyzer.views.android.converter import (apk_2_java, dex_2_smali)
|
||||
from StaticAnalyzer.views.android.db_interaction import (
|
||||
create_db_entry, get_context_from_analysis, get_context_from_db_entry,
|
||||
update_db_entry)
|
||||
get_context_from_analysis, get_context_from_db_entry, save_or_update)
|
||||
from StaticAnalyzer.views.android.icon_analysis import (find_icon_path_zip,
|
||||
get_icon)
|
||||
from StaticAnalyzer.views.android.manifest_analysis import (get_manifest,
|
||||
@@ -228,7 +227,8 @@ def static_analyzer(request, api=False):
|
||||
# SAVE TO DB
|
||||
if rescan == '1':
|
||||
logger.info('Updating Database...')
|
||||
update_db_entry(
|
||||
save_or_update(
|
||||
'update',
|
||||
app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
@@ -241,7 +241,8 @@ def static_analyzer(request, api=False):
|
||||
update_scan_timestamp(app_dic['md5'])
|
||||
elif rescan == '0':
|
||||
logger.info('Saving to Database')
|
||||
create_db_entry(
|
||||
save_or_update(
|
||||
'save',
|
||||
app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
@@ -264,14 +265,14 @@ def static_analyzer(request, api=False):
|
||||
tracker_res,
|
||||
)
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['findings'])
|
||||
'security_score'] = score(context['code_analysis'])
|
||||
context['dynamic_analysis_done'] = is_file_exists(
|
||||
os.path.join(app_dic['app_dir'], 'logcat.txt'))
|
||||
|
||||
context['VT_RESULT'] = None
|
||||
context['virus_total'] = None
|
||||
if settings.VT_ENABLED:
|
||||
vt = VirusTotal.VirusTotal()
|
||||
context['VT_RESULT'] = vt.get_result(
|
||||
context['virus_total'] = vt.get_result(
|
||||
os.path.join(app_dic['app_dir'],
|
||||
app_dic['md5']) + '.apk',
|
||||
app_dic['md5'])
|
||||
@@ -283,10 +284,11 @@ def static_analyzer(request, api=False):
|
||||
elif typ == 'zip':
|
||||
# Check if in DB
|
||||
# pylint: disable=E1101
|
||||
cert_dic = {}
|
||||
cert_dic['cert_info'] = ''
|
||||
cert_dic['issued'] = ''
|
||||
cert_dic['sha256Digest'] = False
|
||||
cert_dic = {
|
||||
'certificate_info': '',
|
||||
'certificate_status': '',
|
||||
'description': '',
|
||||
}
|
||||
bin_an_buff = []
|
||||
app_dic['strings'] = ''
|
||||
app_dic['zipped'] = ''
|
||||
@@ -404,7 +406,8 @@ def static_analyzer(request, api=False):
|
||||
# SAVE TO DB
|
||||
if rescan == '1':
|
||||
logger.info('Updating Database...')
|
||||
update_db_entry(
|
||||
save_or_update(
|
||||
'update',
|
||||
app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
@@ -417,7 +420,8 @@ def static_analyzer(request, api=False):
|
||||
update_scan_timestamp(app_dic['md5'])
|
||||
elif rescan == '0':
|
||||
logger.info('Saving to Database')
|
||||
create_db_entry(
|
||||
save_or_update(
|
||||
'save',
|
||||
app_dic,
|
||||
man_data_dic,
|
||||
man_an_dic,
|
||||
@@ -455,7 +459,7 @@ def static_analyzer(request, api=False):
|
||||
template = 'general/zip.html'
|
||||
return render(request, template, ctx)
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['findings'])
|
||||
'security_score'] = score(context['code_analysis'])
|
||||
template = 'static_analysis/android_source_analysis.html'
|
||||
if api:
|
||||
return context
|
||||
|
||||
@@ -10,6 +10,7 @@ from copy import deepcopy
|
||||
|
||||
from django.shortcuts import render
|
||||
from django.conf import settings
|
||||
from django.utils.html import escape
|
||||
|
||||
from MobSF.utils import print_n_send_error_response
|
||||
|
||||
@@ -78,14 +79,13 @@ def generic_compare(request,
|
||||
'first_app': {},
|
||||
'second_app': {},
|
||||
'urls': {},
|
||||
'api': {},
|
||||
'android_api': {},
|
||||
'permissions': {},
|
||||
'apkid': {},
|
||||
}
|
||||
static_fields = ['md5', 'name', 'size', 'icon_found',
|
||||
'icon_hidden', 'act_count', 'e_act', 'serv_count',
|
||||
'e_ser', 'bro_count', 'e_bro', 'prov_count',
|
||||
'e_cnt', 'apkid']
|
||||
static_fields = ['md5', 'file_name', 'size', 'icon_found',
|
||||
'icon_hidden', 'activities', 'services', 'providers',
|
||||
'receivers', 'exported_count', 'apkid']
|
||||
|
||||
# For now - support only android
|
||||
db_entry = StaticAnalyzerAndroid.objects.filter(MD5=first_hash)
|
||||
@@ -94,10 +94,9 @@ def generic_compare(request,
|
||||
if not (db_entry.exists() and db_entry2.exists()):
|
||||
return print_n_send_error_response(
|
||||
request,
|
||||
'One of the Hashes is not found '
|
||||
'in the Android scan database. Make '
|
||||
'sure both of the apps finished '
|
||||
'analysis and they are both Android.',
|
||||
'Currently you can only diff android apps.'
|
||||
'One of the app has not finished static analysis or'
|
||||
'they are not both android APK/ZIP.',
|
||||
False,
|
||||
)
|
||||
|
||||
@@ -115,8 +114,8 @@ def generic_compare(request,
|
||||
|
||||
# format informative title
|
||||
context[curr_app]['name_ver'] = '{0} - {1}'.format(
|
||||
db_context['packagename'],
|
||||
db_context['androvername'])
|
||||
db_context['package_name'],
|
||||
db_context['version_name'])
|
||||
|
||||
# Fill all the static information
|
||||
for static_attr in static_fields:
|
||||
@@ -124,7 +123,8 @@ def generic_compare(request,
|
||||
|
||||
# Get only the subject of the cert
|
||||
subject_regex = re.compile(r'Subject: .*')
|
||||
match = subject_regex.search(db_context['certinfo'])
|
||||
match = subject_regex.search(
|
||||
db_context['certificate_analysis']['certificate_info'])
|
||||
if match:
|
||||
context[curr_app]['cert_subject'] = match.group()
|
||||
else:
|
||||
@@ -137,6 +137,8 @@ def generic_compare(request,
|
||||
for url in url_obj['urls']:
|
||||
# urls can mess up the table because they can be really long,
|
||||
# so let's cut them
|
||||
# escape url
|
||||
url = escape(url)
|
||||
tmp_url = url[:70]
|
||||
while len(url) > 70:
|
||||
url = url[70:]
|
||||
@@ -156,7 +158,7 @@ def generic_compare(request,
|
||||
# Third, calculate some diffs
|
||||
for section, is_tuples in [
|
||||
('permissions', True),
|
||||
('api', True),
|
||||
('android_api', True),
|
||||
('urls', False),
|
||||
]:
|
||||
if is_tuples:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import logging
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def check_transport_security(p_list):
|
||||
"""Check info.plist for insecure connection configurations."""
|
||||
logger.info('Checking for Insecure Connections')
|
||||
ats = []
|
||||
if 'NSAppTransportSecurity' in p_list:
|
||||
ats_dict = p_list['NSAppTransportSecurity']
|
||||
if ats_dict.get('NSAllowsArbitraryLoads'):
|
||||
ats.append({
|
||||
'issue': 'App Transport Security is allowed',
|
||||
'status': 'insecure',
|
||||
'description': (
|
||||
'App Transport Security restrictions are disabled'
|
||||
' for all network connections. Disabling ATS means that '
|
||||
'unsecured HTTP connections are allowed. HTTPS '
|
||||
'connections are also allowed, and are still subject'
|
||||
' to default server trust evaluation. However, '
|
||||
'extended security checks like requiring a minimum '
|
||||
'Transport Layer Security (TLS) protocol version—are'
|
||||
' disabled. This setting is not applicable to domains '
|
||||
'listed in NSExceptionDomains.'),
|
||||
})
|
||||
if ats_dict.get('NSAllowsArbitraryLoadsForMedia'):
|
||||
ats.append({
|
||||
'issue': 'Insecure media load is allowed',
|
||||
'status': 'insecure',
|
||||
'description': (
|
||||
'App Transport Security restrictions are disabled for '
|
||||
'media loaded using the AVFoundation framework, '
|
||||
'without affecting your URLSession connections.'
|
||||
' This setting is not applicable to domains '
|
||||
'listed in NSExceptionDomains.'),
|
||||
})
|
||||
if ats_dict.get('NSAllowsArbitraryLoadsInWebContent'):
|
||||
ats.append({
|
||||
'issue': 'Insecure WebView load is allowed',
|
||||
'status': 'insecure',
|
||||
'description': (
|
||||
'App Transport Security restrictions are disabled for'
|
||||
' requests made from WebViews without affecting your'
|
||||
' URLSession connections. This setting is not applicable'
|
||||
' to domains listed in NSExceptionDomains.'),
|
||||
})
|
||||
exception_domain = ats_dict.get('NSExceptionDomains')
|
||||
if exception_domain:
|
||||
for domain, config in exception_domain.items():
|
||||
if config.get('NSTemporaryExceptionAllowsInsecureHTTPLoads'):
|
||||
findings = {
|
||||
'issue': ('Insecure communication'
|
||||
' to {} is allowed'.format(domain)),
|
||||
'status': 'insecure',
|
||||
'description': (
|
||||
'This settings allow insecure HTTP loads for {},'
|
||||
' or to be able to loosen the server trust '
|
||||
'evaluation requirements for HTTPS '
|
||||
'connections to the domain. '.format(domain)),
|
||||
}
|
||||
if config.get('NSIncludesSubdomains'):
|
||||
findings['description'] += (
|
||||
'This settings is applicable to the'
|
||||
' subdomains as well. '
|
||||
)
|
||||
if config.get('NSExceptionMinimumTLSVersion'):
|
||||
findings['description'] += (
|
||||
'Minimum TLS '
|
||||
'Version: {}'.format(
|
||||
config.get(
|
||||
'NSTemporaryExceptionMinimumTLSVersion'))
|
||||
)
|
||||
ats.append(findings)
|
||||
return ats
|
||||
@@ -180,10 +180,10 @@ def otool_analysis(tools_dir, bin_name, bin_path, bin_dir):
|
||||
baned_s = b', '.join(baned)
|
||||
if len(baned_s) > 1:
|
||||
banned_apis = {
|
||||
'issue': 'Binary make use of banned API(s)',
|
||||
'issue': 'Binary make use of insecure API(s)',
|
||||
'level': IN_SECURE,
|
||||
'description': ('The binary may contain'
|
||||
' the following banned API(s) {}.').format(
|
||||
' the following insecure API(s) {}.').format(
|
||||
baned_s.decode('utf-8', 'ignore')),
|
||||
'cvss': 6,
|
||||
'cwe': 'CWE-676',
|
||||
@@ -477,8 +477,6 @@ def strings_on_ipa(bin_path):
|
||||
logger.info('Running strings against the Binary')
|
||||
unique_str = []
|
||||
unique_str = list(set(strings_util(bin_path))) # Make unique
|
||||
unique_str = [escape(ip_str)
|
||||
for ip_str in unique_str] # Escape evil strings
|
||||
return unique_str
|
||||
except Exception:
|
||||
logger.exception('Running strings against the Binary')
|
||||
|
||||
@@ -1,92 +1,53 @@
|
||||
"""Module holding the functions for the db."""
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from MobSF.utils import python_dict, python_list
|
||||
|
||||
from StaticAnalyzer.models import StaticAnalyzerIOSZIP, StaticAnalyzerIPA
|
||||
from StaticAnalyzer.models import StaticAnalyzerIOS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
# IPA DB
|
||||
|
||||
|
||||
def get_context_from_analysis_ipa(app_dict,
|
||||
info_dict,
|
||||
bin_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Get the context for IPA from analysis results."""
|
||||
try:
|
||||
context = {
|
||||
'title': 'Static Analysis',
|
||||
'file_name': app_dict['file_name'],
|
||||
'size': app_dict['size'],
|
||||
'md5': app_dict['md5_hash'],
|
||||
'sha1': app_dict['sha1'],
|
||||
'sha256': app_dict['sha256'],
|
||||
'plist': info_dict['plist_xml'],
|
||||
'bin_name': info_dict['bin_name'],
|
||||
'id': info_dict['id'],
|
||||
'build': info_dict['build'],
|
||||
'bundle_version': info_dict['bundle_version_name'],
|
||||
'sdk': info_dict['sdk'],
|
||||
'pltfm': info_dict['pltfm'],
|
||||
'min': info_dict['min'],
|
||||
'bin_anal': bin_dict['bin_res'],
|
||||
'libs': bin_dict['libs'],
|
||||
'files': files,
|
||||
'file_analysis': sfiles,
|
||||
'strings': bin_dict['strings'],
|
||||
'permissions': info_dict['permissions'],
|
||||
'insecure_connections': info_dict['inseccon'],
|
||||
'bundle_name': info_dict['bundle_name'],
|
||||
'bundle_url_types': info_dict['bundle_url_types'],
|
||||
'bundle_supported_platforms':
|
||||
info_dict['bundle_supported_platforms'],
|
||||
'bundle_localizations': info_dict['bundle_localizations'],
|
||||
'binary_info': bin_dict['macho'],
|
||||
'bin_type': bin_dict['bin_type'],
|
||||
'appstore_details': app_dict['appstore'],
|
||||
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Rendering to Template')
|
||||
|
||||
|
||||
def get_context_from_db_entry_ipa(db_entry):
|
||||
"""Return the context for IPA from DB."""
|
||||
def get_context_from_db_entry(db_entry):
|
||||
"""Return the context for IPA/ZIP from DB."""
|
||||
try:
|
||||
logger.info('Analysis is already Done. Fetching data from the DB...')
|
||||
context = {
|
||||
'title': db_entry[0].TITLE,
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': 'Static Analysis',
|
||||
'file_name': db_entry[0].FILE_NAME,
|
||||
'app_name': db_entry[0].APP_NAME,
|
||||
'app_type': db_entry[0].APP_TYPE,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'plist': db_entry[0].INFOPLIST,
|
||||
'bin_name': db_entry[0].BINNAME,
|
||||
'id': db_entry[0].IDF,
|
||||
'build': db_entry[0].BUILD,
|
||||
'bundle_version': db_entry[0].VERSION,
|
||||
'sdk': db_entry[0].SDK,
|
||||
'pltfm': db_entry[0].PLTFM,
|
||||
'min': db_entry[0].MINX,
|
||||
'bin_anal': python_list(db_entry[0].BIN_ANAL),
|
||||
'libs': python_list(db_entry[0].LIBS),
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'file_analysis': python_list(db_entry[0].SFILESX),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'permissions': python_list(db_entry[0].PERMISSIONS),
|
||||
'insecure_connections': python_list(db_entry[0].INSECCON),
|
||||
'bundle_name': db_entry[0].BUNDLE_NAME,
|
||||
'app_version': db_entry[0].APP_VERSION,
|
||||
'sdk_name': db_entry[0].SDK_NAME,
|
||||
'platform': db_entry[0].PLATFORM,
|
||||
'min_os_version': db_entry[0].MIN_OS_VERSION,
|
||||
'bundle_id': db_entry[0].BUNDLE_ID,
|
||||
'bundle_url_types': python_list(db_entry[0].BUNDLE_URL_TYPES),
|
||||
'bundle_supported_platforms':
|
||||
python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
|
||||
'bundle_localizations':
|
||||
python_list(db_entry[0].BUNDLE_LOCALIZATIONS),
|
||||
'binary_info': python_dict(db_entry[0].MACHOINFO),
|
||||
'bin_type': db_entry[0].BINTYPE,
|
||||
'info_plist': db_entry[0].INFO_PLIST,
|
||||
'binary_info': python_dict(db_entry[0].MACHO_INFO),
|
||||
'permissions': python_list(db_entry[0].PERMISSIONS),
|
||||
'ats_analysis': python_list(db_entry[0].ATS_ANALYSIS),
|
||||
'binary_analysis': python_list(db_entry[0].BINARY_ANALYSIS),
|
||||
'ios_api': python_dict(db_entry[0].IOS_API),
|
||||
'code_analysis': python_dict(db_entry[0].CODE_ANALYSIS),
|
||||
'file_analysis': python_list(db_entry[0].FILE_ANALYSIS),
|
||||
'libraries': python_list(db_entry[0].LIBRARIES),
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'urls': python_list(db_entry[0].URLS),
|
||||
'domains': python_dict(db_entry[0].DOMAINS),
|
||||
'emails': python_list(db_entry[0].EMAILS),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'firebase_urls': python_list(db_entry[0].FIREBASE_URLS),
|
||||
'appstore_details': python_dict(db_entry[0].APPSTORE_DETAILS),
|
||||
|
||||
}
|
||||
@@ -95,258 +56,102 @@ def get_context_from_db_entry_ipa(db_entry):
|
||||
logger.exception('Fetching from DB')
|
||||
|
||||
|
||||
def update_db_entry_ipa(app_dict,
|
||||
info_dict,
|
||||
bin_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Update an IPA DB entry."""
|
||||
try:
|
||||
# pylint: disable=E1101
|
||||
StaticAnalyzerIPA.objects.filter(MD5=app_dict['md5_hash']).update(
|
||||
TITLE='Static Analysis',
|
||||
FILE_NAME=app_dict['file_name'],
|
||||
SIZE=app_dict['size'],
|
||||
MD5=app_dict['md5_hash'],
|
||||
SHA1=app_dict['sha1'],
|
||||
SHA256=app_dict['sha256'],
|
||||
INFOPLIST=info_dict['plist_xml'],
|
||||
BINNAME=info_dict['bin_name'],
|
||||
IDF=info_dict['id'],
|
||||
BUILD=info_dict['build'],
|
||||
VERSION=info_dict['bundle_version_name'],
|
||||
SDK=info_dict['sdk'],
|
||||
PLTFM=info_dict['pltfm'],
|
||||
MINX=info_dict['min'],
|
||||
BIN_ANAL=bin_dict['bin_res'],
|
||||
LIBS=bin_dict['libs'],
|
||||
FILES=files,
|
||||
SFILESX=sfiles,
|
||||
STRINGS=bin_dict['strings'],
|
||||
PERMISSIONS=info_dict['permissions'],
|
||||
INSECCON=info_dict['inseccon'],
|
||||
BUNDLE_NAME=info_dict['bundle_name'],
|
||||
BUNDLE_URL_TYPES=info_dict['bundle_url_types'],
|
||||
BUNDLE_SUPPORTED_PLATFORMS=info_dict['bundle_supported_platforms'],
|
||||
BUNDLE_LOCALIZATIONS=info_dict['bundle_localizations'],
|
||||
MACHOINFO=bin_dict['macho'],
|
||||
BINTYPE=bin_dict['bin_type'],
|
||||
APPSTORE_DETAILS=app_dict['appstore'],
|
||||
)
|
||||
|
||||
except Exception:
|
||||
logger.exception('Updating DB')
|
||||
|
||||
|
||||
def create_db_entry_ipa(app_dict,
|
||||
info_dict,
|
||||
bin_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Save an IOS IPA DB entry."""
|
||||
try:
|
||||
static_db = StaticAnalyzerIPA(
|
||||
TITLE='Static Analysis',
|
||||
FILE_NAME=app_dict['file_name'],
|
||||
SIZE=app_dict['size'],
|
||||
MD5=app_dict['md5_hash'],
|
||||
SHA1=app_dict['sha1'],
|
||||
SHA256=app_dict['sha256'],
|
||||
INFOPLIST=info_dict['plist_xml'],
|
||||
BINNAME=info_dict['bin_name'],
|
||||
IDF=info_dict['id'],
|
||||
BUILD=info_dict['build'],
|
||||
VERSION=info_dict['bundle_version_name'],
|
||||
SDK=info_dict['sdk'],
|
||||
PLTFM=info_dict['pltfm'],
|
||||
MINX=info_dict['min'],
|
||||
BIN_ANAL=bin_dict['bin_res'],
|
||||
LIBS=bin_dict['libs'],
|
||||
FILES=files,
|
||||
SFILESX=sfiles,
|
||||
STRINGS=bin_dict['strings'],
|
||||
PERMISSIONS=info_dict['permissions'],
|
||||
INSECCON=info_dict['inseccon'],
|
||||
BUNDLE_NAME=info_dict['bundle_name'],
|
||||
BUNDLE_URL_TYPES=info_dict['bundle_url_types'],
|
||||
BUNDLE_SUPPORTED_PLATFORMS=info_dict['bundle_supported_platforms'],
|
||||
BUNDLE_LOCALIZATIONS=info_dict['bundle_localizations'],
|
||||
MACHOINFO=bin_dict['macho'],
|
||||
BINTYPE=bin_dict['bin_type'],
|
||||
APPSTORE_DETAILS=app_dict['appstore'],
|
||||
)
|
||||
static_db.save()
|
||||
except Exception:
|
||||
logger.exception('Saving to DB')
|
||||
|
||||
# IOS ZIP DB ENTRY
|
||||
|
||||
|
||||
def get_context_from_analysis_ios(app_dict,
|
||||
info_dict,
|
||||
code_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Get the context for IOS ZIP from analysis results."""
|
||||
def get_context_from_analysis(app_dict,
|
||||
info_dict,
|
||||
code_dict,
|
||||
bin_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Get the context for IPA/ZIP from analysis results."""
|
||||
try:
|
||||
context = {
|
||||
'version': settings.MOBSF_VER,
|
||||
'title': 'Static Analysis',
|
||||
'file_name': app_dict['file_name'],
|
||||
'app_name': info_dict['bin_name'],
|
||||
'app_type': bin_dict['bin_type'],
|
||||
'size': app_dict['size'],
|
||||
'md5': app_dict['md5_hash'],
|
||||
'sha1': app_dict['sha1'],
|
||||
'sha256': app_dict['sha256'],
|
||||
'plist': info_dict['plist_xml'],
|
||||
'bin_name': info_dict['bin_name'],
|
||||
'id': info_dict['id'],
|
||||
'build': info_dict['build'],
|
||||
'bundle_version': info_dict['bundle_version_name'],
|
||||
'sdk': info_dict['sdk'],
|
||||
'pltfm': info_dict['pltfm'],
|
||||
'min': info_dict['min'],
|
||||
'files': files,
|
||||
'app_version': info_dict['bundle_version_name'],
|
||||
'sdk_name': info_dict['sdk'],
|
||||
'platform': info_dict['pltfm'],
|
||||
'min_os_version': info_dict['min'],
|
||||
'bundle_id': info_dict['id'],
|
||||
'bundle_url_types': info_dict['bundle_url_types'],
|
||||
'bundle_supported_platforms':
|
||||
info_dict['bundle_supported_platforms'],
|
||||
'info_plist': info_dict['plist_xml'],
|
||||
'binary_info': bin_dict['macho'],
|
||||
'permissions': info_dict['permissions'],
|
||||
'ats_analysis': info_dict['inseccon'],
|
||||
'binary_analysis': bin_dict['bin_res'],
|
||||
'ios_api': code_dict['api'],
|
||||
'code_analysis': code_dict['code_anal'],
|
||||
'file_analysis': sfiles,
|
||||
'api': code_dict['api'],
|
||||
'insecure': code_dict['code_anal'],
|
||||
'libraries': bin_dict['libs'],
|
||||
'files': files,
|
||||
'urls': code_dict['urlnfile'],
|
||||
'domains': code_dict['domains'],
|
||||
'emails': code_dict['emailnfile'],
|
||||
'permissions': info_dict['permissions'],
|
||||
'insecure_connections': info_dict['inseccon'],
|
||||
'bundle_name': info_dict['bundle_name'],
|
||||
'bundle_url_types': info_dict['bundle_url_types'],
|
||||
'bundle_supported_platforms':
|
||||
info_dict['bundle_supported_platforms'],
|
||||
'bundle_localizations': info_dict['bundle_localizations'],
|
||||
'strings': bin_dict['strings'],
|
||||
'firebase_urls': code_dict['firebase'],
|
||||
'appstore_details': app_dict['appstore'],
|
||||
'firebase': code_dict['firebase'],
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Rendering to Template')
|
||||
|
||||
|
||||
def get_context_from_db_entry_ios(db_entry):
|
||||
"""Return the context for IOS ZIP from DB."""
|
||||
def save_or_update(update_type,
|
||||
app_dict,
|
||||
info_dict,
|
||||
code_dict,
|
||||
bin_dict,
|
||||
files,
|
||||
sfiles) -> None:
|
||||
"""Save/Update an IPA/ZIP DB entry."""
|
||||
try:
|
||||
logger.info('Analysis is already Done. Fetching data from the DB...')
|
||||
context = {
|
||||
'title': db_entry[0].TITLE,
|
||||
'file_name': db_entry[0].FILE_NAME,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'plist': db_entry[0].INFOPLIST,
|
||||
'bin_name': db_entry[0].BINNAME,
|
||||
'id': db_entry[0].IDF,
|
||||
'build': db_entry[0].BUILD,
|
||||
'bundle_version': db_entry[0].VERSION,
|
||||
'sdk': db_entry[0].SDK,
|
||||
'pltfm': db_entry[0].PLTFM,
|
||||
'min': db_entry[0].MINX,
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'file_analysis': python_list(db_entry[0].SFILESX),
|
||||
'api': python_dict(db_entry[0].API),
|
||||
'insecure': python_dict(db_entry[0].CODEANAL),
|
||||
'urls': python_list(db_entry[0].URLnFile),
|
||||
'domains': python_dict(db_entry[0].DOMAINS),
|
||||
'emails': python_list(db_entry[0].EmailnFile),
|
||||
'permissions': python_list(db_entry[0].PERMISSIONS),
|
||||
'insecure_connections': python_list(db_entry[0].INSECCON),
|
||||
'bundle_name': db_entry[0].BUNDLE_NAME,
|
||||
'bundle_url_types': python_list(db_entry[0].BUNDLE_URL_TYPES),
|
||||
'bundle_supported_platforms':
|
||||
python_list(db_entry[0].BUNDLE_SUPPORTED_PLATFORMS),
|
||||
'bundle_localizations':
|
||||
python_list(db_entry[0].BUNDLE_LOCALIZATIONS),
|
||||
'appstore_details': python_dict(db_entry[0].APPSTORE_DETAILS),
|
||||
'firebase': python_list(db_entry[0].FIREBASE),
|
||||
values = {
|
||||
'FILE_NAME': app_dict['file_name'],
|
||||
'APP_NAME': info_dict['bin_name'],
|
||||
'APP_TYPE': bin_dict['bin_type'],
|
||||
'SIZE': app_dict['size'],
|
||||
'MD5': app_dict['md5_hash'],
|
||||
'SHA1': app_dict['sha1'],
|
||||
'SHA256': app_dict['sha256'],
|
||||
'BUILD': info_dict['build'],
|
||||
'APP_VERSION': info_dict['bundle_version_name'],
|
||||
'SDK_NAME': info_dict['sdk'],
|
||||
'PLATFORM': info_dict['pltfm'],
|
||||
'MIN_OS_VERSION': info_dict['min'],
|
||||
'BUNDLE_ID': info_dict['id'],
|
||||
'BUNDLE_URL_TYPES': info_dict['bundle_url_types'],
|
||||
'BUNDLE_SUPPORTED_PLATFORMS':
|
||||
info_dict['bundle_supported_platforms'],
|
||||
'INFO_PLIST': info_dict['plist_xml'],
|
||||
'MACHO_INFO': bin_dict['macho'],
|
||||
'PERMISSIONS': info_dict['permissions'],
|
||||
'ATS_ANALYSIS': info_dict['inseccon'],
|
||||
'BINARY_ANALYSIS': bin_dict['bin_res'],
|
||||
'IOS_API': code_dict['api'],
|
||||
'CODE_ANALYSIS': code_dict['code_anal'],
|
||||
'FILE_ANALYSIS': sfiles,
|
||||
'LIBRARIES': bin_dict['libs'],
|
||||
'FILES': files,
|
||||
'URLS': code_dict['urlnfile'],
|
||||
'DOMAINS': code_dict['domains'],
|
||||
'EMAILS': code_dict['emailnfile'],
|
||||
'STRINGS': bin_dict['strings'],
|
||||
'FIREBASE_URLS': code_dict['firebase'],
|
||||
'APPSTORE_DETAILS': app_dict['appstore'],
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Fetching from DB')
|
||||
|
||||
|
||||
def update_db_entry_ios(app_dict,
|
||||
info_dict,
|
||||
code_dict,
|
||||
files,
|
||||
sfiles):
|
||||
"""Update an IOS ZIP DB entry."""
|
||||
try:
|
||||
# pylint: disable=E1101
|
||||
StaticAnalyzerIOSZIP.objects.filter(MD5=app_dict['md5_hash']).update(
|
||||
TITLE='Static Analysis',
|
||||
FILE_NAME=app_dict['file_name'],
|
||||
SIZE=app_dict['size'],
|
||||
MD5=app_dict['md5_hash'],
|
||||
SHA1=app_dict['sha1'],
|
||||
SHA256=app_dict['sha256'],
|
||||
INFOPLIST=info_dict['plist_xml'],
|
||||
BINNAME=info_dict['bin_name'],
|
||||
IDF=info_dict['id'],
|
||||
BUILD=info_dict['build'],
|
||||
VERSION=info_dict['bundle_version_name'],
|
||||
SDK=info_dict['sdk'],
|
||||
PLTFM=info_dict['pltfm'],
|
||||
MINX=info_dict['min'],
|
||||
FILES=files,
|
||||
SFILESX=sfiles,
|
||||
API=code_dict['api'],
|
||||
CODEANAL=code_dict['code_anal'],
|
||||
URLnFile=code_dict['urlnfile'],
|
||||
DOMAINS=code_dict['domains'],
|
||||
EmailnFile=code_dict['emailnfile'],
|
||||
PERMISSIONS=info_dict['permissions'],
|
||||
INSECCON=info_dict['inseccon'],
|
||||
BUNDLE_NAME=info_dict['bundle_name'],
|
||||
BUNDLE_URL_TYPES=info_dict['bundle_url_types'],
|
||||
BUNDLE_SUPPORTED_PLATFORMS=info_dict['bundle_supported_platforms'],
|
||||
BUNDLE_LOCALIZATIONS=info_dict['bundle_localizations'],
|
||||
APPSTORE_DETAILS=app_dict['appstore'],
|
||||
FIREBASE=code_dict['firebase'],
|
||||
)
|
||||
|
||||
if update_type == 'save':
|
||||
StaticAnalyzerIOS.objects.create(**values)
|
||||
else:
|
||||
StaticAnalyzerIOS.objects.filter(
|
||||
MD5=app_dict['md5_hash']).update(**values)
|
||||
except Exception:
|
||||
logger.exception('Updating DB')
|
||||
|
||||
|
||||
def create_db_entry_ios(app_dict, info_dict, code_dict, files, sfiles):
|
||||
"""Save an IOS ZIP DB entry."""
|
||||
try:
|
||||
# pylint: disable=E1101
|
||||
static_db = StaticAnalyzerIOSZIP(
|
||||
TITLE='Static Analysis',
|
||||
FILE_NAME=app_dict['file_name'],
|
||||
SIZE=app_dict['size'],
|
||||
MD5=app_dict['md5_hash'],
|
||||
SHA1=app_dict['sha1'],
|
||||
SHA256=app_dict['sha256'],
|
||||
INFOPLIST=info_dict['plist_xml'],
|
||||
BINNAME=info_dict['bin_name'],
|
||||
IDF=info_dict['id'],
|
||||
BUILD=info_dict['build'],
|
||||
VERSION=info_dict['bundle_version_name'],
|
||||
SDK=info_dict['sdk'],
|
||||
PLTFM=info_dict['pltfm'],
|
||||
MINX=info_dict['min'],
|
||||
FILES=files,
|
||||
SFILESX=sfiles,
|
||||
API=code_dict['api'],
|
||||
CODEANAL=code_dict['code_anal'],
|
||||
URLnFile=code_dict['urlnfile'],
|
||||
DOMAINS=code_dict['domains'],
|
||||
EmailnFile=code_dict['emailnfile'],
|
||||
PERMISSIONS=info_dict['permissions'],
|
||||
INSECCON=info_dict['inseccon'],
|
||||
BUNDLE_NAME=info_dict['bundle_name'],
|
||||
BUNDLE_URL_TYPES=info_dict['bundle_url_types'],
|
||||
BUNDLE_SUPPORTED_PLATFORMS=info_dict['bundle_supported_platforms'],
|
||||
BUNDLE_LOCALIZATIONS=info_dict['bundle_localizations'],
|
||||
APPSTORE_DETAILS=app_dict['appstore'],
|
||||
FIREBASE=code_dict['firebase'],
|
||||
)
|
||||
static_db.save()
|
||||
except Exception:
|
||||
logger.exception('Saving DB')
|
||||
|
||||
@@ -157,6 +157,58 @@ CODE_RULES = [
|
||||
'cwe': 'CWE-22',
|
||||
'owasp': 'M10: Extraneous Functionality',
|
||||
},
|
||||
{
|
||||
'desc': ('File is stored in an encrypted format on '
|
||||
'disk and cannot be read from or written to '
|
||||
'while the device is locked or booting.'),
|
||||
'type': 'string',
|
||||
'string1': 'NSFileProtectionComplete',
|
||||
'level': 'good',
|
||||
'match': 'single_string',
|
||||
'input_case': 'exact',
|
||||
'cvss': 0,
|
||||
'cwe': '',
|
||||
'owasp': '',
|
||||
},
|
||||
{
|
||||
'desc': ('File is stored in an encrypted format '
|
||||
'on disk after it is closed.'),
|
||||
'type': 'string',
|
||||
'string1': 'NSFileProtectionCompleteUnlessOpen',
|
||||
'level': 'good',
|
||||
'match': 'single_string',
|
||||
'input_case': 'exact',
|
||||
'cvss': 0,
|
||||
'cwe': '',
|
||||
'owasp': '',
|
||||
},
|
||||
{
|
||||
'desc': ('File is stored in an encrypted format '
|
||||
'on disk and cannot be accessed until after '
|
||||
'the device has booted.'),
|
||||
'type': 'string',
|
||||
'string1': (
|
||||
'NSFileProtectionComplete'
|
||||
'UntilFirstUserAuthentication'),
|
||||
'level': 'good',
|
||||
'match': 'single_string',
|
||||
'input_case': 'exact',
|
||||
'cvss': 0,
|
||||
'cwe': '',
|
||||
'owasp': '',
|
||||
},
|
||||
{
|
||||
'desc': ('The file has no special protections '
|
||||
'associated with it.'),
|
||||
'type': 'string',
|
||||
'string1': 'NSFileProtectionNone',
|
||||
'level': 'warning',
|
||||
'match': 'single_string',
|
||||
'input_case': 'exact',
|
||||
'cvss': 4.3,
|
||||
'cwe': 'CWE-311',
|
||||
'owasp': 'M1: Improper Platform Usage',
|
||||
},
|
||||
{
|
||||
'desc': ('User input in "loadHTMLString" '
|
||||
'will result in JavaScript Injection.'),
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def check_permissions(p_list):
|
||||
"""Check the permissions the app requests."""
|
||||
# List taken from
|
||||
# https://developer.apple.com/library/content/
|
||||
# documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html
|
||||
logger.info('Checking Permissions')
|
||||
permissions = []
|
||||
if 'NSAppleMusicUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSAppleMusicUsageDescription',
|
||||
'description': 'Access Apple Media Library.',
|
||||
'reason': p_list['NSAppleMusicUsageDescription'],
|
||||
})
|
||||
if 'NSBluetoothPeripheralUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSBluetoothPeripheralUsageDescription',
|
||||
'description': 'Access Bluetooth Interface.',
|
||||
'reason': p_list['NSBluetoothPeripheralUsageDescription'],
|
||||
})
|
||||
if 'NSCalendarsUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSCalendarsUsageDescription',
|
||||
'description': 'Access Calendars.',
|
||||
'reason': p_list['NSCalendarsUsageDescription'],
|
||||
})
|
||||
if 'NSCameraUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSCameraUsageDescription',
|
||||
'description': 'Access the Camera.',
|
||||
'reason': p_list['NSCameraUsageDescription'],
|
||||
})
|
||||
if 'NSContactsUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSContactsUsageDescription',
|
||||
'description': 'Access Contacts.',
|
||||
'reason': p_list['NSContactsUsageDescription'],
|
||||
})
|
||||
if 'NSHealthShareUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHealthShareUsageDescription',
|
||||
'description': 'Read Health Data.',
|
||||
'reason': p_list['NSHealthShareUsageDescription'],
|
||||
})
|
||||
if 'NSHealthUpdateUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHealthUpdateUsageDescription',
|
||||
'description': 'Write Health Data.',
|
||||
'reason': p_list['NSHealthUpdateUsageDescription'],
|
||||
})
|
||||
if 'NSHomeKitUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHomeKitUsageDescription',
|
||||
'description': 'Access HomeKit configuration data.',
|
||||
'reason': p_list['NSHomeKitUsageDescription'],
|
||||
})
|
||||
if 'NSLocationAlwaysUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationAlwaysUsageDescription',
|
||||
'description': 'Access location information at all times.',
|
||||
'reason': p_list['NSLocationAlwaysUsageDescription'],
|
||||
})
|
||||
if 'NSLocationUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationUsageDescription',
|
||||
'description': ('Access location information'
|
||||
' at all times (< iOS 8).'),
|
||||
'reason': p_list['NSLocationUsageDescription'],
|
||||
})
|
||||
if 'NSLocationWhenInUseUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationWhenInUseUsageDescription',
|
||||
'description': ('Access location information when'
|
||||
' app is in the foreground.'),
|
||||
'reason': p_list['NSLocationWhenInUseUsageDescription'],
|
||||
})
|
||||
if 'NSMicrophoneUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSMicrophoneUsageDescription',
|
||||
'description': 'Access microphone.',
|
||||
'reason': p_list['NSMicrophoneUsageDescription'],
|
||||
})
|
||||
if 'NSMotionUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSMotionUsageDescription',
|
||||
'description': 'Access the device’s accelerometer.',
|
||||
'reason': p_list['NSMotionUsageDescription'],
|
||||
})
|
||||
if 'NSPhotoLibraryUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSPhotoLibraryUsageDescription',
|
||||
'description': 'Access the user’s photo library.',
|
||||
'reason': p_list['NSPhotoLibraryUsageDescription'],
|
||||
})
|
||||
if 'NSRemindersUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSRemindersUsageDescription',
|
||||
'description': 'Access the user’s reminders.',
|
||||
'reason': p_list['NSRemindersUsageDescription'],
|
||||
})
|
||||
if 'NSVideoSubscriberAccountUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSVideoSubscriberAccountUsageDescription',
|
||||
'description': 'Access the user’s TV provider account.',
|
||||
'reason': p_list['NSVideoSubscriberAccountUsageDescription'],
|
||||
})
|
||||
|
||||
return permissions
|
||||
@@ -10,6 +10,10 @@ from biplist import readPlist, writePlistToString
|
||||
|
||||
from MobSF.utils import is_file_exists
|
||||
|
||||
from StaticAnalyzer.views.ios.permission_analysis import check_permissions
|
||||
from StaticAnalyzer.views.ios.app_transport_security import (
|
||||
check_transport_security)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -23,131 +27,6 @@ def convert_bin_xml(bin_xml_file):
|
||||
logger.warning('Failed to convert plist')
|
||||
|
||||
|
||||
def check_permissions(p_list):
|
||||
"""Check the permissions the app requests."""
|
||||
# List taken from
|
||||
# https://developer.apple.com/library/content/
|
||||
# documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html
|
||||
logger.info('Checking Permissions')
|
||||
permissions = []
|
||||
if 'NSAppleMusicUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSAppleMusicUsageDescription',
|
||||
'description': 'Access Apple Media Library.',
|
||||
'reason': p_list['NSAppleMusicUsageDescription'],
|
||||
})
|
||||
if 'NSBluetoothPeripheralUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSBluetoothPeripheralUsageDescription',
|
||||
'description': 'Access Bluetooth Interface.',
|
||||
'reason': p_list['NSBluetoothPeripheralUsageDescription'],
|
||||
})
|
||||
if 'NSCalendarsUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSCalendarsUsageDescription',
|
||||
'description': 'Access Calendars.',
|
||||
'reason': p_list['NSCalendarsUsageDescription'],
|
||||
})
|
||||
if 'NSCameraUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSCameraUsageDescription',
|
||||
'description': 'Access the Camera.',
|
||||
'reason': p_list['NSCameraUsageDescription'],
|
||||
})
|
||||
if 'NSContactsUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSContactsUsageDescription',
|
||||
'description': 'Access Contacts.',
|
||||
'reason': p_list['NSContactsUsageDescription'],
|
||||
})
|
||||
if 'NSHealthShareUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHealthShareUsageDescription',
|
||||
'description': 'Read Health Data.',
|
||||
'reason': p_list['NSHealthShareUsageDescription'],
|
||||
})
|
||||
if 'NSHealthUpdateUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHealthUpdateUsageDescription',
|
||||
'description': 'Write Health Data.',
|
||||
'reason': p_list['NSHealthUpdateUsageDescription'],
|
||||
})
|
||||
if 'NSHomeKitUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSHomeKitUsageDescription',
|
||||
'description': 'Access HomeKit configuration data.',
|
||||
'reason': p_list['NSHomeKitUsageDescription'],
|
||||
})
|
||||
if 'NSLocationAlwaysUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationAlwaysUsageDescription',
|
||||
'description': 'Access location information at all times.',
|
||||
'reason': p_list['NSLocationAlwaysUsageDescription'],
|
||||
})
|
||||
if 'NSLocationUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationUsageDescription',
|
||||
'description': ('Access location information'
|
||||
' at all times (< iOS 8).'),
|
||||
'reason': p_list['NSLocationUsageDescription'],
|
||||
})
|
||||
if 'NSLocationWhenInUseUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSLocationWhenInUseUsageDescription',
|
||||
'description': ('Access location information when'
|
||||
' app is in the foreground.'),
|
||||
'reason': p_list['NSLocationWhenInUseUsageDescription'],
|
||||
})
|
||||
if 'NSMicrophoneUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSMicrophoneUsageDescription',
|
||||
'description': 'Access microphone.',
|
||||
'reason': p_list['NSMicrophoneUsageDescription'],
|
||||
})
|
||||
if 'NSMotionUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSMotionUsageDescription',
|
||||
'description': 'Access the device’s accelerometer.',
|
||||
'reason': p_list['NSMotionUsageDescription'],
|
||||
})
|
||||
if 'NSPhotoLibraryUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSPhotoLibraryUsageDescription',
|
||||
'description': 'Access the user’s photo library.',
|
||||
'reason': p_list['NSPhotoLibraryUsageDescription'],
|
||||
})
|
||||
if 'NSRemindersUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSRemindersUsageDescription',
|
||||
'description': 'Access the user’s reminders.',
|
||||
'reason': p_list['NSRemindersUsageDescription'],
|
||||
})
|
||||
if 'NSVideoSubscriberAccountUsageDescription' in p_list:
|
||||
permissions.append({
|
||||
'name': 'NSVideoSubscriberAccountUsageDescription',
|
||||
'description': 'Access the user’s TV provider account.',
|
||||
'reason': p_list['NSVideoSubscriberAccountUsageDescription'],
|
||||
})
|
||||
|
||||
return permissions
|
||||
|
||||
|
||||
def check_insecure_connections(p_list):
|
||||
"""Check info.plist for insecure connection configurations."""
|
||||
logger.info('Checking for Insecure Connections')
|
||||
|
||||
insecure_connections = []
|
||||
if 'NSAppTransportSecurity' in p_list:
|
||||
ns_app_trans_dic = p_list['NSAppTransportSecurity']
|
||||
if 'NSExceptionDomains' in ns_app_trans_dic:
|
||||
for key in ns_app_trans_dic['NSExceptionDomains']:
|
||||
insecure_connections.append(key)
|
||||
if 'NSAllowsArbitraryLoads' in ns_app_trans_dic:
|
||||
if ns_app_trans_dic['NSAllowsArbitraryLoads'] is True:
|
||||
insecure_connections.append(p_list['NSAppTransportSecurity'])
|
||||
return insecure_connections
|
||||
|
||||
|
||||
def plist_analysis(src, is_source):
|
||||
"""Plist Analysis."""
|
||||
try:
|
||||
@@ -168,15 +47,14 @@ def plist_analysis(src, is_source):
|
||||
'build_version_name': '',
|
||||
'bundle_url_types': [],
|
||||
'bundle_supported_platforms': [],
|
||||
'bundle_localizations': [],
|
||||
}
|
||||
plist_file = None
|
||||
if is_source:
|
||||
logger.info('Finding Info.plist in iOS Source')
|
||||
app_plist_file = 'Info.plist'
|
||||
for dirpath, _dirnames, files in os.walk(src):
|
||||
for name in files:
|
||||
if '__MACOSX' not in dirpath and name == app_plist_file:
|
||||
if (not any(x in dirpath for x in ['__MACOSX', 'Pods'])
|
||||
and name == 'Info.plist'):
|
||||
plist_file = os.path.join(dirpath, name)
|
||||
break
|
||||
else:
|
||||
@@ -197,27 +75,17 @@ def plist_analysis(src, is_source):
|
||||
plist_obj = plistlib.readPlist(plist_file)
|
||||
plist_info['plist_xml'] = plistlib.writePlistToBytes(
|
||||
plist_obj).decode('utf-8', 'ignore')
|
||||
if 'CFBundleDisplayName' in plist_obj:
|
||||
plist_info['bin_name'] = plist_obj['CFBundleDisplayName']
|
||||
else:
|
||||
if not is_source:
|
||||
# For iOS IPA
|
||||
plist_info['bin_name'] = dot_app_dir.replace('.app', '')
|
||||
if 'CFBundleExecutable' in plist_obj:
|
||||
plist_info['bin'] = plist_obj['CFBundleExecutable']
|
||||
if 'CFBundleIdentifier' in plist_obj:
|
||||
plist_info['id'] = plist_obj['CFBundleIdentifier']
|
||||
|
||||
# build
|
||||
if 'CFBundleVersion' in plist_obj:
|
||||
plist_info['build'] = plist_obj['CFBundleVersion']
|
||||
if 'DTSDKName' in plist_obj:
|
||||
plist_info['sdk'] = plist_obj['DTSDKName']
|
||||
if 'DTPlatformVersion' in plist_obj:
|
||||
plist_info['pltfm'] = plist_obj['DTPlatformVersion']
|
||||
if 'MinimumOSVersion' in plist_obj:
|
||||
plist_info['min'] = plist_obj['MinimumOSVersion']
|
||||
|
||||
plist_info['bin_name'] = (plist_obj.get('CFBundleDisplayName', '')
|
||||
or plist_obj.get('CFBundleName', ''))
|
||||
if not plist_info['bin_name'] and not is_source:
|
||||
# For iOS IPA
|
||||
plist_info['bin_name'] = dot_app_dir.replace('.app', '')
|
||||
plist_info['bin'] = plist_obj.get('CFBundleExecutable', '')
|
||||
plist_info['id'] = plist_obj.get('CFBundleIdentifier', '')
|
||||
plist_info['build'] = plist_obj.get('CFBundleVersion', '')
|
||||
plist_info['sdk'] = plist_obj.get('DTSDKName', '')
|
||||
plist_info['pltfm'] = plist_obj.get('DTPlatformVersion', '')
|
||||
plist_info['min'] = plist_obj.get('MinimumOSVersion', '')
|
||||
plist_info['bundle_name'] = plist_obj.get('CFBundleName', '')
|
||||
plist_info['bundle_version_name'] = plist_obj.get(
|
||||
'CFBundleShortVersionString', '')
|
||||
@@ -225,12 +93,10 @@ def plist_analysis(src, is_source):
|
||||
'CFBundleURLTypes', [])
|
||||
plist_info['bundle_supported_platforms'] = plist_obj.get(
|
||||
'CFBundleSupportedPlatforms', [])
|
||||
plist_info['bundle_localizations'] = plist_obj.get(
|
||||
'CFBundleLocalizations', [])
|
||||
|
||||
# Check possible app-permissions
|
||||
# Check for app-permissions
|
||||
plist_info['permissions'] = check_permissions(plist_obj)
|
||||
plist_info['inseccon'] = check_insecure_connections(plist_obj)
|
||||
# Check for ats misconfigurations
|
||||
plist_info['inseccon'] = check_transport_security(plist_obj)
|
||||
return plist_info
|
||||
except Exception:
|
||||
logger.exception('Reading from Info.plist')
|
||||
|
||||
@@ -11,14 +11,14 @@ from django.shortcuts import render
|
||||
|
||||
from MobSF.utils import print_n_send_error_response
|
||||
|
||||
from StaticAnalyzer.models import StaticAnalyzerIOSZIP, StaticAnalyzerIPA
|
||||
from StaticAnalyzer.models import StaticAnalyzerIOS
|
||||
from StaticAnalyzer.views.ios.appstore import app_search
|
||||
from StaticAnalyzer.views.ios.binary_analysis import binary_analysis
|
||||
from StaticAnalyzer.views.ios.code_analysis import ios_source_analysis
|
||||
from StaticAnalyzer.views.ios.db_interaction import (
|
||||
create_db_entry_ios, create_db_entry_ipa, get_context_from_analysis_ios,
|
||||
get_context_from_analysis_ipa, get_context_from_db_entry_ios,
|
||||
get_context_from_db_entry_ipa, update_db_entry_ios, update_db_entry_ipa)
|
||||
get_context_from_analysis,
|
||||
get_context_from_db_entry,
|
||||
save_or_update)
|
||||
from StaticAnalyzer.views.ios.file_analysis import ios_list_files
|
||||
from StaticAnalyzer.views.ios.plist_analysis import plist_analysis
|
||||
from StaticAnalyzer.views.shared_func import (file_size, firebase_analysis,
|
||||
@@ -62,10 +62,10 @@ def static_analyzer_ios(request, api=False):
|
||||
app_dict['directory'], 'StaticAnalyzer/tools/mac/')
|
||||
if file_type == 'ipa':
|
||||
# DB
|
||||
ipa_db = StaticAnalyzerIPA.objects.filter(
|
||||
ipa_db = StaticAnalyzerIOS.objects.filter(
|
||||
MD5=app_dict['md5_hash'])
|
||||
if ipa_db.exists() and rescan == '0':
|
||||
context = get_context_from_db_entry_ipa(ipa_db)
|
||||
context = get_context_from_db_entry(ipa_db)
|
||||
else:
|
||||
logger.info('iOS Binary (IPA) Analysis Started')
|
||||
app_dict['app_file'] = app_dict[
|
||||
@@ -92,51 +92,63 @@ def static_analyzer_ios(request, api=False):
|
||||
tools_dir,
|
||||
app_dict['app_dir'],
|
||||
infoplist_dict.get('bin'))
|
||||
fake_code_dict = {
|
||||
'api': {},
|
||||
'code_anal': {},
|
||||
'urlnfile': [],
|
||||
'domains': {},
|
||||
'emailnfile': [],
|
||||
'firebase': [],
|
||||
}
|
||||
# Saving to DB
|
||||
logger.info('Connecting to DB')
|
||||
if rescan == '1':
|
||||
logger.info('Updating Database...')
|
||||
update_db_entry_ipa(
|
||||
save_or_update(
|
||||
'update',
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
fake_code_dict,
|
||||
bin_analysis_dict,
|
||||
files,
|
||||
sfiles)
|
||||
update_scan_timestamp(app_dict['md5_hash'])
|
||||
elif rescan == '0':
|
||||
logger.info('Saving to Database')
|
||||
create_db_entry_ipa(
|
||||
save_or_update(
|
||||
'save',
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
fake_code_dict,
|
||||
bin_analysis_dict,
|
||||
files,
|
||||
sfiles)
|
||||
context = get_context_from_analysis_ipa(
|
||||
context = get_context_from_analysis(
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
fake_code_dict,
|
||||
bin_analysis_dict,
|
||||
files,
|
||||
sfiles)
|
||||
context['VT_RESULT'] = None
|
||||
context['virus_total'] = None
|
||||
if settings.VT_ENABLED:
|
||||
vt = VirusTotal.VirusTotal()
|
||||
context['VT_RESULT'] = vt.get_result(
|
||||
context['virus_total'] = vt.get_result(
|
||||
os.path.join(app_dict['app_dir'], app_dict[
|
||||
'md5_hash']) + '.ipa',
|
||||
app_dict['md5_hash'])
|
||||
context['version'] = settings.MOBSF_VER
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['bin_anal'])
|
||||
'security_score'] = score(context['binary_analysis'])
|
||||
template = 'static_analysis/ios_binary_analysis.html'
|
||||
if api:
|
||||
return context
|
||||
else:
|
||||
return render(request, template, context)
|
||||
elif file_type == 'ios':
|
||||
ios_zip_db = StaticAnalyzerIOSZIP.objects.filter(
|
||||
ios_zip_db = StaticAnalyzerIOS.objects.filter(
|
||||
MD5=app_dict['md5_hash'])
|
||||
if ios_zip_db.exists() and rescan == '0':
|
||||
context = get_context_from_db_entry_ios(ios_zip_db)
|
||||
context = get_context_from_db_entry(ios_zip_db)
|
||||
else:
|
||||
logger.info('iOS Source Code Analysis Started')
|
||||
app_dict['app_file'] = app_dict[
|
||||
@@ -161,34 +173,45 @@ def static_analyzer_ios(request, api=False):
|
||||
# Firebase DB Check
|
||||
code_analysis_dic['firebase'] = firebase_analysis(
|
||||
list(set(code_analysis_dic['urls_list'])))
|
||||
fake_bin_dict = {
|
||||
'bin_type': '',
|
||||
'macho': {},
|
||||
'bin_res': [],
|
||||
'libs': [],
|
||||
'strings': [],
|
||||
}
|
||||
# Saving to DB
|
||||
logger.info('Connecting to DB')
|
||||
if rescan == '1':
|
||||
logger.info('Updating Database...')
|
||||
update_db_entry_ios(
|
||||
save_or_update(
|
||||
'update',
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
code_analysis_dic,
|
||||
fake_bin_dict,
|
||||
files,
|
||||
sfiles)
|
||||
update_scan_timestamp(app_dict['md5_hash'])
|
||||
elif rescan == '0':
|
||||
logger.info('Saving to Database')
|
||||
create_db_entry_ios(
|
||||
save_or_update(
|
||||
'save',
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
code_analysis_dic,
|
||||
fake_bin_dict,
|
||||
files,
|
||||
sfiles)
|
||||
context = get_context_from_analysis_ios(
|
||||
context = get_context_from_analysis(
|
||||
app_dict,
|
||||
infoplist_dict,
|
||||
code_analysis_dic,
|
||||
fake_bin_dict,
|
||||
files,
|
||||
sfiles)
|
||||
context['version'] = settings.MOBSF_VER
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['insecure'])
|
||||
'security_score'] = score(context['code_analysis'])
|
||||
template = 'static_analysis/ios_source_analysis.html'
|
||||
if api:
|
||||
return context
|
||||
|
||||
@@ -27,17 +27,19 @@ from django.utils.html import escape
|
||||
|
||||
from MobSF import settings
|
||||
from MobSF.utils import (print_n_send_error_response,
|
||||
python_list,
|
||||
upstream_proxy)
|
||||
|
||||
from StaticAnalyzer.models import (RecentScansDB, StaticAnalyzerAndroid,
|
||||
StaticAnalyzerIOSZIP, StaticAnalyzerIPA,
|
||||
from StaticAnalyzer.models import (RecentScansDB,
|
||||
StaticAnalyzerAndroid,
|
||||
StaticAnalyzerIOS,
|
||||
StaticAnalyzerWindows)
|
||||
from StaticAnalyzer.views.android.db_interaction import (
|
||||
get_context_from_db_entry)
|
||||
from StaticAnalyzer.views.comparer import generic_compare
|
||||
from StaticAnalyzer.views.android.db_interaction import (
|
||||
get_context_from_db_entry as adb)
|
||||
from StaticAnalyzer.views.ios.db_interaction import (
|
||||
get_context_from_db_entry_ios, get_context_from_db_entry_ipa)
|
||||
get_context_from_db_entry as idb)
|
||||
from StaticAnalyzer.views.windows.db_interaction import (
|
||||
get_context_from_db_entry as wdb)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
try:
|
||||
@@ -122,9 +124,9 @@ def pdf(request, api=False, jsonres=False):
|
||||
logger.info(
|
||||
'Fetching data from DB for '
|
||||
'PDF Report Generation (Android)')
|
||||
context = get_context_from_db_entry(static_db)
|
||||
context = adb(static_db)
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['findings'])
|
||||
'security_score'] = score(context['code_analysis'])
|
||||
if scan_type.lower() == 'apk':
|
||||
template = get_template(
|
||||
'pdf/android_binary_analysis.pdf.html')
|
||||
@@ -141,14 +143,15 @@ def pdf(request, api=False, jsonres=False):
|
||||
status=500)
|
||||
elif scan_type.lower() in ['ipa', 'ioszip']:
|
||||
if scan_type.lower() == 'ipa':
|
||||
static_db = StaticAnalyzerIPA.objects.filter(MD5=checksum)
|
||||
static_db = StaticAnalyzerIOS.objects.filter(MD5=checksum)
|
||||
if static_db.exists():
|
||||
logger.info(
|
||||
'Fetching data from DB for '
|
||||
'PDF Report Generation (IOS IPA)')
|
||||
context = get_context_from_db_entry_ipa(static_db)
|
||||
context = idb(static_db)
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['bin_anal'])
|
||||
'security_score'] = score(
|
||||
context['binary_analysis'])
|
||||
template = get_template(
|
||||
'pdf/ios_binary_analysis_pdf.html')
|
||||
else:
|
||||
@@ -160,15 +163,15 @@ def pdf(request, api=False, jsonres=False):
|
||||
content_type='application/json; charset=utf-8',
|
||||
status=500)
|
||||
elif scan_type.lower() == 'ioszip':
|
||||
static_db = StaticAnalyzerIOSZIP.objects.filter(
|
||||
static_db = StaticAnalyzerIOS.objects.filter(
|
||||
MD5=checksum)
|
||||
if static_db.exists():
|
||||
logger.info(
|
||||
'Fetching data from DB for '
|
||||
'PDF Report Generation (IOS ZIP)')
|
||||
context = get_context_from_db_entry_ios(static_db)
|
||||
context = idb(static_db)
|
||||
context['average_cvss'], context[
|
||||
'security_score'] = score(context['insecure'])
|
||||
'security_score'] = score(context['code_analysis'])
|
||||
template = get_template(
|
||||
'pdf/ios_source_analysis_pdf.html')
|
||||
else:
|
||||
@@ -188,35 +191,7 @@ def pdf(request, api=False, jsonres=False):
|
||||
logger.info(
|
||||
'Fetching data from DB for '
|
||||
'PDF Report Generation (APPX)')
|
||||
|
||||
context = {
|
||||
'title': db_entry[0].TITLE,
|
||||
'name': db_entry[0].APP_NAME,
|
||||
'pub_name': db_entry[0].PUB_NAME,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'bin_name': db_entry[0].BINNAME,
|
||||
'app_version': db_entry[0].VERSION,
|
||||
'arch': db_entry[0].ARCH,
|
||||
'compiler_version': db_entry[0].COMPILER_VERSION,
|
||||
'visual_studio_version':
|
||||
db_entry[0].VISUAL_STUDIO_VERSION,
|
||||
'visual_studio_edition':
|
||||
db_entry[0].VISUAL_STUDIO_EDITION,
|
||||
'target_os': db_entry[0].TARGET_OS,
|
||||
'appx_dll_version': db_entry[0].APPX_DLL_VERSION,
|
||||
'proj_guid': db_entry[0].PROJ_GUID,
|
||||
'opti_tool': db_entry[0].OPTI_TOOL,
|
||||
'target_run': db_entry[0].TARGET_RUN,
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'bin_an_results':
|
||||
python_list(db_entry[0].BIN_AN_RESULTS),
|
||||
'bin_an_warnings':
|
||||
python_list(db_entry[0].BIN_AN_WARNINGS),
|
||||
}
|
||||
context = wdb(db_entry)
|
||||
template = get_template(
|
||||
'pdf/windows_binary_analysis_pdf.html')
|
||||
else:
|
||||
@@ -228,14 +203,14 @@ def pdf(request, api=False, jsonres=False):
|
||||
content_type='application/json; charset=utf-8',
|
||||
status=500)
|
||||
|
||||
context['VT_RESULT'] = None
|
||||
context['virus_total'] = None
|
||||
if settings.VT_ENABLED:
|
||||
app_dir = os.path.join(settings.UPLD_DIR, checksum + '/')
|
||||
vt = VirusTotal.VirusTotal()
|
||||
if 'zip' in scan_type.lower():
|
||||
context['VT_RESULT'] = None
|
||||
context['virus_total'] = None
|
||||
else:
|
||||
context['VT_RESULT'] = vt.get_result(
|
||||
context['virus_total'] = vt.get_result(
|
||||
os.path.join(app_dir, checksum)
|
||||
+ '.' + scan_type.lower(),
|
||||
checksum)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
"""Module holding the functions for the db."""
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from MobSF.utils import python_list
|
||||
|
||||
from StaticAnalyzer.models import StaticAnalyzerWindows
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_context_from_db_entry(db_entry):
|
||||
"""Return the context for APPX from DB."""
|
||||
try:
|
||||
logger.info('Analysis is already Done. Fetching data from the DB...')
|
||||
context = {
|
||||
'title': 'Static Analysis',
|
||||
'version': settings.MOBSF_VER,
|
||||
'file_name': db_entry[0].FILE_NAME,
|
||||
'app_name': db_entry[0].APP_NAME,
|
||||
'publisher_name': db_entry[0].PUBLISHER_NAME,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'app_version': db_entry[0].APP_VERSION,
|
||||
'architecture': db_entry[0].ARCHITECTURE,
|
||||
'compiler_version': db_entry[0].COMPILER_VERSION,
|
||||
'visual_studio_version': db_entry[0].VISUAL_STUDIO_VERSION,
|
||||
'visual_studio_edition': db_entry[0].VISUAL_STUDIO_EDITION,
|
||||
'target_os': db_entry[0].TARGET_OS,
|
||||
'appx_dll_version': db_entry[0].APPX_DLL_VERSION,
|
||||
'proj_guid': db_entry[0].PROJ_GUID,
|
||||
'opti_tool': db_entry[0].OPTI_TOOL,
|
||||
'target_run': db_entry[0].TARGET_RUN,
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'binary_analysis': python_list(db_entry[0].BINARY_ANALYSIS),
|
||||
'binary_warnings': python_list(db_entry[0].BINARY_WARNINGS),
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Fetching from DB')
|
||||
|
||||
|
||||
def get_context_from_analysis(app_dic,
|
||||
xml_dic,
|
||||
bin_an_dic):
|
||||
"""Get the context for APPX from analysis results."""
|
||||
try:
|
||||
context = {
|
||||
'title': 'Static Analysis',
|
||||
'version': settings.MOBSF_VER,
|
||||
'file_name': app_dic['app_name'],
|
||||
'app_name': bin_an_dic['bin_name'],
|
||||
'publisher_name': xml_dic['pub_name'],
|
||||
'size': app_dic['size'],
|
||||
'md5': app_dic['md5'],
|
||||
'sha1': app_dic['sha1'],
|
||||
'sha256': app_dic['sha256'],
|
||||
'app_version': xml_dic['version'],
|
||||
'architecture': xml_dic['arch'],
|
||||
'compiler_version': xml_dic['compiler_version'],
|
||||
'visual_studio_version': xml_dic['visual_studio_version'],
|
||||
'visual_studio_edition': xml_dic['visual_studio_edition'],
|
||||
'target_os': xml_dic['target_os'],
|
||||
'appx_dll_version': xml_dic['appx_dll_version'],
|
||||
'proj_guid': xml_dic['proj_guid'],
|
||||
'opti_tool': xml_dic['opti_tool'],
|
||||
'target_run': xml_dic['target_run'],
|
||||
'files': app_dic['files'],
|
||||
'strings': bin_an_dic['strings'],
|
||||
'binary_analysis': bin_an_dic['results'],
|
||||
'binary_warnings': bin_an_dic['warnings'],
|
||||
}
|
||||
return context
|
||||
except Exception:
|
||||
logger.exception('Rendering to Template')
|
||||
|
||||
|
||||
def save_or_update(update_type,
|
||||
app_dic,
|
||||
xml_dic,
|
||||
bin_an_dic) -> None:
|
||||
"""Save/Update an APPX DB entry."""
|
||||
try:
|
||||
values = {
|
||||
'FILE_NAME': app_dic['app_name'],
|
||||
'APP_NAME': bin_an_dic['bin_name'],
|
||||
'PUBLISHER_NAME': xml_dic['pub_name'],
|
||||
'SIZE': app_dic['size'],
|
||||
'MD5': app_dic['md5'],
|
||||
'SHA1': app_dic['sha1'],
|
||||
'SHA256': app_dic['sha256'],
|
||||
'APP_VERSION': xml_dic['version'],
|
||||
'ARCHITECTURE': xml_dic['arch'],
|
||||
'COMPILER_VERSION': xml_dic['compiler_version'],
|
||||
'VISUAL_STUDIO_VERSION': xml_dic['visual_studio_version'],
|
||||
'VISUAL_STUDIO_EDITION': xml_dic['visual_studio_edition'],
|
||||
'TARGET_OS': xml_dic['target_os'],
|
||||
'APPX_DLL_VERSION': xml_dic['appx_dll_version'],
|
||||
'PROJ_GUID': xml_dic['proj_guid'],
|
||||
'OPTI_TOOL': xml_dic['opti_tool'],
|
||||
'TARGET_RUN': xml_dic['target_run'],
|
||||
'FILES': app_dic['files'],
|
||||
'STRINGS': bin_an_dic['strings'],
|
||||
'BINARY_ANALYSIS': bin_an_dic['results'],
|
||||
'BINARY_WARNINGS': bin_an_dic['warnings'],
|
||||
}
|
||||
if update_type == 'save':
|
||||
StaticAnalyzerWindows.objects.create(**values)
|
||||
else:
|
||||
StaticAnalyzerWindows.objects.filter(
|
||||
MD5=app_dic['md5']).update(**values)
|
||||
except Exception:
|
||||
logger.exception('Updating DB')
|
||||
@@ -21,12 +21,19 @@ from django.conf import settings
|
||||
from django.shortcuts import render
|
||||
from django.utils.html import escape
|
||||
|
||||
from MobSF.utils import print_n_send_error_response, python_list
|
||||
from MobSF.utils import print_n_send_error_response
|
||||
|
||||
from StaticAnalyzer.models import StaticAnalyzerWindows
|
||||
from StaticAnalyzer.tools.strings import strings_util
|
||||
from StaticAnalyzer.views.shared_func import (file_size, hash_gen, unzip,
|
||||
update_scan_timestamp)
|
||||
from StaticAnalyzer.views.shared_func import (
|
||||
file_size,
|
||||
hash_gen,
|
||||
unzip,
|
||||
update_scan_timestamp)
|
||||
from StaticAnalyzer.views.windows.db_interaction import (
|
||||
get_context_from_analysis,
|
||||
get_context_from_db_entry,
|
||||
save_or_update)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -74,35 +81,7 @@ def staticanalyzer_windows(request, api=False):
|
||||
logger.info(
|
||||
'Analysis is already Done.'
|
||||
' Fetching data from the DB...')
|
||||
context = {
|
||||
'title': db_entry[0].TITLE,
|
||||
'name': db_entry[0].APP_NAME,
|
||||
'pub_name': db_entry[0].PUB_NAME,
|
||||
'size': db_entry[0].SIZE,
|
||||
'md5': db_entry[0].MD5,
|
||||
'sha1': db_entry[0].SHA1,
|
||||
'sha256': db_entry[0].SHA256,
|
||||
'bin_name': db_entry[0].BINNAME,
|
||||
'app_version': db_entry[0].VERSION,
|
||||
'arch': db_entry[0].ARCH,
|
||||
'compiler_version': db_entry[0].COMPILER_VERSION,
|
||||
'visual_studio_version':
|
||||
db_entry[0].VISUAL_STUDIO_VERSION,
|
||||
'visual_studio_edition':
|
||||
db_entry[0].VISUAL_STUDIO_EDITION,
|
||||
'target_os': db_entry[0].TARGET_OS,
|
||||
'appx_dll_version': db_entry[0].APPX_DLL_VERSION,
|
||||
'proj_guid': db_entry[0].PROJ_GUID,
|
||||
'opti_tool': db_entry[0].OPTI_TOOL,
|
||||
'target_run': db_entry[0].TARGET_RUN,
|
||||
'files': python_list(db_entry[0].FILES),
|
||||
'strings': python_list(db_entry[0].STRINGS),
|
||||
'bin_an_results':
|
||||
python_list(db_entry[0].BIN_AN_RESULTS),
|
||||
'bin_an_warnings':
|
||||
python_list(db_entry[0].BIN_AN_WARNINGS),
|
||||
'version': settings.MOBSF_VER,
|
||||
}
|
||||
context = get_context_from_db_entry(db_entry)
|
||||
else:
|
||||
logger.info('Windows Binary Analysis Started')
|
||||
app_dic['app_path'] = os.path.join(
|
||||
@@ -123,91 +102,20 @@ def staticanalyzer_windows(request, api=False):
|
||||
logger.info('Connecting to DB')
|
||||
if rescan == '1':
|
||||
logger.info('Updating Database...')
|
||||
StaticAnalyzerWindows.objects.filter(
|
||||
MD5=app_dic['md5'],
|
||||
).update(
|
||||
TITLE='Static Analysis',
|
||||
APP_NAME=app_dic['app_name'],
|
||||
PUB_NAME=xml_dic['pub_name'],
|
||||
SIZE=app_dic['size'],
|
||||
MD5=app_dic['md5'],
|
||||
SHA1=app_dic['sha1'],
|
||||
SHA256=app_dic['sha256'],
|
||||
BINNAME=bin_an_dic['bin_name'],
|
||||
VERSION=xml_dic['version'],
|
||||
ARCH=xml_dic['arch'],
|
||||
COMPILER_VERSION=xml_dic['compiler_version'],
|
||||
VISUAL_STUDIO_VERSION=xml_dic[
|
||||
'visual_studio_version'],
|
||||
VISUAL_STUDIO_EDITION=xml_dic[
|
||||
'visual_studio_edition'],
|
||||
TARGET_OS=xml_dic['target_os'],
|
||||
APPX_DLL_VERSION=xml_dic['appx_dll_version'],
|
||||
PROJ_GUID=xml_dic['proj_guid'],
|
||||
OPTI_TOOL=xml_dic['opti_tool'],
|
||||
TARGET_RUN=xml_dic['target_run'],
|
||||
FILES=app_dic['files'],
|
||||
STRINGS=bin_an_dic['strings'],
|
||||
BIN_AN_RESULTS=bin_an_dic['results'],
|
||||
BIN_AN_WARNINGS=bin_an_dic['warnings'],
|
||||
)
|
||||
save_or_update('update',
|
||||
app_dic,
|
||||
xml_dic,
|
||||
bin_an_dic)
|
||||
update_scan_timestamp(app_dic['md5'])
|
||||
elif rescan == '0':
|
||||
logger.info('Saving to Database')
|
||||
db_item = StaticAnalyzerWindows(
|
||||
TITLE='Static Analysis',
|
||||
APP_NAME=app_dic['app_name'],
|
||||
PUB_NAME=xml_dic['pub_name'],
|
||||
SIZE=app_dic['size'],
|
||||
MD5=app_dic['md5'],
|
||||
SHA1=app_dic['sha1'],
|
||||
SHA256=app_dic['sha256'],
|
||||
BINNAME=bin_an_dic['bin_name'],
|
||||
VERSION=xml_dic['version'],
|
||||
ARCH=xml_dic['arch'],
|
||||
COMPILER_VERSION=xml_dic['compiler_version'],
|
||||
VISUAL_STUDIO_VERSION=xml_dic[
|
||||
'visual_studio_version'],
|
||||
VISUAL_STUDIO_EDITION=xml_dic[
|
||||
'visual_studio_edition'],
|
||||
TARGET_OS=xml_dic['target_os'],
|
||||
APPX_DLL_VERSION=xml_dic['appx_dll_version'],
|
||||
PROJ_GUID=xml_dic['proj_guid'],
|
||||
OPTI_TOOL=xml_dic['opti_tool'],
|
||||
TARGET_RUN=xml_dic['target_run'],
|
||||
FILES=app_dic['files'],
|
||||
STRINGS=bin_an_dic['strings'],
|
||||
BIN_AN_RESULTS=bin_an_dic['results'],
|
||||
BIN_AN_WARNINGS=bin_an_dic['warnings'],
|
||||
)
|
||||
db_item.save()
|
||||
context = {
|
||||
'title': 'Static Analysis',
|
||||
'name': app_dic['app_name'],
|
||||
'pub_name': xml_dic['pub_name'],
|
||||
'size': app_dic['size'],
|
||||
'md5': app_dic['md5'],
|
||||
'sha1': app_dic['sha1'],
|
||||
'sha256': app_dic['sha256'],
|
||||
'bin_name': bin_an_dic['bin_name'],
|
||||
'app_version': xml_dic['version'],
|
||||
'arch': xml_dic['arch'],
|
||||
'compiler_version': xml_dic['compiler_version'],
|
||||
'visual_studio_version':
|
||||
xml_dic['visual_studio_version'],
|
||||
'visual_studio_edition':
|
||||
xml_dic['visual_studio_edition'],
|
||||
'target_os': xml_dic['target_os'],
|
||||
'appx_dll_version': xml_dic['appx_dll_version'],
|
||||
'proj_guid': xml_dic['proj_guid'],
|
||||
'opti_tool': xml_dic['opti_tool'],
|
||||
'target_run': xml_dic['target_run'],
|
||||
'files': app_dic['files'],
|
||||
'strings': bin_an_dic['strings'],
|
||||
'bin_an_results': bin_an_dic['results'],
|
||||
'bin_an_warnings': bin_an_dic['warnings'],
|
||||
'version': settings.MOBSF_VER,
|
||||
}
|
||||
save_or_update('save',
|
||||
app_dic,
|
||||
xml_dic,
|
||||
bin_an_dic)
|
||||
context = get_context_from_analysis(app_dic,
|
||||
xml_dic,
|
||||
bin_an_dic)
|
||||
template = 'static_analysis/windows_binary_analysis.html'
|
||||
if api:
|
||||
return context
|
||||
@@ -211,7 +211,63 @@ div#textnode {
|
||||
vertical-align: middle;
|
||||
transition: font-size 175ms;
|
||||
}
|
||||
/* TOP NAV */
|
||||
/* Add a black background color to the top navigation */
|
||||
.topnav {
|
||||
overflow: hidden;
|
||||
background-color: #312f2f;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Style the links inside the navigation bar */
|
||||
.topnav a {
|
||||
float: left;
|
||||
color: #a7a6a6;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* Change the color of links on hover */
|
||||
.topnav a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Centered section inside the top navigation */
|
||||
.topnav-centered a {
|
||||
float: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.topnav-centered a:hover {
|
||||
background-color: #312f2f;
|
||||
}
|
||||
|
||||
/* Right-aligned section inside the top navigation */
|
||||
.topnav-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Responsive navigation menu - display links on top of each other instead of next to each other (for mobile devices) */
|
||||
@media screen and (max-width: 600px) {
|
||||
.topnav a, .topnav-right {
|
||||
float: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.topnav-centered a {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
/* PROGRESS BAR */
|
||||
|
||||
progress {
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
</ul>
|
||||
<!-- Right navbar links -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'recent' %}" class="nav-link">Recent Scans</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'home' %}" class="nav-link">Static Analysis</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'dynamic' %}" class="nav-link">Dynamic Analysis</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'api_docs' %}" class="nav-link">API Docs</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'about' %}" class="nav-link">About</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'recent' %}" class="nav-link">RECENT SCANS</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'home' %}" class="nav-link">STATIC ANALYZER</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'dynamic' %}" class="nav-link">DYNAMIC ANALYZER</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'api_docs' %}" class="nav-link">API DOCS</a></li>
|
||||
<li class="nav-item d-none d-sm-inline-block"><a href="{% url 'about' %}" class="nav-link">ABOUT</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- SEARCH FORM -->
|
||||
|
||||
@@ -295,21 +295,20 @@ div.loading{
|
||||
{% if apks %}
|
||||
{% for e in apks %}
|
||||
<tr>
|
||||
<td>
|
||||
<img id="app_icon" src="{% if e.ICON_FOUND %}/download/{{ e.MD5 }}-icon.png{% else %}{% static 'img/no_icon.png' %}{% endif %}"/><br/><strong>{{ e.REAL_NAME }}</strong>
|
||||
<td align="center">
|
||||
<img id="app_icon" src="{% if e.ICON_FOUND %}/download/{{ e.MD5 }}-icon.png{% else %}{% static 'img/no_icon.png' %}{% endif %}"/>
|
||||
<br/><strong>{{ e.APP_NAME }}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ e.APP_NAME }}<br/><br/>Hash: {{e.MD5}}
|
||||
{{ e.FILE_NAME }}
|
||||
</td>
|
||||
<td>
|
||||
{{ e.PACKAGENAME }}
|
||||
{{ e.PACKAGE_NAME }}
|
||||
</td>
|
||||
<td>
|
||||
<p align="center">
|
||||
<a class="btn btn-success" onclick="dynamic_loader()" href="../android_dynamic/?hash={{e.MD5}}&package={{e.PACKAGENAME}}"><i class="fab fa-android"></i> Start Dynamic Analysis</a>
|
||||
<td align="center">
|
||||
<a class="btn btn-success" onclick="dynamic_loader()" href="../android_dynamic/?hash={{e.MD5}}&package={{e.PACKAGE_NAME}}"><i class="fab fa-android"></i> Start Dynamic Analysis</a>
|
||||
<br/> <br/>
|
||||
<a class="btn btn-info" href="../dynamic_report/?hash={{ e.MD5 }}&package={{ e.PACKAGENAME }}"><i class="fa fa-mobile"></i> View Report </a>
|
||||
</p>
|
||||
<a class="btn btn-info" href="../dynamic_report/?hash={{ e.MD5 }}&package={{ e.PACKAGE_NAME }}"><i class="fa fa-mobile"></i> View Report </a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -95,7 +95,7 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -F 'file=@/Users/ajin/Desktop/diva-beta.apk' http://localhost:8000/api/v1/upload -H "Authorization:563d64fc5054d3b239ac0419f1d6b2378465f5c80e1778c283eb1e3265bdd7ae"
|
||||
<pre><code>curl -F 'file=@/Users/ajin/Desktop/diva-beta.apk' http://localhost:8000/api/v1/upload -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -182,7 +182,7 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/scan --data "scan_type=apk&file_name=diva-beta.apk&hash=82ab8b2193b3cfb1c737e3a786be363a" -H "Authorization:563d64fc5054d3b239ac0419f1d6b2378465f5c80e1778c283eb1e3265bdd7ae"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/scan --data "scan_type=apk&file_name=diva-beta.apk&hash=82ab8b2193b3cfb1c737e3a786be363a" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -245,7 +245,7 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/delete_scan --data "hash=82ab8b2193b3cfb1c737e3a786be363a" -H "Authorization:563d64fc5054d3b239ac0419f1d6b2378465f5c80e1778c283eb1e3265bdd7ae"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/delete_scan --data "hash=82ab8b2193b3cfb1c737e3a786be363a" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -313,7 +313,7 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/download_pdf --data "hash=82ab8b2193b3cfb1c737e3a786be363a&scan_type=apk" -H "Authorization:563d64fc5054d3b239ac0419f1d6b2378465f5c80e1778c283eb1e3265bdd7ae"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/download_pdf --data "hash=82ab8b2193b3cfb1c737e3a786be363a&scan_type=apk" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -382,7 +382,7 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/report_json --data "hash=82ab8b2193b3cfb1c737e3a786be363a&scan_type=apk" -H "Authorization:563d64fc5054d3b239ac0419f1d6b2378465f5c80e1778c283eb1e3265bdd7ae"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/report_json --data "hash=82ab8b2193b3cfb1c737e3a786be363a&scan_type=apk" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -456,9 +456,9 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/view_source --data "hash=18e244926da1e49c5b8ffc1c30de8abc&type=apk&file=b/a/a/a/a/a.java" -H "Authorization:7e2ddf418b291d2e070496524d1b8599c31637f84055c5db632f49f1a613f5f5"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/view_source --data "hash=18e244926da1e49c5b8ffc1c30de8abc&type=apk&file=b/a/a/a/a/a.java" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/view_source --data "hash=6c23c2970551be15f32bbab0b5db0c71&type=ipa&file=classdump.txt" -H "Authorization:87e2ddf418b291d2e070496524d1b8599c31637f84055c5db632f49f1a613f5f5"
|
||||
<pre><code>curl -X POST --url http://localhost:8000/api/v1/view_source --data "hash=6c23c2970551be15f32bbab0b5db0c71&type=ipa&file=classdump.txt" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -541,9 +541,9 @@ pre {
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Sample Call:</strong></p>
|
||||
<pre><code>curl --url "http://localhost:8000/api/v1/scans" -H "Authorization:87e2ddf418b291d2e070496524d1b8599c31637f84055c5db632f49f1a613f5f5"
|
||||
<pre><code>curl --url "http://localhost:8000/api/v1/scans" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
<pre><code>curl --url "http://localhost:8000/api/v1/scans?page=1&page_size=10" -H "Authorization:87e2ddf418b291d2e070496524d1b8599c31637f84055c5db632f49f1a613f5f5"
|
||||
<pre><code>curl --url "http://localhost:8000/api/v1/scans?page=1&page_size=10" -H "Authorization:{{ api_key}}"
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Mobile Security Framework (MobSF) is an automated, all-in-one mobile application (Android/iOS/Windows) pen-testing, malware analysis and security assessment framework capable of performing static and dynamic analysis.">
|
||||
<meta name="author" content="Ajin Abraham">
|
||||
<link rel="icon" href="{% static "favicon.ico" %}">
|
||||
<link rel="icon" href="{% static "img/favicon.ico" %}">
|
||||
<title>Mobile Security Framework - MobSF</title>
|
||||
<link rel="stylesheet" href="{% static "adminlte/dashboard/css/adminlte.min.css" %}">
|
||||
<link rel="stylesheet" href="{% static "adminlte/plugins/fontawesome-free/css/all.min.css" %}">
|
||||
@@ -16,12 +16,30 @@
|
||||
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
|
||||
<!-- Centered link -->
|
||||
<div class="topnav-centered">
|
||||
<a>
|
||||
<img src="{% static "img/mobsf_logo.png" %}" width="20%" height="20%"/>
|
||||
</a>
|
||||
</div>
|
||||
<!-- Left-aligned links (default) -->
|
||||
<a href="{% url 'recent' %}">RECENT SCANS</a>
|
||||
<a href="{% url 'dynamic' %}">DYNAMIC ANALYZER</a>
|
||||
|
||||
<!-- Right-aligned links -->
|
||||
<div class="topnav-right">
|
||||
<a href="{% url 'api_docs' %}">API DOCS</a>
|
||||
<a href="{% url 'about' %}">ABOUT</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="site-wrapper">
|
||||
<div class="site-wrapper-inner">
|
||||
<div class="cover-container">
|
||||
<div class="masthead clearfix">
|
||||
<div align="center" class="inner">
|
||||
<h3 class="masthead-brand"><img src="{% static "img/mobsf_logo.png" %}" width="45%" height="45%"></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inner cover">
|
||||
@@ -47,7 +65,7 @@
|
||||
<input name="md5" type="text" class="form-control" placeholder="Search MD5">
|
||||
</form>
|
||||
<div class="inner">
|
||||
<h5><strong> <a href="{% url 'recent' %}">RECENT SCANS</a> | <a href="{% url 'dynamic' %}">DYNAMIC ANALYSIS</a> | <a href="{% url 'api_docs' %}">API DOCS</a> | <a href="{% url 'about' %}">ABOUT</a></strong></h5>
|
||||
<h6> <a href="{% url 'recent' %}">RECENT SCANS</a> | <a href="{% url 'dynamic' %}">DYNAMIC ANALYZER</a> | <a href="{% url 'api_docs' %}">API DOCS</a> | <a href="{% url 'about' %}">ABOUT</a></h6>
|
||||
</br>
|
||||
<p>© {% now "Y" %} Mobile Security Framework - MobSF {{ version }}</p>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ body {
|
||||
}
|
||||
|
||||
</style>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{name}} </h1>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{file_name}} </h1>
|
||||
<hr>
|
||||
<div class="col-lg-2">
|
||||
<div class="panel panel-default">
|
||||
@@ -21,9 +21,9 @@ body {
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Security Score: </b>{{ security_score }}/100</span>
|
||||
</p>
|
||||
{% if VT_RESULT and VT_RESULT.total %}
|
||||
{% if virus_total and virus_total.total %}
|
||||
<p>
|
||||
<span class="label label-primary"><b>VirusTotal Detection: </b>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</span>
|
||||
<span class="label label-primary"><b>VirusTotal Detection: </b>{{ virus_total.positives }}/{{ virus_total.total }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if trackers %}
|
||||
@@ -45,8 +45,8 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>Name: </b></span>
|
||||
{{ name }}
|
||||
<span class="label label-primary"><b>File Name: </b></span>
|
||||
{{ file_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Size:</b></span>
|
||||
@@ -76,32 +76,32 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>Name: </b></span>
|
||||
{{ real_name }}
|
||||
<span class="label label-primary"><b>App Name: </b></span>
|
||||
{{ app_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Package Name: </b></span>
|
||||
{{ packagename }}
|
||||
{{ package_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Main Activity: </b></span>
|
||||
{{ mainactivity }}
|
||||
{{ main_activity }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Target SDK: </b></span>
|
||||
{{ targetsdk }}
|
||||
{{ target_sdk }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Min SDK: </b></span>
|
||||
{{ minsdk }}
|
||||
{{ min_sdk }}
|
||||
</p><p>
|
||||
|
||||
<span class="label label-primary"><b>Max SDK: </b></span>
|
||||
{{ maxsdk }}
|
||||
{{ max_sdk }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Android Version Name: </b></span>
|
||||
{{ androvername }}
|
||||
{{ version_name }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Android Version Code: </b></span>
|
||||
{{ androver }}
|
||||
{{ version_code }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -118,50 +118,50 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
|
||||
{% if not play_details.error %}
|
||||
{% if not playstore_details.error %}
|
||||
<p>
|
||||
<span class="label label-info"><b>Title: </b></span>
|
||||
{{ play_details.title }}
|
||||
{{ playstore_details.title }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Score: </b></span>
|
||||
{{ play_details.score}}
|
||||
{{ playstore_details.score}}
|
||||
|
||||
<span class="label label-info"><b>Installs: </b></span>
|
||||
{{ play_details.installs }}
|
||||
{{ playstore_details.installs }}
|
||||
|
||||
<span class="label label-info"><b>Price: </b></span>
|
||||
{{ play_details.price }}
|
||||
{{ playstore_details.price }}
|
||||
|
||||
<span class="label label-info"><b>Android Version Support: </b></span>
|
||||
{{ play_details.androidVersionText }}
|
||||
{{ playstore_details.androidVersionText }}
|
||||
|
||||
<span class="label label-info"><b>Category: </b></span>
|
||||
{{ play_details.genre }}
|
||||
{{ playstore_details.genre }}
|
||||
|
||||
<span class="label label-info"><b>Play Store URL: </b></span>
|
||||
<a target="_blank" href="{{ play_details.url }}"> {{ packagename }} </a>
|
||||
<a target="_blank" href="{{ playstore_details.url }}"> {{ packagename }} </a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span class="label label-info"><b>Developer Details: </b></span>
|
||||
{{play_details.developer}},
|
||||
{{play_details.developerId}},
|
||||
{{play_details.developerAddress }},
|
||||
{{play_details.developerWebsite}},
|
||||
{{play_details.developerEmail}},
|
||||
{{playstore_details.developer}},
|
||||
{{playstore_details.developerId}},
|
||||
{{playstore_details.developerAddress }},
|
||||
{{playstore_details.developerWebsite}},
|
||||
{{playstore_details.developerEmail}},
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Release Date: </b></span>
|
||||
{{ play_details.released }}
|
||||
{{ playstore_details.released }}
|
||||
<span class="label label-info"><b>Privacy Policy: </b></span>
|
||||
<a target="_blank" href="{{ play_details.privacyPolicy }}">Privacy link</a>
|
||||
<a target="_blank" href="{{ playstore_details.privacyPolicy }}">Privacy link</a>
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Description: </b></span>
|
||||
<pre>{{ play_details.description }}</pre>
|
||||
<pre>{{ playstore_details.description }}</pre>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -174,29 +174,25 @@ body {
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i> <span class="glyphicon glyphicon-eye-close"></span> CERTIFICATE</h3><hr>
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i> <span class="glyphicon glyphicon-eye-close"></span> SIGNER CERTIFICATE</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<pre>
|
||||
{{ certinfo | safe}}
|
||||
|
||||
{% if issued == "good" %}
|
||||
<strong>Certificate Status: </strong><span class="label label-success">Good</span>
|
||||
{% elif issued == "bad" %}
|
||||
<strong>Certificate Status: </strong><span class="label label-danger">Bad</span>
|
||||
<strong>Description:</strong>App Signed by 'Android Debug' Certificate.
|
||||
Production ready applications should not be signed with 'Android Debug' Certificate.
|
||||
{% elif issued == "missing" %}
|
||||
<strong>Certificate Status: </strong><span class="label label-warning">Certificate not found</span>
|
||||
{% elif issued == "bad hash" and sha256Digest is True %}
|
||||
<strong>Certificate Status: </strong><span class="label label-warning">Warning</span>
|
||||
<strong>Description:</strong>The app is signed with `SHA1withRSA`. SHA1 hash algorithm is known to have collision issues.
|
||||
<strong>Note:</strong>The manifest indicates `SHA256withRSA` is in use. Be sure to manually confirm this issue.
|
||||
{% elif issued == "bad hash" %}
|
||||
<strong>Certificate Status: </strong><span class="label label-danger">Bad</span>
|
||||
<strong>Description:</strong>The app is signed with `SHA1withRSA`. SHA1 hash algorithm is known to have collision issues.
|
||||
{% endif %}
|
||||
</pre>
|
||||
<pre><code>{{ certificate_analysis.certificate_info }}</code></pre>
|
||||
<!--Cert status-->
|
||||
{% if certificate_analysis.certificate_status == "good" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-success">Good</span><br />
|
||||
<strong>Description: </strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "bad" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-danger">Bad</span><br />
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "missing" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-warning">Certificate missing</span><br />
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "warning" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-warning">Warning</span><br />
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -296,15 +292,15 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
<hr>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-bug"></i>VirusTotal Report</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p> {{ VT_RESULT.positives }} / {{ VT_RESULT.total }} AVs found this file Malicious! </p>
|
||||
{% if VT_RESULT.positives %}
|
||||
<p> {{ virus_total.positives }} / {{ virus_total.total }} AVs found this file Malicious! </p>
|
||||
{% if virus_total.positives %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
@@ -314,7 +310,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for av_name,av_result in VT_RESULT.scans.items %}
|
||||
{% for av_name,av_result in virus_total.scans.items %}
|
||||
{% if av_result.detected == True %}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -507,7 +503,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in manifest %}
|
||||
{% for item in manifest_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{item|key:"title" | safe}}
|
||||
@@ -560,7 +556,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in findings.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -612,7 +608,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in android_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
@@ -681,7 +677,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
@@ -692,7 +688,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
<tbody>
|
||||
|
||||
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -847,7 +843,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
{% if certz %}
|
||||
{% if file_analysis %}
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -856,7 +852,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in certz %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item|key:"finding" }}
|
||||
@@ -875,28 +871,7 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr><div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span> STRINGS</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
|
||||
{% for val in strings %}
|
||||
|
||||
{{ val }}<br>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="col-lg-5">
|
||||
<div class="panel panel-default">
|
||||
@@ -985,23 +960,6 @@ Production ready applications should not be signed with 'Android Debug' Certific
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div><hr> <div class="col-lg-7">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-folder-open"></span> FILES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for file in files %}
|
||||
{{ file}} <br>
|
||||
{% endfor %}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@ body {
|
||||
}
|
||||
|
||||
</style>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{name}} </h1>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{file_name}} </h1>
|
||||
<hr>
|
||||
<div class="col-lg-2">
|
||||
<div class="panel panel-default">
|
||||
@@ -36,8 +36,8 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>Name: </b></span>
|
||||
{{ name }}
|
||||
<span class="label label-primary"><b>File Name: </b></span>
|
||||
{{ file_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Size: </b></span>
|
||||
@@ -67,31 +67,31 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary">Name</span>
|
||||
{{ real_name }}
|
||||
<span class="label label-primary">App Name</span>
|
||||
{{ app_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Package Name: </b></span>
|
||||
{{ packagename }}
|
||||
{{ package_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Main Activity: </b></span>
|
||||
{{ mainactivity }}
|
||||
{{ main_activity }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Target SDK: </b></span>
|
||||
{{ targetsdk }}
|
||||
{{ target_sdk }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Min SDK: </b></span>
|
||||
{{ minsdk }}
|
||||
{{ min_sdk }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Max SDK: </b></span>
|
||||
{{ maxsdk }}
|
||||
{{ max_sdk }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Android Version Name: </b></span>
|
||||
{{ androvername }}
|
||||
{{ version_name }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Android Version Code: </b></span>
|
||||
{{ androver }}
|
||||
{{ version_code }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -108,48 +108,47 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
|
||||
{% if not play_details.error %}
|
||||
{% if not playstore_details.error %}
|
||||
<p>
|
||||
<span class="label label-info"><b>Title: </b></span>
|
||||
{{ play_details.title }}
|
||||
{{ playstore_details.title }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Score: </b></span>
|
||||
{{ play_details.score}}
|
||||
{{ playstore_details.score}}
|
||||
|
||||
<span class="label label-info"><b>Installs: </b></span>
|
||||
{{ play_details.installs }}
|
||||
{{ playstore_details.installs }}
|
||||
|
||||
<span class="label label-info"><b>Price: </b></span>
|
||||
{{ play_details.price }}
|
||||
{{ playstore_details.price }}
|
||||
|
||||
<span class="label label-info"><b>Android Version Support: </b></span>
|
||||
{{ play_details.required_android_version }}
|
||||
{{ playstore_details.required_android_version }}
|
||||
|
||||
<span class="label label-info"><b>Category: </b></span>
|
||||
{{ play_details.genre }
|
||||
|
||||
{{ playstore_details.genre }}
|
||||
<span class="label label-info"><b>Play Store URL: </b></span>
|
||||
<a target="_blank" href="{{ play_details.url }}"> {{ packagename }} </a>
|
||||
<a target="_blank" href="{{ playstore_details.url }}"> {{ packagename }} </a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span class="label label-info"><b>Developer Details: </b></span>
|
||||
{{play_details.developer}},
|
||||
{{play_details.developerId}},
|
||||
{{play_details.developerAddress }},
|
||||
{{play_details.developerWebsite}},
|
||||
{{play_details.developerEmail}},
|
||||
{{playstore_details.developer}},
|
||||
{{playstore_details.developerId}},
|
||||
{{playstore_details.developerAddress }},
|
||||
{{playstore_details.developerWebsite}},
|
||||
{{playstore_details.developerEmail}},
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Release Date: </b></<span>
|
||||
{{ play_details.released }}
|
||||
<span class="label label-info"><b>Release Date: </b> </<span>
|
||||
{{ playstore_details.released }}
|
||||
<span class="label label-info"><b>Privacy Policy: </b></span>
|
||||
<a target="_blank" href="{{ play_details.privacyPolicy }}">Privacy link</a>
|
||||
<a target="_blank" href="{{ playstore_details.privacyPolicy }}">Privacy link</a>
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-info"><b>Description: </b></span>
|
||||
<pre>{{ play_details.description }}</pre>
|
||||
<pre>{{ playstore_details.description }}</pre>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -282,7 +281,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in manifest %}
|
||||
{% for item in manifest_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{item|key:"title" | safe}}
|
||||
@@ -332,7 +331,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in findings.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -353,7 +352,7 @@ body {
|
||||
<td><b>{{ details|key:"owasp" }}</b></td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
</br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -384,14 +383,14 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in android_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
</td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
</br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -431,7 +430,7 @@ body {
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{zipped}}">{{urldict|key:"path"}}</a>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{app_type}}">{{urldict|key:"path"}}</a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
@@ -454,7 +453,7 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
@@ -465,7 +464,7 @@ body {
|
||||
<tbody>
|
||||
|
||||
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -589,7 +588,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in certz %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item|key:"finding" }}
|
||||
@@ -700,24 +699,7 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr> <div class="col-lg-7">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-folder-open"></span> FILES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for file in files %}
|
||||
{{ file}} <br>
|
||||
{% endfor %}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<hr><hr>
|
||||
<h3 align="center"> Report Generated by - MobSF | http://opensecurity.in</h3>
|
||||
|
||||
@@ -20,9 +20,9 @@ body {
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Security Score: </b>{{ security_score }}/100</span>
|
||||
</p>
|
||||
{% if VT_RESULT and VT_RESULT.total %}
|
||||
{% if virus_total and virus_total.total %}
|
||||
<p>
|
||||
<span class="label label-primary"><b>VirusTotal Detection: </b>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</span>
|
||||
<span class="label label-primary"><b>VirusTotal Detection: </b>{{ virus_total.positives }}/{{ virus_total.total }}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
@@ -46,7 +46,7 @@ body {
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Type:</b></span>
|
||||
{{ bin_type }}
|
||||
{{ app_type }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Size: </b></span>
|
||||
@@ -95,26 +95,32 @@ body {
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Name: </b></span>
|
||||
{{ bin_name }}
|
||||
{{ app_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Identifier: </b></span>
|
||||
{{ id }}</p>
|
||||
{{ bundle_id }}</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Version: </b></span>
|
||||
{{ bundle_version }}
|
||||
{{ app_version }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Build: </b></span>
|
||||
{{ build }}
|
||||
{{ build }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>SDK Name: </b></span>
|
||||
{{ sdk }}</p><p>
|
||||
{{ sdk_name }}</p><p>
|
||||
<span class="label label-primary"><b>Platform Version: </b></span>
|
||||
{{ pltfm }}</p><p>
|
||||
{{ platform }}</p><p>
|
||||
<span class="label label-primary"><b>Min OS Version: </b></span>
|
||||
{{ min }}
|
||||
{{ min_os_version }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="badge bg-primary">Supported Platforms</span>
|
||||
{% for pl in bundle_supported_platforms %}
|
||||
{{pl}},
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -185,7 +191,53 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="fa fa-mobile"></span> URL SCHEMES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if bundle_url_types|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL NAME</th>
|
||||
<th>SCHEMES</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for scheme in bundle_url_types %}
|
||||
<tr>
|
||||
<td>
|
||||
{{scheme | key:"CFBundleURLName" }}
|
||||
{% if scheme|key:"CFBundleTypeRole" %}
|
||||
<br>
|
||||
{{scheme | key:"CFBundleTypeRole" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for ul in scheme.CFBundleURLSchemes %}
|
||||
{{ul}} <br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No URL Schemes found.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
@@ -203,7 +255,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for perm in permissions%}
|
||||
{% for perm in permissions %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ perm.name }}
|
||||
@@ -240,42 +292,43 @@ body {
|
||||
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ISSUE</th>
|
||||
<th>STATUS</th>
|
||||
<th>DESCRIPTION</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if insecure_connections|length > 0 %}
|
||||
{%for con in insecure_connections%}
|
||||
<tr>
|
||||
<td>
|
||||
Exception in NSAppTransportSecurity found.
|
||||
<td>
|
||||
Insecure
|
||||
</td>
|
||||
<td>
|
||||
App Transport Security (ATS) is disabled on the domain '{{ con }}'. Disabling ATS can allow insecure communication with particular servers or allow insecure loads for web views or for media, while maintaining ATS protections elsewhere in your app.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
None
|
||||
<td>
|
||||
Secure
|
||||
</td>
|
||||
<td>
|
||||
No insecure connections configured. App Transport Security (ATS) is enabled.
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ISSUE</th>
|
||||
<th>STATUS</th>
|
||||
<th>DESCRIPTION</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if ats_analysis|length > 0 %}
|
||||
{% for findings in ats_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{findings.issue}}
|
||||
<td>
|
||||
<span class="badge bg-danger"> {{findings.status}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{findings.description}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
No ATS exceptions found.
|
||||
<td>
|
||||
<span class="badge bg-success">secure</span>
|
||||
</td>
|
||||
<td>
|
||||
No insecure connections configured. App Transport Security (ATS) is enabled.
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
@@ -283,15 +336,15 @@ body {
|
||||
</div><hr>
|
||||
|
||||
<!-- ============================================================= -->
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-bug"></i>VirusTotal Report</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p> {{ VT_RESULT.positives }} / {{ VT_RESULT.total }} AVs found this file Malicious! </p>
|
||||
{% if VT_RESULT.positives %}
|
||||
<p> {{ virus_total.positives }} / {{ virus_total.total }} AVs found this file Malicious! </p>
|
||||
{% if virus_total.positives %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
@@ -301,7 +354,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for av_name,av_result in VT_RESULT.scans.items %}
|
||||
{% for av_name,av_result in virus_total.scans.items %}
|
||||
{% if av_result.detected == True %}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -342,7 +395,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for bin in bin_anal%}
|
||||
{% for bin in binary_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ bin.issue }}
|
||||
@@ -393,7 +446,7 @@ body {
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{%for item in file_analysis %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.issue }}
|
||||
@@ -423,7 +476,7 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for lib in libs %}
|
||||
{% for lib in libraries %}
|
||||
{{ lib }}
|
||||
</br>
|
||||
{% endfor %}
|
||||
@@ -433,44 +486,6 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span> STRINGS</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for string in strings %}
|
||||
{{string | safe}} </br>
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-folder-open"></span> FILES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for file in files %}
|
||||
{{ file}} <br>
|
||||
{% endfor %}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr><hr>
|
||||
<h3 align="center"> Report Generated by - MobSF | http://opensecurity.in</h3>
|
||||
|
||||
|
||||
@@ -70,14 +70,14 @@ body {
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Name: </b></span>
|
||||
{{ bin_name }}
|
||||
{{ app_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Identifier: </b></span>
|
||||
{{ id }}
|
||||
{{ bundle_id }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Version: </b></span>
|
||||
{{ bundle_version }}
|
||||
{{ app_version }}
|
||||
|
||||
</p>
|
||||
<p>
|
||||
@@ -86,13 +86,18 @@ body {
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>SDK Name: </b></span>
|
||||
{{ sdk }}</p><p>
|
||||
{{ sdk_name }}</p><p>
|
||||
<span class="label label-primary"><b>Platform Version: </b></span>
|
||||
{{ pltfm }}
|
||||
{{ platform }}
|
||||
</p><p>
|
||||
<span class="label label-primary"><b>Min OS Version: </b></span>
|
||||
{{ min }}
|
||||
{{ min_os_version }}
|
||||
|
||||
</p> <p>
|
||||
<span class="badge bg-primary">Supported Platforms</span>
|
||||
{% for pl in bundle_supported_platforms %}
|
||||
{{pl}},
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
@@ -163,6 +168,51 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="fa fa-mobile"></span> URL SCHEMES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if bundle_url_types|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL NAME</th>
|
||||
<th>SCHEMES</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for scheme in bundle_url_types %}
|
||||
<tr>
|
||||
<td>
|
||||
{{scheme | key:"CFBundleURLName" }}
|
||||
{% if scheme|key:"CFBundleTypeRole" %}
|
||||
<br>
|
||||
{{scheme | key:"CFBundleTypeRole" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for ul in scheme.CFBundleURLSchemes %}
|
||||
{{ul}} <br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No URL Schemes found.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div> <hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
@@ -171,30 +221,32 @@ body {
|
||||
<div class="panel-body">
|
||||
{% if permissions|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Permissions</th>
|
||||
<th>Description</th>
|
||||
<th>Reason in Manifest</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for perm in permissions%}
|
||||
<tr>
|
||||
<td>
|
||||
{{ perm.0 | safe }}
|
||||
</td>
|
||||
<td>
|
||||
{{ perm.1 | safe }}
|
||||
</td>
|
||||
<td>
|
||||
{{ perm.2 | safe }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>PERMISSIONS</th>
|
||||
<th>DESCRIPTION</th>
|
||||
<th>REASON IN MANIFEST</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for perm in permissions %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ perm.name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ perm.description}}
|
||||
</td>
|
||||
<td>
|
||||
{{ perm.reason }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="list-group">
|
||||
@@ -217,41 +269,42 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ISSUE</th>
|
||||
<th>STATUS</th>
|
||||
<th>DESCRIPTION</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if insecure_connections|length > 0 %}
|
||||
{%for con in insecure_connections%}
|
||||
<tr>
|
||||
<td>
|
||||
Exception in NSAppTransportSecurity found.
|
||||
<td>
|
||||
Insecure
|
||||
</td>
|
||||
<td>
|
||||
App Transport Security (ATS) is disabled on the domain '{{ con }}'. Disabling ATS can allow insecure communication with particular servers or allow insecure loads for web views or for media, while maintaining ATS protections elsewhere in your app.
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
None
|
||||
<td>
|
||||
Secure
|
||||
</td>
|
||||
<td>
|
||||
No insecure connections configured. App Transport Security (ATS) is enabled.
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ISSUE</th>
|
||||
<th>STATUS</th>
|
||||
<th>DESCRIPTION</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if ats_analysis|length > 0 %}
|
||||
{% for findings in ats_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{findings.issue}}
|
||||
<td>
|
||||
<span class="badge bg-danger"> {{findings.status}}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{findings.description}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
No ATS exceptions found.
|
||||
<td>
|
||||
<span class="badge bg-success">secure</span>
|
||||
</td>
|
||||
<td>
|
||||
No insecure connections configured. App Transport Security (ATS) is enabled.
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
@@ -280,7 +333,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in insecure.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -333,7 +386,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in ios_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
@@ -403,7 +456,7 @@ body {
|
||||
<div class="panel-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL</th>
|
||||
@@ -414,7 +467,7 @@ body {
|
||||
<tbody>
|
||||
|
||||
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -538,7 +591,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{%for item in file_analysis %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.issue }}
|
||||
@@ -559,25 +612,6 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-folder-open"></span> FILES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for file in files %}
|
||||
{{ file}} <br>
|
||||
{% endfor %}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr><hr>
|
||||
<h3 align="center"> Report Generated by - MobSF | http://opensecurity.in</h3>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ body {
|
||||
}
|
||||
|
||||
</style>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{name}} </h1>
|
||||
<h1 align="center" class="page-header">Static Analysis - {{file_name}} </h1>
|
||||
<hr>
|
||||
<div class="col-lg-7">
|
||||
<div class="panel panel-default">
|
||||
@@ -18,7 +18,7 @@ body {
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>File Name: </b></span>
|
||||
{{ name }}
|
||||
{{ file_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Size: </b></span>
|
||||
@@ -49,11 +49,11 @@ body {
|
||||
<div class="list-group">
|
||||
<p>
|
||||
<span class="label label-primary"><b>App Name: </b></span>
|
||||
{{ bin_name }}
|
||||
{{ app_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Publisher: </b></span>
|
||||
{{ pub_name }}
|
||||
<span class="label label-primary"><b>Publisher: </b></span>
|
||||
{{ publisher_name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Version: </b></span>
|
||||
@@ -61,7 +61,7 @@ body {
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-primary"><b>Arch: </b></span>
|
||||
{{ arch }}
|
||||
{{ architecture }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,7 +133,7 @@ body {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for result in bin_an_results %}
|
||||
{% for result in binary_analysis %}
|
||||
<tr>
|
||||
<td>{{ result.rule_id }}</td>
|
||||
<td>
|
||||
@@ -152,7 +152,7 @@ body {
|
||||
<td>{{ result.desc }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for warn in bin_an_warnings %}
|
||||
{% for warn in binary_warnings %}
|
||||
<tr>
|
||||
<td>{{ warn.rule_id }}</td>
|
||||
<td>
|
||||
@@ -170,39 +170,8 @@ body {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span> STRINGS</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for string in strings %}
|
||||
{{string | safe}} </br>
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
<hr><hr>
|
||||
<h3 align="center"> Report Generated by - MobSF | http://opensecurity.in</h3>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title"><i class="fa fa-clock-o fa-fw"></i><span class="glyphicon glyphicon-folder-open"></span> FILES</h3><hr>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for file in files %}
|
||||
{{ file}} <br>
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -145,7 +145,7 @@
|
||||
<p>APKiD Analysis</p>
|
||||
</a>
|
||||
</li>
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<li class="nav-item">
|
||||
<a href="#virus_total" class="nav-link">
|
||||
<i class="fas fa-spider nav-icon"></i>
|
||||
@@ -267,7 +267,7 @@
|
||||
</li>
|
||||
{% if dynamic_analysis_done %}
|
||||
<li class="nav-item">
|
||||
<a href="../dynamic_report/?hash={{ md5 }}&package={{ packagename }}" class="nav-link">
|
||||
<a href="../dynamic_report/?hash={{ md5 }}&package={{ package_name }}" class="nav-link">
|
||||
<i class="nav-icon fas fa-file-alt"></i>
|
||||
<p>
|
||||
Dynamic Analysis Report
|
||||
@@ -276,7 +276,7 @@
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a href="../android_dynamic/?hash={{md5}}&package={{packagename}}" class="nav-link">
|
||||
<a href="../android_dynamic/?hash={{md5}}&package={{package_name}}" class="nav-link">
|
||||
<i class="nav-icon fa fa-play-circle"></i>
|
||||
<p>
|
||||
Start Dynamic Analysis
|
||||
@@ -331,18 +331,18 @@
|
||||
{% else %}
|
||||
<span class="badge bg-success">Trackers Detection</span> <strong>{{ trackers.detected_trackers }}/{{ trackers.total_trackers }}</strong><br/>
|
||||
{% endif %}
|
||||
{% if VT_RESULT %}
|
||||
{% if VT_RESULT.positives > 0 %}
|
||||
<span class="badge bg-danger">VirusTotal Detection</span> <strong>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</strong><br/>
|
||||
{% if virus_total %}
|
||||
{% if virus_total.positives > 0 %}
|
||||
<span class="badge bg-danger">VirusTotal Detection</span> <strong>{{ virus_total.positives }}/{{ virus_total.total }}</strong><br/>
|
||||
{% else %}
|
||||
<span class="badge bg-success">VirusTotal Detection</span> <strong>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</strong><br/>
|
||||
<span class="badge bg-success">VirusTotal Detection</span> <strong>{{ virus_total.positives }}/{{ virus_total.total }}</strong><br/>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p><strong><i class="fas fa-box-open"></i> FILE INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">File Name</span>
|
||||
{{ name }}<br/>
|
||||
{{ file_name }}<br/>
|
||||
<span class="badge bg-primary">Size</span>
|
||||
{{ size }}<br/>
|
||||
<span class="badge bg-primary">MD5</span>
|
||||
@@ -355,21 +355,21 @@
|
||||
<div class="col-4">
|
||||
<p><strong><i class="fas fa-info"></i> APP INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">App Name</span>
|
||||
{{ real_name }}<br/>
|
||||
{{ app_name }}<br/>
|
||||
<span class="badge bg-primary">Package Name</span>
|
||||
{{ packagename }}<br/>
|
||||
{{ package_name }}<br/>
|
||||
<span class="badge bg-primary">Main Activity</span>
|
||||
{{ mainactivity }}<br/>
|
||||
{{ main_activity }}<br/>
|
||||
<span class="badge bg-primary">Target SDK</span>
|
||||
{{ targetsdk }}
|
||||
{{ target_sdk }}
|
||||
<span class="badge bg-primary">Min SDK</span>
|
||||
{{ minsdk }}
|
||||
{{ min_sdk }}
|
||||
<span class="badge bg-primary">Max SDK</span>
|
||||
{{ maxsdk }}<br/>
|
||||
{{ max_sdk }}<br/>
|
||||
<span class="badge bg-primary">Android Version Name</span>
|
||||
{{ androvername }}
|
||||
{{ version_name }}
|
||||
<span class="badge bg-primary">Android Version Code</span>
|
||||
{{ androver }}
|
||||
{{ version_code }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -377,7 +377,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Play Store -->
|
||||
{% if not play_details.error %}
|
||||
{% if not playstore_details.error %}
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@@ -385,38 +385,38 @@
|
||||
<strong><i class="fab fa-google-play"></i> PLAYSTORE INFORMATION</strong>
|
||||
</p>
|
||||
<span class="badge bg-info">Title</span>
|
||||
{{ play_details.title }} <br/>
|
||||
{{ playstore_details.title }} <br/>
|
||||
<span class="badge bg-info">Score</span>
|
||||
{{ play_details.score}}
|
||||
{{ playstore_details.score}}
|
||||
<span class="badge bg-info">Installs</span>
|
||||
{{ play_details.installs }}
|
||||
{{ playstore_details.installs }}
|
||||
<span class="badge bg-info">Price</span>
|
||||
{{ play_details.price }}
|
||||
{{ playstore_details.price }}
|
||||
<span class="badge bg-info">Android Version Support</span>
|
||||
{{ play_details.androidVersionText }}
|
||||
{{ playstore_details.androidVersionText }}
|
||||
<span class="badge bg-info">Category</span>
|
||||
{{ play_details.genre }}
|
||||
{{ playstore_details.genre }}
|
||||
<span class="badge bg-info">Play Store URL</span>
|
||||
<a target="_blank" href="{{ play_details.url }}"> {{ packagename }} </a>
|
||||
<a target="_blank" href="{{ playstore_details.url }}"> {{ package_name }} </a>
|
||||
<br/>
|
||||
<span class="badge bg-info">Developer</span>
|
||||
{{play_details.developer}},
|
||||
{{playstore_details.developer}},
|
||||
<span class="badge bg-info">Developer ID</span>
|
||||
{{play_details.developerId}} <br/>
|
||||
{{playstore_details.developerId}} <br/>
|
||||
<span class="badge bg-info">Developer Address</span>
|
||||
{{play_details.developerAddress}} <br/>
|
||||
{{playstore_details.developerAddress}} <br/>
|
||||
<span class="badge bg-info">Developer Website</span>
|
||||
{{play_details.developerWebsite}} <br/>
|
||||
{{playstore_details.developerWebsite}} <br/>
|
||||
<span class="badge bg-info">Developer Email</span>
|
||||
{{play_details.developerEmail}}
|
||||
{{playstore_details.developerEmail}}
|
||||
<br/>
|
||||
<span class="badge bg-info">Release Date</span>
|
||||
{{ play_details.released }}
|
||||
{{ playstore_details.released }}
|
||||
<span class="badge bg-info">Privacy Policy</span>
|
||||
<a target="_blank" href="{{ play_details.privacyPolicy }}">Privacy link</a>
|
||||
<a target="_blank" href="{{ playstore_details.privacyPolicy }}">Privacy link</a>
|
||||
<br/>
|
||||
<span class="badge bg-info">Description</span>
|
||||
<pre id="pre-wrap">{{ play_details.description }}</pre>
|
||||
<pre id="pre-wrap">{{ playstore_details.description }}</pre>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
</div>
|
||||
@@ -440,7 +440,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-info">
|
||||
<div class="inner">
|
||||
<h3>{{ act_count }}</h3>
|
||||
<h3>{{ activities | length }}</h3>
|
||||
|
||||
<p>ACTIVITIES</p>
|
||||
</div>
|
||||
@@ -455,7 +455,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-success">
|
||||
<div class="inner">
|
||||
<h3>{{ serv_count }}</h3>
|
||||
<h3>{{ services | length }}</h3>
|
||||
|
||||
<p>SERVICES</p>
|
||||
</div>
|
||||
@@ -470,7 +470,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-warning">
|
||||
<div class="inner">
|
||||
<h3>{{ bro_count }}</h3>
|
||||
<h3>{{ receivers | length }}</h3>
|
||||
|
||||
<p>RECEIVERS</p>
|
||||
</div>
|
||||
@@ -485,7 +485,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-danger">
|
||||
<div class="inner">
|
||||
<h3>{{ prov_count }}</h3>
|
||||
<h3>{{ providers | length }}</h3>
|
||||
|
||||
<p>PROVIDERS</p>
|
||||
</div>
|
||||
@@ -503,7 +503,7 @@
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Activities</span>
|
||||
<span class="info-box-number">
|
||||
{{ e_act }}
|
||||
{{ exported_count.exported_activities }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
@@ -517,7 +517,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Services</span>
|
||||
<span class="info-box-number">{{ e_ser }}</span>
|
||||
<span class="info-box-number">{{ exported_count.exported_services }}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -534,7 +534,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Receivers</span>
|
||||
<span class="info-box-number">{{e_bro}}</span>
|
||||
<span class="info-box-number">{{ exported_count.exported_receivers }}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -547,7 +547,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Providers</span>
|
||||
<span class="info-box-number">{{e_cnt}}</span>
|
||||
<span class="info-box-number">{{exported_count.exported_providers}}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -575,9 +575,9 @@
|
||||
<p>
|
||||
<strong><i class="fas fa-cog"></i> SCAN OPTIONS</strong>
|
||||
</p>
|
||||
<p> <a href="../StaticAnalyzer/?checksum={{ md5 }}&name={{ name }}&type=apk&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a></p>
|
||||
<p> <a href="../StaticAnalyzer/?checksum={{ md5 }}&name={{ file_name }}&type=apk&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a></p>
|
||||
<p>
|
||||
<a href="../android_dynamic/?hash={{md5}}&package={{packagename}}" class="btn btn-success" role="button"><i class="fa fa-play-circle"></i> Start Dynamic Analysis</a>
|
||||
<a href="../android_dynamic/?hash={{md5}}&package={{package_name}}" class="btn btn-success" role="button"><i class="fa fa-play-circle"></i> Start Dynamic Analysis</a>
|
||||
</p>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
@@ -589,8 +589,8 @@
|
||||
<strong><i class="fas fa-file-code"></i> DECOMPILED CODE</strong>
|
||||
</p>
|
||||
<p>
|
||||
<a target="_blank" href="{{mani}}" role="button" class="btn btn-primary"><i class="fa fa-eye"></i> View AndroidManifest.xml</a>
|
||||
<a href="../Java/?md5={{ md5 }}&type={{ zipped }}" class="btn btn-info" role="button"><i class="fa fa-code"></i> View Java</a>
|
||||
<a target="_blank" href="../ManifestView/?md5={{ md5 }}&type={{ app_type }}&bin=1" role="button" class="btn btn-primary"><i class="fa fa-eye"></i> View AndroidManifest.xml</a>
|
||||
<a href="../Java/?md5={{ md5 }}&type={{ app_type }}" class="btn btn-info" role="button"><i class="fa fa-code"></i> View Java</a>
|
||||
<a href="../Smali/?md5={{ md5 }}" class="btn btn-info" role="button"><i class="fa fa-code"></i> View Smali</a>
|
||||
</p>
|
||||
<p>
|
||||
@@ -617,23 +617,20 @@
|
||||
<p>
|
||||
<strong><i class="fa fa-certificate"></i> SIGNER CERTIFICATE</strong>
|
||||
</p>
|
||||
<pre><code>{{ certinfo }}</code></pre>
|
||||
<pre><code>{{ certificate_analysis.certificate_info }}</code></pre>
|
||||
<!--Cert status-->
|
||||
{% if issued == "good" %}
|
||||
{% if certificate_analysis.certificate_status == "good" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-success">Good</span><br />
|
||||
{% elif issued == "bad" %}
|
||||
<strong>Description: </strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "bad" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-danger">Bad</span><br />
|
||||
<strong>Description:</strong>App Signed by <code>Android Debug</code> Certificate.
|
||||
Production ready applications should not be signed with <code>Android Debug</code> Certificate.<br />
|
||||
{% elif issued == "missing" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-warning">Certificate not found</span><br />
|
||||
{% elif issued == "bad hash" and sha256Digest is True %}
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "missing" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-warning">Certificate missing</span><br />
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% elif certificate_analysis.certificate_status == "warning" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-warning">Warning</span><br />
|
||||
<strong>Description:</strong>The app is signed with <code>SHA1withRSA</code>. SHA1 hash algorithm is known to have collision issues.<br />
|
||||
<strong>Note:</strong>The manifest indicates <code>SHA256withRSA</code> is in use. Be sure to manually confirm this issue.<br />
|
||||
{% elif issued == "bad hash" %}
|
||||
<strong>Certificate Status: </strong><span class="badge bg-danger">Bad</span> <br />
|
||||
<strong>Description:</strong>The app is signed with <code>SHA1withRSA</code>. SHA1 hash algorithm is known to have collision issues.
|
||||
<strong>Description:</strong>{{ certificate_analysis.description }}<br />
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
@@ -790,14 +787,14 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in android_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
</td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -915,7 +912,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for item in manifest %}
|
||||
{% for item in manifest_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{item|key:"title" | safe}}
|
||||
@@ -971,7 +968,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in findings.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -992,7 +989,7 @@
|
||||
<td><strong>{{ details|key:"owasp" }}</strong></td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -1028,7 +1025,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in certz %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item|key:"finding" }}
|
||||
@@ -1136,7 +1133,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end apkid analysis ================================== -->
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<a id="virus_total" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
@@ -1148,11 +1145,11 @@
|
||||
<strong><i class="fas fa-spider"></i> VIRUSTOTAL SCAN</strong>
|
||||
</p>
|
||||
<div class="table-responsive">
|
||||
{% if VT_RESULT.items|length < 9 %} {% comment %} Basic check to determine if the response is a msg or a result {% endcomment %}
|
||||
<p align="left"> <strong>{{ VT_RESULT.verbose_msg }}</strong></p>
|
||||
{% if virus_total.items|length < 9 %} {% comment %} Basic check to determine if the response is a msg or a result {% endcomment %}
|
||||
<p align="left"> <strong>{{ virus_total.verbose_msg }}</strong></p>
|
||||
{% else %}
|
||||
<p align="left"> <strong> {{ VT_RESULT.positives }} / {{ VT_RESULT.total }} AVs found this file Malicious! </strong> <a href="{{ VT_RESULT.permalink }}" target="_blank" rel="noopener"><i class="fas fa-th-list"></i> Full Report</a></p>
|
||||
{% if VT_RESULT.positives > 0 %}
|
||||
<p align="left"> <strong> {{ virus_total.positives }} / {{ virus_total.total }} AVs found this file Malicious! </strong> <a href="{{ virus_total.permalink }}" target="_blank" rel="noopener"><i class="fas fa-th-list"></i> Full Report</a></p>
|
||||
{% if virus_total.positives > 0 %}
|
||||
<table id="table_vt" class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1161,7 +1158,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for av_name,av_result in VT_RESULT.scans.items %}
|
||||
{% for av_name,av_result in virus_total.scans.items %}
|
||||
{% if av_result.detected == True %}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -1263,7 +1260,7 @@
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{zipped}}">{{urldict|key:"path"}}</a>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{app_type}}">{{urldict|key:"path"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -1290,7 +1287,7 @@
|
||||
<strong><i class="fas fa-database"></i> FIREBASE DATABASE</strong>
|
||||
</p>
|
||||
<div class="table-responsive">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<table id="table_firebase" class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -1300,7 +1297,7 @@
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -1354,7 +1351,7 @@
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
<a href="../ViewSource/?file={{email_dict|key:"path"}}&md5={{ md5}}&type={{zipped}}">{{email_dict|key:"path"}}</a>
|
||||
<a href="../ViewSource/?file={{email_dict|key:"path"}}&md5={{ md5}}&type={{app_type}}">{{email_dict|key:"path"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
<div class="col-6">
|
||||
<p><strong><i class="fas fa-box-open"></i> FILE INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">File Name</span>
|
||||
{{ name }}<br/>
|
||||
{{ file_name }}<br/>
|
||||
<span class="badge bg-primary">Size</span>
|
||||
{{ size }}<br/>
|
||||
<span class="badge bg-primary">MD5</span>
|
||||
@@ -280,21 +280,21 @@
|
||||
<div class="col-4">
|
||||
<p><strong><i class="fas fa-info"></i> APP INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">App Name</span>
|
||||
{{ real_name }}<br/>
|
||||
{{ app_name }}<br/>
|
||||
<span class="badge bg-primary">Package Name</span>
|
||||
{{ packagename }}<br/>
|
||||
{{ package_name }}<br/>
|
||||
<span class="badge bg-primary">Main Activity</span>
|
||||
{{ mainactivity }}<br/>
|
||||
{{ main_activity }}<br/>
|
||||
<span class="badge bg-primary">Target SDK</span>
|
||||
{{ targetsdk }}
|
||||
{{ target_sdk }}
|
||||
<span class="badge bg-primary">Min SDK</span>
|
||||
{{ minsdk }}
|
||||
{{ min_sdk }}
|
||||
<span class="badge bg-primary">Max SDK</span>
|
||||
{{ maxsdk }}<br/>
|
||||
{{ max_sdk }}<br/>
|
||||
<span class="badge bg-primary">Android Version Name</span>
|
||||
{{ androvername }}
|
||||
{{ version_name }}
|
||||
<span class="badge bg-primary">Android Version Code</span>
|
||||
{{ androver }}
|
||||
{{ version_code }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- Play Store -->
|
||||
{% if not play_details.error %}
|
||||
{% if not playstore_details.error %}
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@@ -310,34 +310,34 @@
|
||||
<strong><i class="fab fa-google-play"></i> PLAYSTORE INFORMATION</strong>
|
||||
</p>
|
||||
<span class="badge bg-info">Title</span>
|
||||
{{ play_details.title }} <br/>
|
||||
{{ playstore_details.title }} <br/>
|
||||
<span class="badge bg-info">Score</span>
|
||||
{{ play_details.score}}
|
||||
{{ playstore_details.score}}
|
||||
<span class="badge bg-info">Installs</span>
|
||||
{{ play_details.installs }}
|
||||
{{ playstore_details.installs }}
|
||||
<span class="badge bg-info">Price</span>
|
||||
{{ play_details.price }}
|
||||
{{ playstore_details.price }}
|
||||
<span class="badge bg-info">Android Version Support</span>
|
||||
{{ play_details.androidVersionText }}
|
||||
{{ playstore_details.androidVersionText }}
|
||||
<span class="badge bg-info">Category</span>
|
||||
{{ play_details.genre }}
|
||||
{{ playstore_details.genre }}
|
||||
<span class="badge bg-info">Play Store URL</span>
|
||||
<a target="_blank" href="{{ play_details.url }}"> {{ packagename }} </a>
|
||||
<a target="_blank" href="{{ playstore_details.url }}"> {{ package_name }} </a>
|
||||
<br/>
|
||||
<span class="badge bg-info">Developer Details</span>
|
||||
{{play_details.developer}},
|
||||
{{play_details.developerId}},
|
||||
{{play_details.developerAddress}},
|
||||
{{play_details.developerWebsite}},
|
||||
{{play_details.developerEmail}},
|
||||
{{playstore_details.developer}},
|
||||
{{playstore_details.developerId}},
|
||||
{{playstore_details.developerAddress}},
|
||||
{{playstore_details.developerWebsite}},
|
||||
{{playstore_details.developerEmail}},
|
||||
<br/>
|
||||
<span class="badge bg-info">Release Date</span>
|
||||
{{ play_details.released }}
|
||||
{{ playstore_details.released }}
|
||||
<span class="badge bg-info">Privacy Policy</span>
|
||||
<a target="_blank" href="{{ play_details.privacyPolicy }}">Privacy link</a>
|
||||
<a target="_blank" href="{{ playstore_details.privacyPolicy }}">Privacy link</a>
|
||||
<br/>
|
||||
<span class="badge bg-info">Description</span>
|
||||
<pre id="pre-wrap">{{ play_details.description }}</pre>
|
||||
<pre id="pre-wrap">{{ playstore_details.description }}</pre>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
</div>
|
||||
@@ -361,7 +361,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-info">
|
||||
<div class="inner">
|
||||
<h3>{{ act_count }}</h3>
|
||||
<h3>{{ activities | length }}</h3>
|
||||
|
||||
<p>ACTIVITIES</p>
|
||||
</div>
|
||||
@@ -376,7 +376,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-success">
|
||||
<div class="inner">
|
||||
<h3>{{ serv_count }}</h3>
|
||||
<h3>{{ services | length }}</h3>
|
||||
|
||||
<p>SERVICES</p>
|
||||
</div>
|
||||
@@ -391,7 +391,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-warning">
|
||||
<div class="inner">
|
||||
<h3>{{ bro_count }}</h3>
|
||||
<h3>{{ receivers | length }}</h3>
|
||||
|
||||
<p>RECEIVERS</p>
|
||||
</div>
|
||||
@@ -406,7 +406,7 @@
|
||||
<!-- small box -->
|
||||
<div class="small-box bg-danger">
|
||||
<div class="inner">
|
||||
<h3>{{ prov_count }}</h3>
|
||||
<h3>{{ providers | length }}</h3>
|
||||
|
||||
<p>PROVIDERS</p>
|
||||
</div>
|
||||
@@ -424,7 +424,7 @@
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Activities</span>
|
||||
<span class="info-box-number">
|
||||
{{ e_act }}
|
||||
{{ exported_count.exported_activities }}
|
||||
</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
@@ -438,7 +438,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Services</span>
|
||||
<span class="info-box-number">{{ e_ser }}</span>
|
||||
<span class="info-box-number">{{ exported_count.exported_services }}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -455,7 +455,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Receivers</span>
|
||||
<span class="info-box-number">{{e_bro}}</span>
|
||||
<span class="info-box-number">{{ exported_count.exported_receivers}}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -468,7 +468,7 @@
|
||||
|
||||
<div class="info-box-content">
|
||||
<span class="info-box-text">Exported <br/>Providers</span>
|
||||
<span class="info-box-number">{{e_cnt}}</span>
|
||||
<span class="info-box-number">{{ exported_count.exported_providers }}</span>
|
||||
</div>
|
||||
<!-- /.info-box-content -->
|
||||
</div>
|
||||
@@ -496,8 +496,8 @@
|
||||
<strong><i class="fas fa-cog"></i> SCAN OPTIONS</strong>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="../StaticAnalyzer/?checksum={{ md5 }}&name={{ name }}&type=zip&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a>
|
||||
<a target="_blank" href="{{mani}}" role="button" class="btn btn-primary"><i class="fa fa-eye"></i> View AndroidManifest.xml</a>
|
||||
<a href="../StaticAnalyzer/?checksum={{ md5 }}&name={{ file_name }}&type=zip&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a>
|
||||
<a target="_blank" href="../ManifestView/?md5={{ md5 }}&type={{ app_type }}&bin=0" role="button" class="btn btn-primary"><i class="fa fa-eye"></i> View AndroidManifest.xml</a>
|
||||
</p>
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
@@ -578,14 +578,14 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in android_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
</td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -703,7 +703,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for item in manifest %}
|
||||
{% for item in manifest_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{item|key:"title" | safe}}
|
||||
@@ -759,7 +759,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in findings.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -780,7 +780,7 @@
|
||||
<td><b>{{ details|key:"owasp" }}</b></td>
|
||||
<td>
|
||||
{% for path in details|key:"path" %}
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{zipped}}"> {{ path }}</a>
|
||||
<a href="../ViewSource/?file={{ path }}&md5={{ md5 }}&type={{app_type}}"> {{ path }}</a>
|
||||
<br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
@@ -816,10 +816,10 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in certz %}
|
||||
{% for item in file_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item|key:"finding" }}
|
||||
{{ item|key:"findings" }}
|
||||
</td>
|
||||
<td>
|
||||
{% for cert_f in item|key:"files" %}
|
||||
@@ -915,7 +915,7 @@
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{zipped}}">{{urldict|key:"path"}}</a>
|
||||
<a href="../ViewSource/?file={{urldict|key:"path"}}&md5={{ md5}}&type={{app_type}}">{{urldict|key:"path"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -942,7 +942,7 @@
|
||||
<strong><i class="fas fa-database"></i> FIREBASE DATABASE</strong>
|
||||
</p>
|
||||
<div class="table-responsive">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<table id="table_firebase" class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -952,7 +952,7 @@
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -1006,7 +1006,7 @@
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
<a href="../ViewSource/?file={{email_dict|key:"path"}}&md5={{ md5}}&type={{zipped}}">{{email_dict|key:"path"}}</a>
|
||||
<a href="../ViewSource/?file={{email_dict|key:"path"}}&md5={{ md5}}&type={{app_type}}">{{email_dict|key:"path"}}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -58,6 +58,14 @@
|
||||
Scan Options
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#url_schemes" class="nav-link">
|
||||
<i class="nav-icon fas fa-hashtag"></i>
|
||||
<p>
|
||||
URL Schemes
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#permissions" class="nav-link">
|
||||
@@ -67,7 +75,16 @@
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<li class="nav-item has-treeview">
|
||||
<a href="#" class="nav-link">
|
||||
<i class="nav-icon fas fa-shield-alt"></i>
|
||||
<p>
|
||||
Security Analysis
|
||||
<i class="fas fa-angle-left right"></i>
|
||||
</p>
|
||||
</a>
|
||||
<ul class="nav nav-treeview">
|
||||
<li class="nav-item">
|
||||
<a href="#transport_security" class="nav-link">
|
||||
<i class="nav-icon fas fa-lock"></i>
|
||||
<p>
|
||||
@@ -90,8 +107,10 @@
|
||||
File Analysis
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<li class="nav-item">
|
||||
<a href="#virus_total" class="nav-link">
|
||||
<i class="nav-icon fas fa-spider"></i>
|
||||
@@ -170,11 +189,11 @@
|
||||
<br/>
|
||||
<span class="badge bg-info">Average CVSS</span> <strong>{{ average_cvss }} </strong><br/>
|
||||
<span class="badge bg-{% if security_score < 50 %}danger{% elif security_score == 100 %}success{% else %}warning{% endif %}">Security Score</span> <strong>{{ security_score }}/100 </strong><br/>
|
||||
{% if VT_RESULT %}
|
||||
{% if VT_RESULT.positives > 0 %}
|
||||
<span class="badge bg-danger">VirusTotal Detection</span> <strong>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</strong><br/>
|
||||
{% if virus_total %}
|
||||
{% if virus_total.positives > 0 %}
|
||||
<span class="badge bg-danger">VirusTotal Detection</span> <strong>{{ virus_total.positives }}/{{ virus_total.total }}</strong><br/>
|
||||
{% else %}
|
||||
<span class="badge bg-success">VirusTotal Detection</span> <strong>{{ VT_RESULT.positives }}/{{ VT_RESULT.total }}</strong><br/>
|
||||
<span class="badge bg-success">VirusTotal Detection</span> <strong>{{ virus_total.positives }}/{{ virus_total.total }}</strong><br/>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -194,21 +213,25 @@
|
||||
<div class="col-3">
|
||||
<p><strong><i class="fas fa-info"></i> APP INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">App Name</span>
|
||||
{{ bin_name }}<br/>
|
||||
{{ app_name }}<br/>
|
||||
<span class="badge bg-primary">App Type</span>
|
||||
{{ bin_type }}<br/>
|
||||
{{ app_type }}<br/>
|
||||
<span class="badge bg-primary">Identifier</span>
|
||||
{{ id }}<br/>
|
||||
{{ bundle_id }}<br/>
|
||||
<span class="badge bg-primary">SDK Name</span>
|
||||
{{ sdk }}<br/>
|
||||
{{ sdk_name }}<br/>
|
||||
<span class="badge bg-primary">Version</span>
|
||||
{{ bundle_version }}
|
||||
{{ app_version }}
|
||||
<span class="badge bg-primary">Build</span>
|
||||
{{ build }}
|
||||
<span class="badge bg-primary">Platform Version</span>
|
||||
{{ pltfm }}
|
||||
{{ platform }}
|
||||
<span class="badge bg-primary">Min OS Version</span>
|
||||
{{ min }}
|
||||
{{ min_os_version }} <br/>
|
||||
<span class="badge bg-primary">Supported Platforms</span>
|
||||
{% for pl in bundle_supported_platforms %}
|
||||
{{pl}},
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<p><strong><i class="fas fa-ad"></i> BINARY INFORMATION </strong></p>
|
||||
@@ -305,6 +328,61 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end scan options================================== -->
|
||||
<a id="url_schemes" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong><i class="fas fa-hashtag"></i> CUSTOM URL SCHEMES</strong>
|
||||
<p>
|
||||
{% if bundle_url_types|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL NAME</th>
|
||||
<th>SCHEMES</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for scheme in bundle_url_types %}
|
||||
<tr>
|
||||
<td>
|
||||
{{scheme | key:"CFBundleURLName" }}
|
||||
{% if scheme|key:"CFBundleTypeRole" %}
|
||||
<br>
|
||||
{{scheme | key:"CFBundleTypeRole" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for ul in scheme.CFBundleURLSchemes %}
|
||||
{{ul}} <br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No URL Schemes found.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
</div>
|
||||
<!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end url schemes ================================== -->
|
||||
|
||||
<a id="permissions" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
@@ -328,7 +406,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{%for perm in permissions%}
|
||||
{% for perm in permissions %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ perm.name }}
|
||||
@@ -346,7 +424,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No permissions required.
|
||||
No Permissions required.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -378,23 +456,23 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if insecure_connections|length > 0 %}
|
||||
{%for con in insecure_connections%}
|
||||
{% if ats_analysis|length > 0 %}
|
||||
{% for findings in ats_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
Exception in NSAppTransportSecurity found.
|
||||
{{findings.issue}}
|
||||
<td>
|
||||
<span class="badge bg-danger">insecure</span>
|
||||
<span class="badge bg-danger"> {{findings.status}}</span>
|
||||
</td>
|
||||
<td>
|
||||
App Transport Security (ATS) is disabled on the domain <strong>{{ con }}</strong>. Disabling ATS can allow insecure communication with particular servers or allow insecure loads for web views or for media, while maintaining ATS protections elsewhere in your app.
|
||||
{{findings.description}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
None
|
||||
No ATS exceptions found.
|
||||
<td>
|
||||
<span class="badge bg-success">secure</span>
|
||||
</td>
|
||||
@@ -440,7 +518,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for bin in bin_anal %}
|
||||
{% for bin in binary_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ bin.issue }}
|
||||
@@ -460,7 +538,7 @@
|
||||
<td><strong>{{bin.cwe}}</strong></td>
|
||||
<td><strong>{{bin.owasp}}</strong></td>
|
||||
<td>
|
||||
{{ bin.description | safe}}
|
||||
{{ bin.description}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -524,7 +602,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end file analysis ================================== -->
|
||||
{% if VT_RESULT %}
|
||||
{% if virus_total %}
|
||||
<a id="virus_total" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
@@ -536,11 +614,11 @@
|
||||
<strong><i class="fas fa-spider"></i> VIRUSTOTAL SCAN</strong>
|
||||
</p>
|
||||
<div class="table-responsive">
|
||||
{% if VT_RESULT.items|length < 9 %} {% comment %} Basic check to determine if the response is a msg or a result {% endcomment %}
|
||||
<p align="left"> <strong>{{ VT_RESULT.verbose_msg }}</strong></p>
|
||||
{% if virus_total.items|length < 9 %} {% comment %} Basic check to determine if the response is a msg or a result {% endcomment %}
|
||||
<p align="left"> <strong>{{ virus_total.verbose_msg }}</strong></p>
|
||||
{% else %}
|
||||
<p align="left"> <strong> {{ VT_RESULT.positives }} / {{ VT_RESULT.total }} AVs found this file Malicious! </strong> <a href="{{ VT_RESULT.permalink }}" target="_blank" rel="noopener"><i class="fas fa-th-list"></i> Full Report</a></p>
|
||||
{% if VT_RESULT.positives > 0 %}
|
||||
<p align="left"> <strong> {{ virus_total.positives }} / {{ virus_total.total }} AVs found this file Malicious! </strong> <a href="{{ virus_total.permalink }}" target="_blank" rel="noopener"><i class="fas fa-th-list"></i> Full Report</a></p>
|
||||
{% if virus_total.positives > 0 %}
|
||||
<table id="table_vt" class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -549,7 +627,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for av_name,av_result in VT_RESULT.scans.items %}
|
||||
{% for av_name,av_result in virus_total.scans.items %}
|
||||
{% if av_result.detected == True %}
|
||||
<tr>
|
||||
<td>
|
||||
@@ -587,7 +665,7 @@
|
||||
</p>
|
||||
<div class="list-group">
|
||||
<p>
|
||||
{% for lib in libs %}
|
||||
{% for lib in libraries %}
|
||||
{{ lib }}
|
||||
<br/>
|
||||
{% endfor %}
|
||||
@@ -642,7 +720,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre><code>
|
||||
{{ plist }}
|
||||
{{ info_plist }}
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
@@ -663,7 +741,7 @@
|
||||
<div class="modal-body">
|
||||
<pre><code>
|
||||
{% for string in strings %}
|
||||
{{string | safe}}
|
||||
{{string}}
|
||||
{% endfor %}
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
@@ -58,6 +58,14 @@
|
||||
Scan Options
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#url_schemes" class="nav-link">
|
||||
<i class="nav-icon fas fa-hashtag"></i>
|
||||
<p>
|
||||
URL Schemes
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a href="#permissions" class="nav-link">
|
||||
@@ -232,19 +240,23 @@
|
||||
<div class="col-5">
|
||||
<p><strong><i class="fas fa-info"></i> APP INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">App Name</span>
|
||||
{{ bin_name }}<br/>
|
||||
{{ app_name }}<br/>
|
||||
<span class="badge bg-primary">Identifier</span>
|
||||
{{ id }}<br/>
|
||||
{{ bundle_id }}<br/>
|
||||
<span class="badge bg-primary">SDK Name</span>
|
||||
{{ sdk }}<br/>
|
||||
{{ sdk_name }}<br/>
|
||||
<span class="badge bg-primary">Version</span>
|
||||
{{ bundle_version }}
|
||||
{{ app_version }}
|
||||
<span class="badge bg-primary">Build</span>
|
||||
{{ build }}
|
||||
<span class="badge bg-primary">Platform Version</span>
|
||||
{{ pltfm }}
|
||||
{{ platform }}
|
||||
<span class="badge bg-primary">Min OS Version</span>
|
||||
{{ min }}
|
||||
{{ min_os_version }} <br/>
|
||||
<span class="badge bg-primary">Supported Platforms</span>
|
||||
{% for pl in bundle_supported_platforms %}
|
||||
{{pl}},
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -328,6 +340,60 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end scan options================================== -->
|
||||
<a id="url_schemes" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong><i class="fas fa-hashtag"></i> CUSTOM URL SCHEMES</strong>
|
||||
<p>
|
||||
{% if bundle_url_types|length > 0 %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover table-striped">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>URL NAME</th>
|
||||
<th>SCHEMES</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for scheme in bundle_url_types %}
|
||||
<tr>
|
||||
<td>
|
||||
{{scheme | key:"CFBundleURLName" }}
|
||||
{% if scheme|key:"CFBundleTypeRole" %}
|
||||
<br>
|
||||
{{scheme | key:"CFBundleTypeRole" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for ul in scheme.CFBundleURLSchemes %}
|
||||
{{ul}} <br/>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No URL Schemes found.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div><!-- /.card -->
|
||||
</div>
|
||||
<!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end url schemes ================================== -->
|
||||
<a id="permissions" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
@@ -351,7 +417,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{%for perm in permissions%}
|
||||
{% for perm in permissions %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ perm.name }}
|
||||
@@ -369,7 +435,7 @@
|
||||
</div>
|
||||
{% else %}
|
||||
<p>
|
||||
No permissions required.
|
||||
No Permissions required.
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -400,7 +466,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for desc, details in api.items %}
|
||||
{% for desc, details in ios_api.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ desc }}
|
||||
@@ -425,7 +491,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- ===========================end ios api analysis ================================== -->
|
||||
<a id="transport_security" class="anchor"></a>
|
||||
<a id="transport_security" class="anchor"></a>
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
@@ -446,23 +512,23 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if insecure_connections|length > 0 %}
|
||||
{% for con in insecure_connections %}
|
||||
{% if ats_analysis|length > 0 %}
|
||||
{% for findings in ats_analysis %}
|
||||
<tr>
|
||||
<td>
|
||||
Exception in NSAppTransportSecurity found.
|
||||
{{findings.issue}}
|
||||
<td>
|
||||
<span class="badge bg-danger">insecure</span>
|
||||
<span class="badge bg-danger"> {{findings.status}}</span>
|
||||
</td>
|
||||
<td>
|
||||
App Transport Security (ATS) is disabled on the domain <strong>{{ con }}</strong>. Disabling ATS can allow insecure communication with particular servers or allow insecure loads for web views or for media, while maintaining ATS protections elsewhere in your app.
|
||||
{{findings.description}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<tr>
|
||||
<td>
|
||||
None
|
||||
No ATS exceptions found.
|
||||
<td>
|
||||
<span class="badge bg-success">secure</span>
|
||||
</td>
|
||||
@@ -508,7 +574,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for issue, details in insecure.items %}
|
||||
{% for issue, details in code_analysis.items %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ issue }}
|
||||
@@ -697,7 +763,7 @@
|
||||
<strong><i class="fas fa-database"></i> FIREBASE DATABASE</strong>
|
||||
</p>
|
||||
<div class="table-responsive">
|
||||
{% if firebase %}
|
||||
{% if firebase_urls %}
|
||||
<table id="table_firebase" class="table table-bordered table-hover table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -707,7 +773,7 @@
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for item in firebase %}
|
||||
{% for item in firebase_urls %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ item.url }}
|
||||
@@ -818,7 +884,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<pre><code>
|
||||
{{ plist }}
|
||||
{{ info_plist }}
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -120,18 +120,18 @@
|
||||
<div class="col-2">
|
||||
<p><strong><i class="fas fa-info"></i> APP INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">App Name</span>
|
||||
{{ bin_name }} <br/>
|
||||
{{ app_name }} <br/>
|
||||
<span class="badge bg-primary">Publisher</span>
|
||||
{{ pub_name }} <br/>
|
||||
{{ publisher_name }} <br/>
|
||||
<span class="badge bg-primary">Version</span>
|
||||
{{ app_version }} <br/>
|
||||
<span class="badge bg-primary">Arch</span>
|
||||
{{ arch }}
|
||||
{{ architecture }}
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<p><strong><i class="fas fa-box-open"></i> FILE INFORMATION </strong></p>
|
||||
<span class="badge bg-primary">Name</span>
|
||||
{{ name }} <br/>
|
||||
<span class="badge bg-primary">File Name</span>
|
||||
{{ file_name }} <br/>
|
||||
<span class="badge bg-primary">Size</span>
|
||||
{{ size }} <br/>
|
||||
<span class="badge bg-primary">MD5</span>
|
||||
@@ -139,7 +139,7 @@
|
||||
<span class="badge bg-primary">SHA1</span>
|
||||
{{ sha1 }} <br/>
|
||||
<span class="badge bg-primary">SHA256</span>
|
||||
{{ sha256 }}
|
||||
{{ sha256 }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
@@ -188,7 +188,7 @@
|
||||
<strong><i class="fas fa-cog"></i> SCAN OPTIONS</strong>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="../StaticAnalyzer_Windows/?checksum={{ md5 }}&name={{ name }}&type=appx&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a>
|
||||
<a href="../StaticAnalyzer_Windows/?checksum={{ md5 }}&name={{ file_name }}&type=appx&rescan=1" class="btn btn-info" role="button"><i class="fa fa-sync"></i> Rescan</a>
|
||||
<a href="#" data-target="#mstrings" role="button" class="btn btn-primary" data-toggle="modal"><i class="fa fa-list"></i> View Strings</a>
|
||||
</p>
|
||||
</div>
|
||||
@@ -220,7 +220,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for result in bin_an_results %}
|
||||
{% for result in binary_analysis %}
|
||||
<tr>
|
||||
<td>{{ result.rule_id }}</td>
|
||||
<td>
|
||||
@@ -240,7 +240,7 @@
|
||||
<td>{{ result.info }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% for warn in bin_an_warnings %}
|
||||
{% for warn in binary_warnings %}
|
||||
<tr>
|
||||
<td>{{ warn.rule_id }}</td>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user