Skip to content

Commit

Permalink
[HOTFIX] AppSec PNW 2024, Deeplink Trigger Support for Android Dynami…
Browse files Browse the repository at this point in the history
…c Analyzer (#2402)

* iOS  Dynamic Analyzer String Compare Frida script improvement
* Android Dynamic Analyzer Deeplink UI trigger support 
* Android & iOS Dynamic Analyzer UI Improvements
* Android & iOS Dynamic Analyzer Bug fixes
  • Loading branch information
ajinabraham authored Jul 26, 2024
1 parent 39ba3e6 commit a9de033
Show file tree
Hide file tree
Showing 13 changed files with 319 additions and 199 deletions.
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

0 comments on commit a9de033

Please sign in to comment.