Skip to content

Commit

Permalink
file analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
ajinabraham committed Nov 24, 2023
1 parent f8f8bf9 commit f245882
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 27 deletions.
40 changes: 27 additions & 13 deletions mobsf/DynamicAnalyzer/views/android/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,19 @@ def safe_paths(tar_meta):
yield fh


def get_app_files(apk_dir, package):
"""Get files from device."""
logger.info('Getting app files')
all_files = {'xml': [], 'sqlite': [], 'others': []}
def untar_files(tar_loc, untar_dir):
"""Untar files."""
logger.info('Extracting Tar files')
# Extract Device Data
tar_loc = os.path.join(apk_dir, package + '.tar')
untar_dir = os.path.join(apk_dir, 'DYNAMIC_DeviceData/')
if not is_file_exists(tar_loc):
return all_files
if os.path.exists(untar_dir):
if not tar_loc.exists():

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
return False
if untar_dir.exists():

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
# fix for permission errors
shutil.rmtree(untar_dir)

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
else:
os.makedirs(untar_dir)

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
This path depends on a
user-provided value
.
try:
with tarfile.open(tar_loc, errorlevel=1) as tar:
with tarfile.open(tar_loc.as_posix(), errorlevel=1) as tar:

def is_within_directory(directory, target):
abs_directory = os.path.abspath(directory)
Expand All @@ -216,14 +215,26 @@ def safe_extract(tar, path='.',
pass
except Exception:
logger.exception('Tar extraction failed')
return True


def get_app_files(apk_dir, package):
"""Get files from device."""
logger.info('Getting app files')
all_files = {'xml': [], 'sqlite': [], 'others': [], 'plist': []}
app_dir = Path(apk_dir)
tar_loc = app_dir / f'{package}.tar'
untar_dir = app_dir / 'DYNAMIC_DeviceData'
success = untar_files(tar_loc, untar_dir)
if not success:
return all_files
# Do Static Analysis on Data from Device
try:
if not os.path.exists(untar_dir):
os.makedirs(untar_dir)
untar_dir = untar_dir.as_posix()
for dir_name, _, files in os.walk(untar_dir):
for jfile in files:
file_path = os.path.join(untar_dir, dir_name, jfile)
fileparam = file_path.replace(untar_dir, '')
fileparam = file_path.replace(f'{untar_dir}/', '')
if is_pipe_or_link(file_path):
continue
if jfile == 'lib':
Expand All @@ -232,6 +243,9 @@ def safe_extract(tar, path='.',
if jfile.endswith('.xml'):
all_files['xml'].append(
{'type': 'xml', 'file': fileparam})
elif jfile.endswith('.plist'):
all_files['plist'].append(
{'type': 'plist', 'file': fileparam})
else:
with open(file_path, # lgtm [py/path-injection]
'r',
Expand Down
18 changes: 12 additions & 6 deletions mobsf/DynamicAnalyzer/views/android/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ntpath
import os
import io
from pathlib import Path

from django.conf import settings
from django.shortcuts import render
Expand Down Expand Up @@ -36,6 +37,10 @@
read_sqlite,
)

from biplist import (
writePlistToString,
)


logger = logging.getLogger(__name__)
register.filter('key', key)
Expand Down Expand Up @@ -130,11 +135,10 @@ def view_file(request, api=False):
return print_n_send_error_response(request,
'Invalid Parameters',
api)
src = os.path.join(
settings.UPLD_DIR,
md5_hash,
'DYNAMIC_DeviceData/')
sfile = os.path.join(src, fil)
src = Path(settings.UPLD_DIR) / md5_hash / 'DYNAMIC_DeviceData'
sfile = src / fil
src = src.as_posix()
sfile = sfile.as_posix()
if not is_safe_path(src, sfile) or is_path_traversal(fil):
err = 'Path Traversal Attack Detected'
return print_n_send_error_response(request, err, api)
Expand All @@ -143,7 +147,9 @@ def view_file(request, api=False):
mode='r',
encoding='ISO-8859-1') as flip:
dat = flip.read()
if fil.endswith('.xml') and typ == 'xml':
if fil.endswith('.plist') and 'bplist00' in dat:
dat = writePlistToString(dat).decode('utf-8', 'ignore')
if fil.endswith(('.xml', '.plist')) and typ in ['xml', 'plist']:
rtyp = 'xml'
elif typ == 'db':
dat = None
Expand Down
9 changes: 6 additions & 3 deletions mobsf/DynamicAnalyzer/views/ios/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ def run_analysis(app_dir, checksum):
for email in EMAIL_REGEX.findall(data.lower()):
if (email not in emails) and (not email.startswith('//')):
emails.append(email)
analysis_result['appdata'] = get_app_files(
pfiles = get_app_files(
app_dir,
f'{checksum}-app-container')
analysis_result['sqlite'] = pfiles['sqlite']
analysis_result['plist'] = pfiles['plist']
analysis_result['others'] = pfiles['others']
analysis_result['urls'] = urls
analysis_result['domains'] = domains
analysis_result['emails'] = emails
Expand All @@ -86,7 +89,7 @@ def ios_api_analysis(app_dir):
'pasteboard': [],
'textinputs': [],
'datadir': [],
'sqlite': [],
'sql': [],
}
try:
dump_file = app_dir / 'mobsf_dump_file.txt'
Expand Down Expand Up @@ -121,7 +124,7 @@ def ios_api_analysis(app_dir):
elif parsed.get('datadir'):
dump['datadir'] = parsed['datadir']
elif parsed.get('sql'):
dump['sqlite'].append(parsed['sql'])
dump['sql'].append(parsed['sql'])
if len(dump['network']) > 0:
dump['network'] = list(
{v['url']: v for v in dump['network']}.values())
Expand Down
107 changes: 102 additions & 5 deletions mobsf/templates/dynamic_analysis/ios/dynamic_report.html
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,6 @@ <h5 class="card-title"></h5>
</div>
</section>
<!-- ===========================end files ================================== -->
{{ appdata }}

<a id="appdata" class="anchor"></a>
<section class="content">
Expand Down Expand Up @@ -856,7 +855,7 @@ <h5 class="card-title"></h5>
</section>
<!-- ===========================end credentials ================================== -->

<a id="sqlite" class="anchor"></a>
<a id="sql" class="anchor"></a>
<section class="content">
<div class="container-fluid">
<div class="row">
Expand All @@ -867,15 +866,15 @@ <h5 class="card-title"></h5>
<strong><i class="fas fa-user-secret"></i> SQLITE QUERIES</strong>
</p>
<div class="table-responsive">
{% if sqlite %}
<table id="table_sqlite" class="table table-bordered table-hover table-striped">
{% if sql %}
<table id="table_sql" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>QUERIES</th>
</tr>
</thead>
<tbody>
{% for item in sqlite %}
{% for item in sql %}
<tr>
<td>
{{item}}
Expand Down Expand Up @@ -1137,6 +1136,104 @@ <h5 class="card-title"></h5>
</div>
</section>
<!-- ===========================end trackers ================================== -->
<a id="sqlitedb" 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-database"></i> SQLITE DATABASE</strong>
</p>
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>FILES</th>
</tr>
</thead>
<tbody>
{% for file in sqlite %}
<tr><td><a href="{% url 'dynamic_view_file' %}?file={{file|key:"file"}}&amp;hash={{hash}}&amp;type={{file|key:"type"}}">{{file|key:"file"}}</a></td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div><!-- /.card -->
</div>
<!-- end row -->
</div>
</div>
</section>
<!-- ===========================end sqlite ================================== -->
<a id="plistfiles" 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-file-code"></i> PLIST FILES</strong>
</p>
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>FILES</th>
</tr>
</thead>
<tbody>
{% for file in plist %}
<tr><td><a href="{% url 'dynamic_view_file' %}?file={{file|key:"file"}}&amp;hash={{hash}}&amp;type={{file|key:"type"}}">{{file|key:"file"}}</a></td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div><!-- /.card -->
</div>
<!-- end row -->
</div>
</section>
<!-- ===========================end plist files ================================== -->
<a id="other_files" 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-file-contract"></i> OTHER FILES</strong>
</p>
<div class="table-responsive">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>FILES</th>
</tr>
</thead>
<tbody>
{% for file in others %}
<tr><td><a href="{% url 'dynamic_view_file' %}?file={{file|key:"file"}}&amp;hash={{hash}}&amp;type={{file|key:"type"}}">{{file|key:"file"}}</a></td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div><!-- /.card -->
</div>
<!-- end row -->
</div>
</section>
<!-- ===========================end other files ================================== -->


<!-- end of contents -->
</div>

Expand Down

0 comments on commit f245882

Please sign in to comment.