[HOTFIX] Code QA (#2393)

* QA
* Add new android rule setAllow*FromFileURLs
* android root bypass and debugger bypass scripts improvements
* Dockerfile qa
* prevent entrypoint exit if username already exists
This commit is contained in:
Ajin Abraham
2024-06-02 16:37:00 -07:00
committed by GitHub
parent 680ca5d302
commit 39ba3e64be
9 changed files with 150 additions and 68 deletions
+24 -23
View File
@@ -10,7 +10,24 @@ LABEL \
contributor_2="Vincent Nadal <[email protected]>" \
description="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."
ENV DEBIAN_FRONTEND=noninteractive
ENV DEBIAN_FRONTEND=noninteractive \
MOBSF_USER=mobsf \
USER_ID=9901 \
MOBSF_PLATFORM=docker \
MOBSF_ADB_BINARY=/usr/bin/adb \
JDK_FILE=openjdk-20.0.2_linux-x64_bin.tar.gz \
JDK_FILE_ARM=openjdk-20.0.2_linux-aarch64_bin.tar.gz \
WKH_FILE=wkhtmltox_0.12.6.1-2.jammy_amd64.deb \
WKH_FILE_ARM=wkhtmltox_0.12.6.1-2.jammy_arm64.deb \
JAVA_HOME=/jdk-20.0.2 \
PATH=$JAVA_HOME/bin:$PATH \
LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONFAULTHANDLER=1 \
POETRY_VERSION=1.6.1
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run
RUN apt update -y && apt install -y --no-install-recommends \
@@ -37,32 +54,13 @@ RUN apt update -y && apt install -y --no-install-recommends \
locale-gen en_US.UTF-8 && \
apt upgrade -y
ENV MOBSF_USER=mobsf \
MOBSF_PLATFORM=docker \
MOBSF_ADB_BINARY=/usr/bin/adb \
JDK_FILE=openjdk-20.0.2_linux-x64_bin.tar.gz \
JDK_FILE_ARM=openjdk-20.0.2_linux-aarch64_bin.tar.gz \
WKH_FILE=wkhtmltox_0.12.6.1-2.jammy_amd64.deb \
WKH_FILE_ARM=wkhtmltox_0.12.6.1-2.jammy_arm64.deb \
JAVA_HOME=/jdk-20.0.2 \
PATH=$JAVA_HOME/bin:$PATH \
LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
LC_ALL=en_US.UTF-8 \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONFAULTHANDLER=1 \
POETRY_VERSION=1.6.1
# Install wkhtmltopdf & OpenJDK
ARG TARGETPLATFORM
COPY scripts/install_java_wkhtmltopdf.sh .
RUN ./install_java_wkhtmltopdf.sh
RUN groupadd -g 9901 $MOBSF_USER
RUN adduser $MOBSF_USER --shell /bin/false -u 9901 --ingroup $MOBSF_USER --gecos "" --disabled-password
# Install Python dependencies
COPY poetry.lock pyproject.toml ./
RUN python3 -m pip install --upgrade --no-cache-dir pip poetry==${POETRY_VERSION} && \
poetry config virtualenvs.create false && \
@@ -104,8 +102,11 @@ HEALTHCHECK CMD curl --fail http://host.docker.internal:8000/ || exit 1
# Expose MobSF Port and Proxy Port
EXPOSE 8000 8000 1337 1337
RUN chown -R $MOBSF_USER:$MOBSF_USER /home/mobsf
USER mobsf
# Create mobsf user
RUN groupadd --gid $USER_ID $MOBSF_USER && \
useradd $MOBSF_USER --uid $USER_ID --gid $MOBSF_USER --shell /bin/false && \
chown -R $MOBSF_USER:$MOBSF_USER /home/mobsf
USER $MOBSF_USER
# Run MobSF
CMD ["/home/mobsf/Mobile-Security-Framework-MobSF/scripts/entrypoint.sh"]
@@ -196,3 +196,22 @@ Java.perform(function() {
}
} catch(e){}
})
/* React Native JailMonkey Detection Bypass */
Java.perform(function() {
try{
let hook = Java.use("com.gantix.JailMonkey.JailMonkeyModule")['isDevelopmentSettingsMode'];
if (hook) {
hook.overload("com.facebook.react.bridge.Promise").implementation = function(p) {
p.resolve(Java.use("java.lang.Boolean").$new(false));
}
}
let hook2 = Java.use("com.gantix.JailMonkey.JailMonkeyModule")['isDebuggedMode'];
if (hook2) {
hook2.overload("com.facebook.react.bridge.Promise").implementation = function(p) {
p.resolve(Java.use("java.lang.Boolean").$new(false));
}
}
} catch(e){}
});
@@ -163,7 +163,6 @@ Java.performNow(function () {
}
} catch (err) {
send('[RootDetection Bypass] Error ' + className + '.' + classMethod + err);
return
}
try {
@@ -183,7 +182,6 @@ Java.performNow(function () {
}
} catch (err) {
send('[RootDetection Bypass] Error ' + className + '.' + classMethod + err);
return
}
try {
className = 'android.security.keystore.KeyInfo'
@@ -203,7 +201,6 @@ Java.performNow(function () {
}
} catch (err) {
send('[RootDetection Bypass] Error ' + className + '.' + classMethod + err);
return
}
// Native Root Check Bypass
@@ -257,4 +254,53 @@ Java.performNow(function () {
int execvpe(const char *file, char *const argv[], char *const envp[]);
*/
});
});
Java.perform(function() {
// Bypassing Root in React Native JailMonkey
// Source: https://codeshare.frida.re/@RohindhR/react-native-jail-monkey-bypass-all-checks/
try {
let toHook = Java.use('com.gantix.JailMonkey.JailMonkeyModule')['getConstants'];
toHook.implementation = function() {
var hashmap = this.getConstants();
hashmap.put('isJailBroken', Java.use("java.lang.Boolean").$new(false));
hashmap.put('hookDetected', Java.use("java.lang.Boolean").$new(false));
hashmap.put('canMockLocation', Java.use("java.lang.Boolean").$new(false));
hashmap.put('isOnExternalStorage', Java.use("java.lang.Boolean").$new(false));
hashmap.put('AdbEnabled', Java.use("java.lang.Boolean").$new(false));
return hashmap;
}
} catch (err) {}
try{
// Bypassing Rooted Check
let hook = Java.use('com.gantix.JailMonkey.Rooted.RootedCheck')['getResultByDetectionMethod']
hook.implementation = function() {
let map = this.getResultByDetectionMethod();
map.put("jailMonkey", Java.use("java.lang.Boolean").$new(false));
return map;
}
} catch (err) {}
try{
// Bypassing Root detection method's result of RootBeer library
var className = 'com.gantix.JailMonkey.Rooted.RootedCheck$RootBeerResults';
let toHook = Java.use(className)['isJailBroken'];
toHook.implementation = function() {
return false;
};
let toHook2 = Java.use(className)['toNativeMap']
toHook2.implementation = function() {
var map = this.toNativeMap.call(this);
map.put("detectRootManagementApps", Java.use("java.lang.Boolean").$new(false));
map.put("detectPotentiallyDangerousApps", Java.use("java.lang.Boolean").$new(false));
map.put("checkForSuBinary", Java.use("java.lang.Boolean").$new(false));
map.put("checkForDangerousProps", Java.use("java.lang.Boolean").$new(false));
map.put("checkForRWPaths", Java.use("java.lang.Boolean").$new(false));
map.put("detectTestKeys", Java.use("java.lang.Boolean").$new(false));
map.put("checkSuExists", Java.use("java.lang.Boolean").$new(false));
map.put("checkForRootNative", Java.use("java.lang.Boolean").$new(false));
map.put("checkForMagiskBinary", Java.use("java.lang.Boolean").$new(false));
return map;
};
} catch (err) {}
})
+1 -1
View File
@@ -10,7 +10,7 @@ from mobsf.install.windows.setup import windows_config_local
logger = logging.getLogger(__name__)
VERSION = '4.0.2'
VERSION = '4.0.3'
BANNER = """
__ __ _ ____ _____ _ _ ___
| \/ | ___ | |__/ ___|| ___|_ _| || | / _ \
@@ -161,6 +161,23 @@
owasp-mobile: m1
masvs: platform-7
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#testing-javascript-execution-in-webviews-mstg-platform-5
- id: android_webview_allow_file_from_url
message: >-
Ensure that user controlled URLs never reaches the Webview. Enabling file access
from URLs in WebView can leak sensitive information from the file system.
type: RegexAndOr
pattern:
- setJavaScriptEnabled\(true\)
- - \.setAllowFileAccessFromFileURLs\(true\)
- \.setAllowUniversalAccessFromFileURLs\(true\)
severity: warning
input_case: exact
metadata:
cvss: 6.1
cwe: cwe-200
owasp-mobile: m1
masvs: platform-7
ref: https://github.com/MobSF/owasp-mstg/blob/master/Document/0x05h-Testing-Platform-Interaction.md#static-analysis-6
- id: android_sql_cipher_aes256
message: >-
This App uses SQL Cipher. SQLCipher provides 256-bit AES encryption to
@@ -198,31 +198,28 @@ def ar_extract(src, dst):
def url_n_email_extract(dat, relative_path):
"""Extract URLs and Emails from Source Code."""
urls = []
emails = []
urls = set()
emails = set()
urllist = []
url_n_file = []
email_n_file = []
# URL Extraction
urllist = URL_REGEX.findall(dat.lower())
uflag = 0
for url in urllist:
if url not in urls:
urls.append(url)
uflag = 1
if uflag == 1:
url_n_file.append(
{'urls': urls, 'path': escape(relative_path)})
urls.add(url)
if urls:
url_n_file.append({
'urls': list(urls),
'path': escape(relative_path)})
# Email Extraction
eflag = 0
for email in EMAIL_REGEX.findall(dat.lower()):
if (email not in emails) and (not email.startswith('//')):
emails.append(email)
eflag = 1
if eflag == 1:
email_n_file.append(
{'emails': emails, 'path': escape(relative_path)})
if not email.startswith('//'):
emails.add(email)
if emails:
email_n_file.append({
'emails': list(emails),
'path': escape(relative_path)})
return urllist, url_n_file, email_n_file
Generated
+23 -23
View File
@@ -348,13 +348,13 @@ beautifulsoup4 = "*"
[[package]]
name = "certifi"
version = "2024.2.2"
version = "2024.6.2"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
{file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
{file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"},
{file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"},
]
[[package]]
@@ -736,24 +736,24 @@ dotenv = ["python-dotenv"]
[[package]]
name = "frida"
version = "16.2.5"
version = "16.3.1"
description = "Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers"
optional = false
python-versions = ">=3.7"
files = [
{file = "frida-16.2.5-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:2ad75fce6507641b92e9910be81d894631ae7d4b0c61a7cd0f2224edb963e186"},
{file = "frida-16.2.5-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:746286dc3e44c21beec3e7818038ce175df2debd850780343564b27995f78d6c"},
{file = "frida-16.2.5-cp37-abi3-manylinux1_i686.whl", hash = "sha256:6ff76a814e1a1fbf492a380c5ace4e415a71bd71f40d250f1593517a31bcc504"},
{file = "frida-16.2.5-cp37-abi3-manylinux1_x86_64.whl", hash = "sha256:9f05a10c63ce2ef2063e2288ac497c8be311c39664b658f4757003a3ff6a546b"},
{file = "frida-16.2.5-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:d0c6082a37c7814d45daddb9744febd52dba691e5c0ef5db2660e66e1b266b6e"},
{file = "frida-16.2.5-cp37-abi3-manylinux2014_armv7l.whl", hash = "sha256:af2d6077aced6c47fe94014f5a0680e541c49897b030b383b8666acd70f015e0"},
{file = "frida-16.2.5-cp37-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:f53212a24fb190aa10738021f2f8e402ee305621f0bbc528b8de3ff1182d6d0c"},
{file = "frida-16.2.5-cp37-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:06779eb8e8412c407c55dd1476a18f43232a916dc5fc80dcf1247d2bc1ded553"},
{file = "frida-16.2.5-cp37-abi3-manylinux_2_5_i686.whl", hash = "sha256:d3dfd8206f05e832c00163ba9630a007b0ad83a766225c72f3a3134b50f0d808"},
{file = "frida-16.2.5-cp37-abi3-manylinux_2_5_x86_64.whl", hash = "sha256:3a1dcf378e370e58af76c8dff5ea93d3c59025193d493b69dc23c48170dafe65"},
{file = "frida-16.2.5-cp37-abi3-win32.whl", hash = "sha256:6ee90623b2945964b72169a56de12a6d23996b1c93d4310ab3942060cca5e42e"},
{file = "frida-16.2.5-cp37-abi3-win_amd64.whl", hash = "sha256:42650e5a0595e527cb8fd909e2b32b9d6601ac4dd23b0d051ea46241d13cd6a7"},
{file = "frida-16.2.5.tar.gz", hash = "sha256:4804e136fd344bbd5d22fee10e38bcbd6762a6f388e36e5146c55ea64b8cbe52"},
{file = "frida-16.3.1-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:48dfc17d03700a6e9d0270a187a35360c8abac52a4d8ad88b4ac8cc4308c8b60"},
{file = "frida-16.3.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:735ce89036d1e2f92af85a1763c3110cb7fec4b0204dcd1b18ffd7a21723d27a"},
{file = "frida-16.3.1-cp37-abi3-manylinux1_i686.whl", hash = "sha256:e95f335cf93d6f3ce0e7533c5e6dc3914ba3694283f25721a8da8f5aa6d9ff76"},
{file = "frida-16.3.1-cp37-abi3-manylinux1_x86_64.whl", hash = "sha256:e3c98b03f49ea325b98e9095b73fe581a7b7aa8e4d6190a65f4e32505de30b44"},
{file = "frida-16.3.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:5086c2ccadd4ebdba7a98b721cb9ae1b208270373fb15f39b207b4b0742cad47"},
{file = "frida-16.3.1-cp37-abi3-manylinux2014_armv7l.whl", hash = "sha256:20acfe2eff088e41b677d59747d2f6dbfee8aaab09223d6ca46fb29f4fda63f2"},
{file = "frida-16.3.1-cp37-abi3-manylinux_2_17_aarch64.whl", hash = "sha256:0230989bef733f95d65c72544e5b13983c2d5b4b48e22c0ba0c06ff70e150cc4"},
{file = "frida-16.3.1-cp37-abi3-manylinux_2_17_armv7l.whl", hash = "sha256:de2425faa66a1769ea3eb299eb90fc007cb1922fd1f9a7dc5e22da18dc088902"},
{file = "frida-16.3.1-cp37-abi3-manylinux_2_5_i686.whl", hash = "sha256:35f60b36cd7abad510dfa8889ff39ee332d129e28cfabd6c0d8830122ca8d733"},
{file = "frida-16.3.1-cp37-abi3-manylinux_2_5_x86_64.whl", hash = "sha256:c01dcfc1e2b8a4d6bd3ea4381c54e54a10e169c046b8f9593444fb729b4de646"},
{file = "frida-16.3.1-cp37-abi3-win32.whl", hash = "sha256:c637c3c4f6281e4677c48d91030ead6ed52c5066908a69ab170658414d12355d"},
{file = "frida-16.3.1-cp37-abi3-win_amd64.whl", hash = "sha256:b3770d3040a51e60bcd33f6080b6d3c93e8950cea23773044b07b46e5bbfc02f"},
{file = "frida-16.3.1.tar.gz", hash = "sha256:652f7badc6f27dd8e08a6fb9ba63265d277b37c54f360e521241675a65a9c82f"},
]
[package.dependencies]
@@ -1852,13 +1852,13 @@ files = [
[[package]]
name = "requests"
version = "2.32.2"
version = "2.32.3"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.8"
files = [
{file = "requests-2.32.2-py3-none-any.whl", hash = "sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c"},
{file = "requests-2.32.2.tar.gz", hash = "sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289"},
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[package.dependencies]
@@ -2285,13 +2285,13 @@ telegram = ["requests"]
[[package]]
name = "typing-extensions"
version = "4.12.0"
version = "4.12.1"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"},
{file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"},
{file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"},
{file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"},
]
[[package]]
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "mobsf"
version = "4.0.2"
version = "4.0.3"
description = "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."
keywords = ["mobsf", "mobile security framework", "mobile security", "security tool", "static analysis", "dynamic analysis", "malware analysis"]
authors = ["Ajin Abraham <[email protected]>"]
+2
View File
@@ -4,7 +4,9 @@ set -e
python3 manage.py makemigrations && \
python3 manage.py makemigrations StaticAnalyzer && \
python3 manage.py migrate
set +e
python3 manage.py createsuperuser --noinput --email ""
set -e
python3 manage.py create_roles
exec gunicorn -b 0.0.0.0:8000 "mobsf.MobSF.wsgi:application" --workers=1 --threads=10 --timeout=3600 \