Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOTFIX] AppSec PNW 2024, Deeplink Trigger Support for Android Dynamic Analyzer #2402

Merged
merged 8 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ function captureStringCompare() {
send('Capturing string comparisons')
Interceptor.attach(ObjC.classes.__NSCFString['- isEqualToString:'].implementation, {
onEnter: function (args) {
var src = new ObjC.Object(ptr(args[0])).toString()
var str = new ObjC.Object(ptr(args[2])).toString()
send('[AUXILIARY] [__NSCFString isEqualToString:] -> '+ str);
send('[AUXILIARY] [__NSCFString isEqualToString:] -> \nstring 1: '+ src + '\nstring 2: '+ str);
}
});
}

function captureStringCompare2(){
Interceptor.attach(ObjC.classes.NSTaggedPointerString['- isEqualToString:'].implementation, {
onEnter: function (args) {
var src = new ObjC.Object(ptr(args[0])).toString()
var str = new ObjC.Object(ptr(args[2])).toString()
send('[AUXILIARY] NSTaggedPointerString[- isEqualToString:] -> '+ str);
send('[AUXILIARY] NSTaggedPointerString[- isEqualToString:] -> \nstring 1: '+ src + '\nstring 2: '+ str);
}
});
}
Expand Down
6 changes: 5 additions & 1 deletion mobsf/DynamicAnalyzer/views/android/dynamic_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
get_proxy_ip,
is_md5,
print_n_send_error_response,
python_dict,
python_list,
strict_package_check,
)
Expand Down Expand Up @@ -155,9 +156,11 @@ def dynamic_analyzer(request, checksum, api=False):
static_android_db.EXPORTED_ACTIVITIES)
activities = python_list(
static_android_db.ACTIVITIES)
deeplinks = python_dict(
static_android_db.BROWSABLE_ACTIVITIES)
except ObjectDoesNotExist:
logger.warning(
'Failed to get Activities. '
'Failed to get Activities/Deeplinks. '
'Static Analysis not completed for the app.')
env = Environment(identifier)
if not env.connect_n_mount():
Expand Down Expand Up @@ -218,6 +221,7 @@ def dynamic_analyzer(request, checksum, api=False):
'version': settings.MOBSF_VER,
'activities': activities,
'exported_activities': exported_activities,
'deeplinks': deeplinks,
'title': 'Dynamic Analyzer'}
template = 'dynamic_analysis/android/dynamic_analyzer.html'
if api:
Expand Down
4 changes: 2 additions & 2 deletions mobsf/DynamicAnalyzer/views/android/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def get_environment(self):
return 'emulator'
elif (b'genymotion' in out.lower()
or any(char.isdigit() for char in ver)):
logger.info('Found Genymotion x86 Android VM')
logger.info('Found Genymotion Android VM')
return 'genymotion'
elif b'corellium' in out:
logger.info('Found Corellium ARM Android VM')
Expand Down Expand Up @@ -652,7 +652,7 @@ def frida_setup(self):
elif arch == 'x86_64':
frida_arch = 'x86_64'
else:
logger.error('Make sure a Genymotion Android x86 VM'
logger.error('Make sure a Genymotion Android VM'
' or Android Studio Emulator'
' instance is running')
return
Expand Down
2 changes: 2 additions & 0 deletions mobsf/DynamicAnalyzer/views/android/frida_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ def api_handler(self, api):
loaded_class_methods = []
implementations = []
try:
if not self.extras:
return
raction = self.extras.get('rclass_action')
rclass = self.extras.get('rclass_name')
rclass_pattern = self.extras.get('rclass_pattern')
Expand Down
28 changes: 27 additions & 1 deletion mobsf/DynamicAnalyzer/views/android/tests_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
stop_httptools,
)
from mobsf.MobSF.utils import (
cmd_injection_check,
is_md5,
python_list,
)
Expand All @@ -50,7 +51,7 @@
@permission_required(Permissions.SCAN)
@require_http_methods(['POST'])
def start_activity(request, api=False):
"""Lunch a specific activity."""
"""Launch a specific activity."""
try:
env = Environment()
activity = request.POST['activity']
Expand All @@ -77,6 +78,31 @@ def start_activity(request, api=False):
data = {'status': 'failed', 'message': str(exp)}
return send_response(data, api)

# AJAX


@login_required
@permission_required(Permissions.SCAN)
@require_http_methods(['POST'])
def start_deeplink(request, api=False):
"""Launch a specific deeplink."""
try:
env = Environment()
url = request.POST['url']
md5_hash = request.POST['hash']

valid_md5 = is_md5(md5_hash)
if cmd_injection_check(url) or not valid_md5:
return invalid_params(api)
env.adb_command(
['am', 'start', '-a',
'android.intent.action.VIEW',
'-d', url], True)
data = {'status': 'ok'}
except Exception as exp:
logger.exception('Start Activity')
data = {'status': 'failed', 'message': str(exp)}
return send_response(data, api)

# AJAX

Expand Down
2 changes: 2 additions & 0 deletions mobsf/DynamicAnalyzer/views/ios/frida_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def api_handler(self, api):
self.container_file.write_text(self.app_container)
except frida.InvalidOperationError:
pass
if not self.extras:
return
raction = self.extras.get('rclass_action')
rclass = self.extras.get('rclass_name')
rclass_pattern = self.extras.get('rclass_pattern')
Expand Down
2 changes: 1 addition & 1 deletion mobsf/MobSF/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

logger = logging.getLogger(__name__)

VERSION = '4.0.3'
VERSION = '4.0.4'
BANNER = """
__ __ _ ____ _____ _ _ ___
| \/ | ___ | |__/ ___|| ___|_ _| || | / _ \
Expand Down
3 changes: 3 additions & 0 deletions mobsf/MobSF/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@
re_path(r'^start_activity/$',
tests_common.start_activity,
name='start_activity'),
re_path(r'^start_deeplink/$',
tests_common.start_deeplink,
name='start_deeplink'),
re_path(r'^download_data/$', tests_common.download_data),
re_path(r'^collect_logs/$', tests_common.collect_logs),
re_path(r'^tls_tests/$', tests_common.tls_tests),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,13 @@ <h3 class="card-title">Android Runtime not found!</h3>
<div class="col-md-9">
<h4>MobSF Dynamic Analyzer Supports</h4>
<h5>
<strong>• Genymotion Android VM</strong> version 4.1 - 11.0 (x86, upto API 30)<br/>
<strong>• Genymotion Android VM</strong> version 4.1 - 11.0 (arm64, x86, upto API 30)<br/>
<strong>• Android Emulator AVD</strong> (non production) version 5.0 - 9.0 (arm, arm64, x86, and x86_64 upto API 28)<br/>
<strong>• Corellium Android VM</strong> (userdebug builds) version 7.1.2 - 11.0 (arm64 upto API 30)
</h5>
<p>
{% if android_version %}
Recommended Android version is <strong>9.0</strong><br/>
Android version >= <strong>9.0</strong> recommended<br/>
Detected Android Version: <strong>{{android_version}}</strong>, SDK: <strong>{{ android_sdk }}</strong> <br/>
{% if android_sdk|floatformat > android_supported|floatformat %}
<script src="{% static "adminlte/plugins/sweetalert2/sweetalert2.min.js" %}"></script>
Expand Down
Loading
Loading