Quark Script
Ecosystem for Mobile Security Tools
Innovative & Interactive
The goal of Quark Script aims to provide an innovative way for mobile security researchers to analyze or pentest the targets.
Based on Quark, we integrate decent tools as Quark Script APIs and make them exchange valuable intelligence to each other. This enables security researchers to interact with staged results and perform creative analysis with Quark Script.
Dynamic & Static Analysis
In Quark script, we integrate not only static analysis tools (e.g. Quark itself) but also dynamic analysis tools (e.g. objection).
Re-Usable & Sharable
Once the user creates a Quark script for specific analysis scenario. The script can be used in another targets. Also, the script can be shared to other security researchers. This enables the exchange of knowledges.
More APIs to come
Quark Script is now in a beta version. We’ll keep releasing practical APIs and analysis scenarios.
Quickstart
Step 1: Environments Requirements
Quark Script requires Python 3.10 or above.
Step 2: Install Quark Engine
You can install Quark Engine by running:
$ pip3 install quark-engine
Step 3: Prepare Quark Script, Detection Rule and the Sample File
Get the CWE-798 Quark Script and the detection rule here.
Get the sampe file (ovaa.apk) here.
Put the script, detection rule, and sample file in the same directory.
Edit accordingly to the file names:
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "findSecretKeySpec.json"
Now you are ready to run the script!
Step 4: Run the script
$ python3 CWE-798.py
You should now see the detection result in the terminal.
Found hard-coded AES key 49u5gh249gh24985ghf429gh4ch8f23f
Introduce of Quark Script APIs
findMethodInAPK(samplePath, targetMethod)
Description: Find the target method in APK
- params:
samplePath: Target file
targetMethod: A python list contains class name, method name, and descriptor of target method
return: Python list contains caller method instance of target method
checkMethodCalls(samplePath, targetMethod, checkMethods)
Description: Check any of the specific methods shown in the target method.
- params:
samplePath: target file
targetMethod: python list contains the class name, method name, and descriptor of the target method or a Method Object
checkMethods: python list contains the class name, method name, and descriptor of the target method
return: bool that indicates if the specific methods are called or defined within a target method or not
Rule(rule.json)
Description: Making detection rule a rule instance
params: Path of a single Quark rule
return: Quark rule instance
runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
Description: Given detection rule and target sample, this instance runs the basic Quark analysis.
- params:
SAMPLE_PATH: Target file
ruleInstance: Quark rule object
return: quarkResult instance
quarkResultInstance.behaviorOccurList
Description: List that stores instances of detected behavior in different part of the target file.
params: none
return: detected behavior instance
quarkResultInstance.getAllStrings(none)
Description: Get all strings inside the target APK file.
params: none
return: python list containing all strings inside the target APK file.
quarkResultInstance.isHardcoded(argument)
Description: Check if the argument is hardcoded into the APK.
- params:
argument: string value that is passed in when a method is invoked
return: True/False
quarkResultInstance.findMethodInCaller(callerMethod, targetMethod)
Description: Find target method in caller method.
- params:
callerMethod: python list contains class name, method name and descriptor of caller method.
targetMethod: python list contains class name, method name and descriptor of target method.
return: python list contains target method instances.
behaviorInstance.firstAPI.fullName
Description: Show the name of the first key API called in this behavior.
params: none
return: API name
behaviorInstance.secondAPI.fullName
Description: Show the name of the second key API called in this behavior.
params: none
return: API name
behaviorInstance.hasString(pattern, isRegex)
Description: Check if the arguments of the two APIs contain the string.
- params:
pattern: string that may appear in the arguments
isRegex: consider the string as a regular expression if True, defaults to False
return: the matched string
behaviorInstance.hasUrl(none)
Description: Check if the behavior contains urls.
params: none
return: python list containing all detected urls.
behaviorInstance.methodCaller
Description: Find method who calls this behavior (API1 & API2).
params: none
return: method instance
behaviorInstance.getParamValues(none)
Description: Get parameter values that API1 sends to API2 in the behavior.
params: none
return: python list containing parameter values.
behaviorInstance.isArgFromMethod(targetMethod)
Description: Check if there are any arguments from the target method.
- params:
targetMethod: python list contains class name, method name, and descriptor of target method
return: True/False
behaviorInstance.getMethodsInArgs(none)
Description: Get the methods which the arguments in API2 has passed through.
params: none
return: python list containing method instances
methodInstance.getXrefFrom(none)
Description: Find out who call this method.
params: none
return: python list containing caller methods.
methodInstance.getXrefTo(none)
Description: Find out who this method called.
params: none
return: python list containing tuples (callee methods, index).
methodInstance.getArguments(none)
Description: Get arguments from method.
params: none
return: python list containing arguments.
methodInstance.findSuperclassHierarchy(none)
Description: Find all superclasses of this method object.
params: none
return: Python list contains all superclass names of this method.
Objection(host)
Description: Create an instance for Objection (dynamic analysis tool).
params: Monitoring IP:port
return: objection instance
objInstance.hookMethod(method, watchArgs, watchBacktrace, watchRet)
Description: Hook the target method with Objection.
- params:
method: the target API. (type: str or method instance)
watchArgs: Return Args information if True. (type: boolean)
watchBacktrace: Return backtrace information if True. (type: boolean)
watchRet: Return the return information of the target API if True. (type: boolean)
return: none
runFridaHook(apkPackageName, targetMethod, methodParamTypes, secondToWait)
Description: Track calls to the specified method for given seconds.
- params:
apkPackageName: the package name of the target APP
targetMethod: the target API
methodParamTypes: string that holds the parameters used by the target API
secondToWait: seconds to wait for method calls, defaults to 10
return: FridaResult instance
checkClearText(inputString)
Description: Check the decrypted value of the input string.
- params:
inputString: string to be checked
return: the decrypted value
getActivities(samplePath)
Description: Get activities from the manifest of target sample.
- params:
samplePath: the file path of target sample
return: python list containing activities
activityInstance.hasIntentFilter(none)
Description: Check if the activity has an intent-filter.
params: none
return: True/False
activityInstance.isExported(none)
Description: Check if the activity set
android:exported=true
.params: none
return: True/False
getReceivers(samplePath)
Description: Get receivers from a target sample.
- params:
samplePath: target sample
return: python list containing receivers
receiverInstance.hasIntentFilter(none)
Description: Check if the receiver has an intent-filter.
params: none
return: True/False
receiverInstance.isExported(none)
Description: Check if the receiver is exported.
params: none
return: True/False
getApplication(samplePath)
Description: Get the application element from the manifest file of the target sample.
- params:
samplePath: the file path of the target sample
return: the application element of the target sample
applicationInstance.isDebuggable(none)
Description: Check if the application element sets
android:debuggable=true
.params: none
return: True/False
Analyzing real case (InstaStealer) using Quark Script
Quark Script that dynamic hooks the method containing urls
The scenario is simple! We’d like to dynamic hooking the methods in the malware that contains urls. We can use APIs above to write Quark Script.
from quark.script import runQuarkAnalysis, Rule
from quark.script.objection import Objection
SAMPLE_PATH = "6f032.apk"
RULE_PATH = "00211.json"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for behaviorInstance in quarkResult.behaviorOccurList:
detectedUrl = behaviorInstance.hasUrl()
if detectedUrl:
print(f"\nDetected Behavior -> {ruleInstance.crime}")
print(f"\nDetected Url -> {detectedUrl}")
method = behaviorInstance.methodCaller
print(f"\nThe detected behavior was called by -> {method.fullName}")
print("\nAttempt to hook the method:")
obj = Objection("127.0.0.1:8888")
obj.hookMethod(method,
watchArgs=True,
watchBacktrace=True,
watchRet=True)
print(f"\tHook -> {method.fullName}")
for methodCaller in method.getXrefFrom():
obj.hookMethod(methodCaller,
watchArgs=True,
watchBacktrace=True,
watchRet=True)
print(f"\tHook -> {methodCaller.fullName}")
for methodCallee, _ in method.getXrefTo():
obj.hookMethod(methodCallee,
watchArgs=True,
watchBacktrace=True,
watchRet=True)
print(f"\tHook -> {methodCallee.fullName}")
print("\nSee the hook results in Objection's terminal.")
Note
Please make sure you have the dynamic analysis environment ready before executing the script.
Quark Script Result
Logs on the Objection terminal (hooking)
Method (callComponentMethod) with urls is detected triggered!
Detect CWE-798 in Android Application
This scenario seeks to find hard-coded credentials in the APK file.
CWE-798 Use of Hard-coded Credentials
We analyze the definition of CWE-798 and identify its characteristics.
See CWE-798 for more details.
Code of CWE-798 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-798.
Quark Script: CWE-798.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule findSecretKeySpec.json
to spot on behavior using the method SecretKeySpec
. Then, we get all the parameter values that are input to this method. And we parse the AES key out of the parameter values. Finally, we check if the AES key is hardcoded in the APK file. If the answer is YES, BINGO!!! We find hard-coded credentials in the APK file.
import re
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "findSecretKeySpec.json"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for secretKeySpec in quarkResult.behaviorOccurList:
firstParam = secretKeySpec.secondAPI.getArguments()[1]
secondParam = secretKeySpec.secondAPI.getArguments()[2]
if secondParam == "AES":
AESKey = re.findall(r"\((.*?)\)", firstParam)[1]
if quarkResult.isHardcoded(AESKey):
print(f"Found hard-coded {secondParam} key {AESKey}")
Quark Rule: findSecretKeySpec.json
{
"crime": "Detect APK using SecretKeySpec.",
"permission": [],
"api": [
{
"descriptor": "()[B",
"class": "Ljava/lang/String;",
"method": "getBytes"
},
{
"descriptor": "([BLjava/lang/String;)V",
"class": "Ljavax/crypto/spec/SecretKeySpec;",
"method": "<init>"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 findSecretKeySpec.py
Found hard-coded AES key 49u5gh249gh24985ghf429gh4ch8f23f
Detect CWE-94 in Android Application
This scenario seeks to find code injection in the APK file.
CWE-94 Improper Control of Generation of Code
We analyze the definition of CWE-94 and identify its characteristics.
See CWE-94 for more details.
Code of CWE-94 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-94.
Quark Script: CWE-94.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule loadExternalCode.json
to spot on behavior using the method createPackageContext
. Then, we find the caller method that calls the createPackageContext
. Finally, we check if the method checkSignatures
is called in the caller method for verification.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "loadExternalCode.json"
targetMethod = [
"Landroid/content/pm/PackageManager;",
"checkSignatures",
"(Ljava/lang/String;Ljava/lang/String;)I"
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for ldExternalCode in quarkResult.behaviorOccurList:
callerMethod = [
ldExternalCode.methodCaller.className,
ldExternalCode.methodCaller.methodName,
ldExternalCode.methodCaller.descriptor
]
if not quarkResult.findMethodInCaller(callerMethod, targetMethod):
print(f"Method: {targetMethod[1]} not found!")
print(f"CWE-94 is detected in {SAMPLE_PATH}")
Quark Rule: loadExternalCode.json
{
"crime": "Load external code from other APK.",
"permission": [],
"api": [
{
"descriptor": "(Ljava/lang/String;I)Landroid/content/Context;",
"class": "",
"method": "createPackageContext"
},
{
"descriptor": "(Ljava/lang/String;)Ljava/lang/Class;",
"class": "Ljava/lang/ClassLoader;",
"method": "loadClass"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-94.py
Method: checkSignatures not found!
CWE-94 is detected in ovaa.apk
Detect CWE-921 in Android Application
This scenario seeks to find the unsecured storage mechanism of sensitive data in the APK file.
CWE-921 Storage of Sensitive Data in a Mechanism without Access Control
We analyze the definition of CWE-921 and identify its characteristics.
See CWE-921 for more details.
Code of CWE-921 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-921.
Quark Script: CWE-921.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule checkFileExistence.json
to spot on behavior that checks if a file exists on a given storage mechanism. Then, we use API methodInstance.getArguments()
to get the file path. Finally, CWE-921 is found if the file path contains the keyword sdcard
.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "checkFileExistence.json"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for existingFile in quarkResult.behaviorOccurList:
filePath = existingFile.secondAPI.getArguments()[0]
if "sdcard" in filePath:
print(f"This file is stored inside the SDcard\n")
print(f"CWE-921 is detected in {SAMPLE_PATH}.")
Quark Rule: checkFileExistence.json
{
"crime": "Check file existence",
"permission": [],
"api": [
{
"descriptor": "(Ljava/lang/String;)V",
"class": "Ljava/io/File;",
"method": "<init>"
},
{
"descriptor": "()Z",
"class": "Ljava/io/File;",
"method": "exists"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-921.py
This file is stored inside the SDcard
CWE-921 is detected in ovaa.apk.
Detect CWE-312 in Android Application
This scenario seeks to find cleartext storage of sensitive data in the APK file.
CWE-312: Cleartext Storage of Sensitive Information
We analyze the definition of CWE-312 and identify its characteristics.
See CWE-312 for more details.
Code of CWE-312 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-312.
CWE-312 Detection Process Using Quark Script API
Let’s use the above APIs to show how the Quark script finds this vulnerability.
We have designed a Frida script agent.js
to hook a specified method and get the arguments when the method is called. It can be found in quark-engine/quark/script/frida.
To begin with, we hook the method putString
to catch its arguments. Then, we check if sensitive information like email or password is passed. Finally, we use checkClearText
imported from Ares to check if the arguments are cleartext. If both YES, CWE-312 vulnerability might be caused.
Quark Script: CWE-312.py
from quark.script.frida import runFridaHook
from quark.script.ares import checkClearText
APP_PACKAGE_NAME = "oversecured.ovaa"
TARGET_METHOD = "android.app." "SharedPreferencesImpl$EditorImpl." "putString"
METHOD_PARAM_TYPE = "java.lang.String," "java.lang.String"
fridaResult = runFridaHook(
APP_PACKAGE_NAME, TARGET_METHOD, METHOD_PARAM_TYPE, secondToWait=10
)
for putString in fridaResult.behaviorOccurList:
firstParam = putString.firstAPI.getArguments()
secondParam = putString.secondAPI.getArguments()
if firstParam in ["email", "password"] and secondParam == checkClearText(
secondParam
):
print(
"The CWE-312 vulnerability is found. "
f'The cleartext is "{secondParam}"'
)
Frida Script: agent.js
// -*- coding: utf-8 -*-
// This file is part of Quark-Engine - https://github.com/quark-engine/quark-engine
// See the file 'LICENSE' for copying permission.
/*global Java, send, rpc*/
function replaceMethodImplementation(targetMethod, classAndMethodName, methodParamTypes, returnType) {
targetMethod.implementation = function () {
let callEvent = {
"type": "CallCaptured",
"identifier": [classAndMethodName, methodParamTypes, returnType],
"paramValues": []
};
for (const arg of arguments) {
callEvent["paramValues"].push((arg || "(none)").toString());
}
send(JSON.stringify(callEvent));
return targetMethod.apply(this, arguments);
};
}
function watchMethodCall(classAndMethodName, methodParamTypes) {
if (classAndMethodName == null || methodParamTypes == null) {
return;
}
const indexOfLastSeparator = classAndMethodName.lastIndexOf(".");
const classNamePattern = classAndMethodName.substring(0, indexOfLastSeparator);
const methodNamePattern = classAndMethodName.substring(indexOfLastSeparator + 1);
Java.perform(() => {
const classOfTargetMethod = Java.use(classNamePattern);
const possibleMethods = classOfTargetMethod[`${methodNamePattern}`];
if (typeof possibleMethods === "undefined") {
const failedToWatchEvent = {
"type": "FailedToWatch",
"identifier": [classAndMethodName, methodParamTypes]
};
send(JSON.stringify(failedToWatchEvent));
return;
}
possibleMethods.overloads.filter((possibleMethod) => {
const paramTypesOfPossibleMethod = possibleMethod.argumentTypes.map((argument) => argument.className);
return paramTypesOfPossibleMethod.join(",") === methodParamTypes;
}).forEach((matchedMethod) => {
const retType = matchedMethod.returnType.name;
replaceMethodImplementation(matchedMethod, classAndMethodName, methodParamTypes, retType);
}
);
});
}
rpc.exports["watchMethodCall"] = (classAndMethodName, methodParamTypes) => watchMethodCall(classAndMethodName, methodParamTypes);
Quark Script Result
$ python3 CWE-312.py
The CWE-312 vulnerability is found. The cleartext is "test@email.com"
The CWE-312 vulnerability is found. The cleartext is "password"
Detect CWE-89 in Android Application
This scenario seeks to find SQL injection in the APK file.
CWE-89 Improper Neutralization of Special Elements used in an SQL Command
We analyze the definition of CWE-89 and identify its characteristics.
See CWE-89 for more details.
Code of CWE-89 in androgoat.apk
We use the androgoat.apk sample to explain the vulnerability code of CWE-89.
Quark Script: CWE-89.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule executeSQLCommand.json
to spot on behavior using SQL command Execution. Then, we use API behaviorInstance.isArgFromMethod(targetMethod)
to check if append
uses the value of getText
as the argument. If yes, we confirmed that the SQL command string is built from user input, which will cause CWE-89 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "AndroGoat.apk"
RULE_PATH = "executeSQLCommand.json"
targetMethod = [
"Landroid/widget/EditText;", # class name
"getText", # method name
"()Landroid/text/Editable;", # descriptor
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for sqlCommandExecution in quarkResult.behaviorOccurList:
if sqlCommandExecution.isArgFromMethod(
targetMethod
):
print(f"CWE-89 is detected in {SAMPLE_PATH}")
Quark Rule: executeSQLCommand.json
{
"crime": "Execute SQL Command",
"permission": [],
"api": [
{
"class": "Ljava/lang/StringBuilder;",
"method": "append",
"descriptor": "(Ljava/lang/String;)Ljava/lang/StringBuilder;"
},
{
"class": "Landroid/database/sqlite/SQLiteDatabase;",
"method": "rawQuery",
"descriptor": "(Ljava/lang/String; [Ljava/lang/String;)Landroid/database/Cursor;"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-89.py
CWE-89 is detected in AndroGoat.apk
Detect CWE-926 in Android Application
This scenario seeks to find Improper Export of Android Application Components in the APK file.
CWE-926 Improper Export of Android Application Components
We analyze the definition of CWE-926 and identify its characteristics.
See CWE-926 for more details.
Code of CWE-926 in dvba.apk
We use the dvba.apk sample to explain the vulnerability code of CWE-926.
Quark Script: CWE-926.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we use Quark API getActivities(samplePath)
to get all activity data in the manifest. Then, we use activityInstance.hasIntentFilter()
to check if the activities have intent-filter
. Also, we use activityInstance.isExported()
to check if the activities set the attribute android:exported=true
. If both are true, then the APK exports the component for use by other applications. That may cause CWE-926 vulnerabilities.
from quark.script import *
SAMPLE_PATH = "dvba.apk"
for activityInstance in getActivities(SAMPLE_PATH):
if activityInstance.hasIntentFilter() and activityInstance.isExported():
print(f"CWE-926 is detected in the activity, {activityInstance}")
Quark Script Result
$ python3 CWE-926.py
CWE-926 is detected in the activity, com.app.damnvulnerablebank.CurrencyRates
CWE-926 is detected in the activity, com.app.damnvulnerablebank.SplashScreen
Detect CWE-749 in Android Application
This scenario seeks to find exposed methods or functions in the APK file.
CWE-749 Exposed Dangerous Method or Function
We analyze the definition of CWE-749 and identify its characteristics.
See CWE-749 for more details.
Code of CWE-749 in MSTG-Android-Java.apk
We use the MSTG-Android-Java.apk sample to explain the vulnerability code of CWE-749.
Quark Script CWE-749.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule configureJsExecution.json
to spot on behavior using the method setJavascriptEnabled
. Then, we use the API methodInstance.getArguments()
to check if it enables JavaScript execution on websites. Finally, we look for calls to the method addJavaScriptInterface
in the caller method. If yes, the APK exposes dangerous methods or functions to websites. That causes CWE-749 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "MSTG-Android-Java.apk"
RULE_PATH = "configureJsExecution.json"
targetMethod = [
"Landroid/webkit/WebView;",
"addJavascriptInterface",
"(Ljava/lang/Object; Ljava/lang/String;)V"
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for configureJsExecution in quarkResult.behaviorOccurList:
caller = configureJsExecution.methodCaller
secondAPI = configureJsExecution.secondAPI
enableJS = secondAPI.getArguments()[1]
exposeAPI = quarkResult.findMethodInCaller(caller, targetMethod)
if enableJS and exposeAPI:
print(f"CWE-749 is detected in method, {caller.fullName}")
Quark Rule: configureJsExecution.json
{
"crime": "Configure JavaScript execution on websites",
"permission": [],
"api": [
{
"class": "Landroid/webkit/WebView;",
"method": "getSettings",
"descriptor": "()Landroid/webkit/WebSettings;"
},
{
"class": "Landroid/webkit/WebSettings;",
"method": "setJavaScriptEnabled",
"descriptor": "(Z)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-749.py
CWE-749 is detected in method, Lsg/vp/owasp_mobile/OMTG_Android/OMTG_ENV_005_WebView_Remote; onCreate (Landroid/os/Bundle;)V
CWE-749 is detected in method, Lsg/vp/owasp_mobile/OMTG_Android/OMTG_ENV_005_WebView_Local; onCreate (Landroid/os/Bundle;)V
Detect CWE-532 in Android Application
This scenario seeks to find insertion of sensitive information into Log file in the APK file.
CWE-532: Insertion of Sensitive Information into Log File
We analyze the definition of CWE-532 and identify its characteristics.
See CWE-532 for more details.
Code of CWE-532 in dvba.apk
We use the dvba.apk sample to explain the vulnerability code of CWE-532.
Quark Scipt: CWE-532.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we use the API findMethodInAPK(samplePath, targetMethod)
to locate log.d
method. Then we use API methodInstance.getArguments()
to get the argument that input to log.d
. Finally, we use some keywords such as “token”, “password”, and “decrypt” to check if arguments include sensitive data. If the answer is YES, that may cause sensitive data leakage into log file.
You can use your own keywords in the keywords list to detect sensitive data.
from quark.script import findMethodInAPK
SAMPLE_PATH = "dvba.apk"
TARGET_METHOD = [
"Landroid/util/Log;", # class name
"d", # method name
"(Ljava/lang/String; Ljava/lang/String;)I" # descriptor
]
CREDENTIAL_KEYWORDS = [
"token",
"decrypt",
"password"
]
methodsFound = findMethodInAPK(SAMPLE_PATH, TARGET_METHOD)
for debugLogger in methodsFound:
arguments = debugLogger.getArguments()
for keyword in CREDENTIAL_KEYWORDS:
if keyword in arguments[1]:
print(f"CWE-532 is detected in method, {debugLogger.fullName}")
Quark Script Result
$ python CWE-532.py
CWE-532 is detected in method, Lcom/google/firebase/auth/FirebaseAuth; d (Lc/c/b/h/o;)V
Detect CWE-780 in Android Application
This scenario seeks to find the use of the RSA algorithm without Optimal Asymmetric Encryption Padding (OAEP) in the APK file.
CWE-780 Use of RSA Algorithm without OAEP
We analyze the definition of CWE-780 and identify its characteristics.
See CWE-780 for more details.
Code of CWE-780 in dvba.apk
We use the MSTG-Android-Java.apk sample to explain the vulnerability code of CWE-780.
Quark Script: CWE-780.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
We first design a detection rule useOfCryptographicAlgo.json
to spot on behavior using the cryptographic algorithm. Then, we use API behaviorInstance.hasString(pattern, isRegex)
to filter behaviors using the RSA algorithm. Finally, we use the same API to check if the algorithm runs without the OAEP scheme. If the answer is YES, the plaintext is predictable.
from quark.script import Rule, runQuarkAnalysis
SAMPLE_PATH = "MSTG-Android-Java.apk"
RULE_PATH = "useOfCryptographicAlgo.json"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for useCryptographicAlgo in quarkResult.behaviorOccurList:
methodCaller = useCryptographicAlgo.methodCaller
if useCryptographicAlgo.hasString(
"RSA"
) and not useCryptographicAlgo.hasString("OAEP"):
print(f"CWE-780 is detected in method, {methodCaller.fullName}")
Quark Rule: useOfCryptographicAlgo.json
{
"crime": "Use of cryptographic algorithm",
"permission": [],
"api": [
{
"class": "Ljavax/crypto/Cipher;",
"method": "getInstance",
"descriptor": "(Ljava/lang/String; Ljava/lang/String;)Ljavax/crypto/Cipher"
},
{
"class": "Ljavax/crypto/Cipher;",
"method": "init",
"descriptor": "(I Ljava/security/Key;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-780.py
CWE-780 is detected in method, Lsg/vp/owasp_mobile/OMTG_Android/OMTG_DATAST_001_KeyStore; encryptString (Ljava/lang/String;)V
Detect CWE-319 in Android Application
This scenario seeks to find Cleartext Transmission of Sensitive Information in the APK file.
CWE-319 Cleartext Transmission of Sensitive Information
We analyze the definition of CWE-319 and identify its characteristics.
See CWE-319 for more details.
Code of CWE-319 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-319.
Quark Script: CWE-319.py
Let’s use the above APIs to show how the Quark script finds this vulnerability. This sample uses the package Retrofit to request Web APIs, but the APIs use cleartext protocols.
We first design a detection rule setRetrofitBaseUrl.json
to spot on behavior that sets the base URL of the Retrofit instance. Then, we loop through a custom list of cleartext protocol schemes and use API behaviorInstance.hasString(pattern, isRegex)
to filter arguments that are URL strings with cleartext protocol.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "./ovaa.apk"
RULE_PATH = "setRetrofitBaseUrl.json"
PROTOCOL_KEYWORDS = [
"http",
"smtp",
"ftp"
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for setRetrofitBaseUrl in quarkResult.behaviorOccurList:
for protocol in PROTOCOL_KEYWORDS:
regexRule = f"{protocol}://[0-9A-Za-z./-]+"
cleartextProtocolUrl = setRetrofitBaseUrl.hasString(regexRule, True)
if cleartextProtocolUrl:
print(f"CWE-319 detected!")
print(f"Here are the found URLs with cleartext protocol:")
print("\n".join(cleartextProtocolUrl))
Quark Rule: setRetrofitBaseUrl.json
{
"crime": "Set Retrofit Base Url",
"permission": [],
"api":
[
{
"descriptor": "()V",
"class": "Lretrofit2/Retrofit$Builder;",
"method": "<init>"
},
{
"descriptor": "(Ljava/lang/String;)Lretrofit2/Retrofit$Builder;",
"class": "Lretrofit2/Retrofit$Builder;",
"method": "baseUrl"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-319.py
CWE-319 detected!
Here are the found URLs with cleartext protocol:
http://example.com./api/v1/
Detect CWE-327 in Android Application
This scenario seeks to find Use of a Broken or Risky Cryptographic Algorithm in the APK file.
CWE-327 Use of a Broken or Risky Cryptographic Algorithm
We analyze the definition of CWE-327 and identify its characteristics.
See CWE-327 for more details.
Code of CWE-327 in InjuredAndroid.apk
We use the InjuredAndroid.apk sample to explain the vulnerability code of CWE-327.
Quark Script CWE-327.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
We first design a detection rule useOfCryptographicAlgo.json
to spot on behavior using cryptographic algorithms. Then, we use API behaviorInstance.hasString(pattern, isRegex)
with a list to check if the algorithm is risky. If YES, that may cause the exposure of sensitive data.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "InjuredAndroid.apk"
RULE_PATH = "useOfCryptographicAlgo.json"
WEAK_ALGORITHMS = ["DES", "ARC4", "BLOWFISH"]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for useCryptoAlgo in quarkResult.behaviorOccurList:
caller = useCryptoAlgo.methodCaller
for algo in WEAK_ALGORITHMS:
if useCryptoAlgo.hasString(algo):
print(f"CWE-327 is detected in method, {caller.fullName}")
Quark Rule: useOfCryptographicAlgo.json
{
"crime": "Use of cryptographic algorithm",
"permission": [],
"api": [
{
"class": "Ljavax/crypto/Cipher;",
"method": "getInstance",
"descriptor": "(Ljava/lang/String;)Ljavax/crypto/Cipher"
},
{
"class": "Ljavax/crypto/Cipher;",
"method": "init",
"descriptor": "(I Ljava/security/Key;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-327.py
CWE-327 is detected in method, Lb3nac/injuredandroid/k; b (Ljava/lang/String;)Ljava/lang/String;
CWE-327 is detected in method, Lb3nac/injuredandroid/k; a (Ljava/lang/String;)Ljava/lang/String;
Detect CWE-20 in Android Application
This scenario seeks to find Improper Input Validation in the APK file.
CWE-20 Improper Input Validation
We analyze the definition of CWE-20 and identify its characteristics.
See CWE-20 for more details.
Code of CWE-20 in diva.apk
We use the diva.apk sample to explain the vulnerability code of CWE-20.
Quark Script CWE-20.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule openUrlThatUserInput.json
, to spot the behavior of opening the URL that the user inputs. Then, we use API behaviorInstance.getMethodsInArgs()
to get a list of methods that the URL in loadUrl
passes through. Finally, we check if any validation method is in the list. If No, the APK does not validate user input. That causes CWE-20 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "diva.apk"
RULE_PATH = "openUrlThatUserInput.json"
rule = Rule(RULE_PATH)
result = runQuarkAnalysis(SAMPLE_PATH, rule)
VALIDATE_METHODS = ["contains", "indexOf", "matches", "replaceAll"]
for openUrl in result.behaviorOccurList:
calledMethods = openUrl.getMethodsInArgs()
if not any(
method.methodName in VALIDATE_METHODS for method in calledMethods
):
print(f"CWE-20 is detected in method, {openUrl.methodCaller.fullName}")
Quark Rule: openUrlThatUserInput.json
{
"crime": "Open the Url that user input",
"permission": [],
"api": [
{
"class": "Landroid/widget/EditText;",
"method": "getText",
"descriptor": "()Landroid/text/Editable;"
},
{
"class": "Landroid/webkit/WebView;",
"method": "loadUrl",
"descriptor": "(Ljava/lang/String;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-20.py
CWE-20 is detected in method, Ljakhar/aseem/diva/InputValidation2URISchemeActivity; get (Landroid/view/View;)V
Detect CWE-79 in Android Application
This scenario seeks to find Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’) in the APK file.
CWE-79 Improper Neutralization of Input During Web Page Generation (‘Cross-site Scripting’)
We analyze the definition of CWE-79 and identify its characteristics.
See CWE-79 for more details.
Code of CWE-79 in Vuldroid.apk
We use the Vuldroid.apk sample to explain the vulnerability code of CWE-79.
Quark Script CWE-79.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule loadUrlFromIntent.json
to spot the behavior loading URL from intent data to the WebView instance.
Next, we use API quarkResultInstance.findMethodInCaller(callerMethod, targetMethod)
and methodInstance.getArguments()
to check if the Javascript execution is enabled in the WebView. Finally, we check if there are any famous XSS filters. If NO, that may cause CWE-79 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "Vuldroid.apk"
RULE_PATH = "loadUrlFromIntent.json"
XSS_FILTERS = [
[
"Lorg/owasp/esapi/Validator;",
"getValidSafeHTML",
"(Ljava/lang/String; Ljava/lang/String; I Z)Ljava/lang/String;",
],
[
"Lorg/owasp/esapi/Encoder;",
"encodeForHTML",
"(Ljava/lang/String;)Ljava/lang/String;",
],
[
"Lorg/owasp/esapi/Encoder;",
"encodeForJavaScript",
"(Ljava/lang/String;)Ljava/lang/String;",
],
[
"Lorg/owasp/html/PolicyFactory;",
"sanitize",
"(Ljava/lang/String;)Ljava/lang/String;",
],
]
targetMethod = ["Landroid/webkit/WebSettings;", "setJavaScriptEnabled", "(Z)V"]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for loadUrl in quarkResult.behaviorOccurList:
caller = loadUrl.methodCaller
setJS = quarkResult.findMethodInCaller(caller, targetMethod)
enableJS = []
if setJS:
enableJS = setJS[0].getArguments()[1]
if enableJS:
XSSFiltersInCaller = [
filterAPI
for filterAPI in XSS_FILTERS
if quarkResult.findMethodInCaller(caller, filterAPI)
]
if not XSSFiltersInCaller:
print(f"CWE-79 is detected in method, {caller.fullName}")
Quark Rule: loadUrlFromIntent.json
{
"crime": "Load URL from intent to WebView",
"permission": [],
"api": [
{
"descriptor": "()Landroid/net/Uri;",
"class": "Landroid/content/Intent;",
"method": "getData"
},
{
"descriptor": "(Ljava/lang/String;)V",
"class": "Landroid/webkit/WebView;",
"method": "loadUrl"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-79.py
CWE-79 is detected in method, Lcom/vuldroid/application/ForgetPassword; onCreate (Landroid/os/Bundle;)V
Detect CWE-328 in Android Application
This scenario seeks to find the use of weak Hash.
CWE-328 Use of Weak Hash
We analyze the definition of CWE-328 and identify its characteristics.
See CWE-328 for more details.
Code of CWE-328 in allsafe.apk
We use the allsafe.apk sample to explain the vulnerability code of CWE-328.
Quark Script: CWE-328.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we use API findMethodInAPK(samplePath, targetMethod)
to find the method MessageDigest.getInstance()
or SecretKeyFactory.getInstance()
. Next, we use API methodInstance.getArguments()
with a list to check if the method uses weak hashing algorithms. If YES, that causes CWE-328 vulnerability.
from quark.script import findMethodInAPK
SAMPLE_PATH = "./allsafe.apk"
TARGET_METHODS = [
[
"Ljava/security/MessageDigest;",
"getInstance",
"(Ljava/lang/String;)Ljava/security/MessageDigest;",
],
[
"Ljavax/crypto/SecretKeyFactory;",
"getInstance",
"(Ljava/lang/String;)Ljavax/crypto/SecretKeyFactory;",
],
]
HASH_KEYWORDS = [
"MD2",
"MD4",
"MD5",
"PANAMA",
"SHA0",
"SHA1",
"HAVAL128",
"RIPEMD128",
]
methodsFound = []
for target in TARGET_METHODS:
methodsFound += findMethodInAPK(SAMPLE_PATH, target)
for setHashAlgo in methodsFound:
algoName = setHashAlgo.getArguments()[0].replace("-", "")
if any(keyword in algoName for keyword in HASH_KEYWORDS):
print(
f"CWE-328 is detected in {SAMPLE_PATH},\n\t"
f"and it occurs in method, {setHashAlgo.fullName}"
)
Quark Script Result
$ python3 CWE-328.py
CWE-328 is detected in ./allsafe.apk,
and it occurs in method, Linfosecadventures/allsafe/challenges/SQLInjection; md5 (Ljava/lang/String;)Ljava/lang/String;
CWE-328 is detected in ./allsafe.apk,
and it occurs in method, Linfosecadventures/allsafe/challenges/WeakCryptography; md5Hash (Ljava/lang/String;)Ljava/lang/String;
CWE-328 is detected in ./allsafe.apk,
and it occurs in method, Lcom/google/firebase/database/core/utilities/Utilities; sha1HexDigest (Ljava/lang/String;)Ljava/lang/String;
Detect CWE-295 in Android Application
This scenario seeks to find Improper Certificate Validation.
CWE-295: Improper Certificate Validation
We analyze the definition of CWE-295 and identify its characteristics.
See CWE-295 for more details.
Code of CWE-295 in InsecureShop.apk
We use the InsecureShop.apk sample to explain the vulnerability code of CWE-295.
Quark Script CWE-295.py
To begin with, we use the API findMethodInAPK(samplePath, targetMethod)
to locate all callers of method SslErrorHandler.proceed
.
Next, we must verify whether the caller overrides the method WebViewClient.onReceivedSslErroris
.
Therefore, we check if the method name and descriptor of the caller match those of WebViewClient.onReceivedSslErroris
. After that, we use the API methodInstance.findSuperclassHierarchy()
to check if the superclasses of the caller include Landroid/webkit/WebViewClient
.
If both are YES, the APK will call SslErrorHandler.procees
without certificate validation when an SSL error occurs, which may cause CWE-295 vulnerability.
from quark.script import findMethodInAPK
SAMPLE_PATH = "insecureShop.apk"
TARGET_METHOD = [
"Landroid/webkit/SslErrorHandler;", # class name
"proceed", # method name
"()V" # descriptor
]
OVERRIDDEN_METHOD = [
"Landroid/webkit/WebViewClient;", # class name
"onReceivedSslError", # method name
"(Landroid/webkit/WebView;" + " Landroid/webkit/SslErrorHandler;" + \
" Landroid/net/http/SslError;)V" # descriptor
]
for sslProceedCaller in findMethodInAPK(SAMPLE_PATH, TARGET_METHOD):
if (
sslProceedCaller.name == OVERRIDDEN_METHOD[1]
and sslProceedCaller.descriptor == OVERRIDDEN_METHOD[2]
and OVERRIDDEN_METHOD[0] in sslProceedCaller.findSuperclassHierarchy()
):
print(f"CWE-295 is detected in method, {sslProceedCaller.fullName}")
Quark Script Result
$ python3 CWE-295.py
CWE-295 is detected in method, Lcom/insecureshop/util/CustomWebViewClient; onReceivedSslError (Landroid/webkit/WebView; Landroid/webkit/SslErrorHandler; Landroid/net/http/SslError;)V
Detect CWE-489 in Android Application
This scenario seeks to find active debug code.
CWE-489: active debug code
We analyze the definition of CWE-489 and identify its characteristics.
See CWE-489 for more details.
Code of CWE-489 in allsafe.apk
We use the allsafe.apk sample to explain the vulnerability code of CWE-489.
Quark Script CWE-489.py
First, we use Quark API getApplication(samplePath)
to get the application element in the manifest file. Then we use applicationInstance.isDebuggable()
to check if the application element sets the attribute android:debuggable
to true. If Yes, that causes CWE-489 vulnerabilities.
from quark.script import getApplication
SAMPLE_PATH = "allsafe.apk"
if getApplication(SAMPLE_PATH).isDebuggable():
print(f"CWE-489 is detected in {SAMPLE_PATH}.")
Quark Script Result
$ python3 CWE-489.py
CWE-489 is detected in allsafe.apk.
Detect CWE-22 in Android Application
This scenario seeks to find the improper limitation of a pathname to a restricted directory (‘Path Traversal’).
CWE-22: Improper Limitation of a Pathname to a Restricted Directory (‘Path Traversal’)
We analyze the definition of CWE-22 and identify its characteristics.
See CWE-22 for more details.
Code of CWE-22 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-22.
Quark Script: CWE-22.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule accessFileInExternalDir.json
to spot behavior accessing a file in an external directory.
Next, we use API methodInstance.getArguments()
to get the argument for the file path and use quarkResultInstance.isHardcoded(argument)
to check if the argument is hardcoded into the APK. If No, the argument is from external input.
Finally, we use Quark API quarkResultInstance.findMethodInCaller(callerMethod, targetMethod)
to check if there are any APIs in the caller method for string matching. If NO, the APK does not neutralize special elements within the argument, which may cause CWE-22 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "accessFileInExternalDir.json"
STRING_MATCHING_API = [
["Ljava/lang/String;", "contains", "(Ljava/lang/CharSequence)Z"],
["Ljava/lang/String;", "indexOf", "(I)I"],
["Ljava/lang/String;", "indexOf", "(Ljava/lang/String;)I"],
["Ljava/lang/String;", "matches", "(Ljava/lang/String;)Z"],
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for accessExternalDir in quarkResult.behaviorOccurList:
filePath = accessExternalDir.secondAPI.getArguments()[2]
if quarkResult.isHardcoded(filePath):
continue
caller = accessExternalDir.methodCaller
strMatchingAPIs = [
api
for api in STRING_MATCHING_API
if quarkResult.findMethodInCaller(caller, api)
]
if not strMatchingAPIs:
print(f"CWE-22 is detected in method, {caller.fullName}")
Quark Rule: accessFileInExternalDir.json
{
"crime": "Access a file in an external directory",
"permission": [],
"api": [
{
"class": "Landroid/os/Environment;",
"method": "getExternalStorageDirectory",
"descriptor": "()Ljava/io/File;"
},
{
"class": "Ljava/io/File;",
"method": "<init>",
"descriptor": "(Ljava/io/File;Ljava/lang/String;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-22.py
CWE-22 is detected in method, Loversecured/ovaa/providers/TheftOverwriteProvider; openFile (Landroid/net/Uri; Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;
Detect CWE-23 in Android Application
This scenario aims to demonstrate the detection of the Relative Path Traversal vulnerability.
CWE-23: Relative Path Traversal
We analyze the definition of CWE-23 and identify its characteristics.
See CWE-23 for more details.
Code of CWE-23 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-23.
Quark Script: CWE-23.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
To begin with, we will create a detection rule named accessFileInExternalDir.json
to identify behavior that accesses a file in an external directory.
Next, we will use methodInstance.getArguments()
to retrieve the file path argument and check whether it belongs to the APK or not. If it does not belong to the APK, the argument is likely from external input.
Finally, we will use the Quark API quarkResultInstance.findMethodInCaller(callerMethod, targetMethod)
to search for any APIs in the caller method that match the string. If no matching API is found, the APK does not neutralize special elements within the argument, which may result in the CWE-23 vulnerability. If a matching API is found, we will verify whether it neutralizes the Relative Path string or not. If it does not neutralize it, the APK may still be vulnerable to CWE-23.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "accessFileInExternalDir.json"
STRING_MATCHING_API = [
["Ljava/lang/String;", "contains", "(Ljava/lang/CharSequence)Z"],
["Ljava/lang/String;", "indexOf", "(I)I"],
["Ljava/lang/String;", "indexOf", "(Ljava/lang/String;)I"],
["Ljava/lang/String;", "matches", "(Ljava/lang/String;)Z"],
[
"Ljava/lang/String;",
"replaceAll",
"(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String;",
],
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for accessExternalDir in quarkResult.behaviorOccurList:
filePath = accessExternalDir.secondAPI.getArguments()[2]
if quarkResult.isHardcoded(filePath):
continue
caller = accessExternalDir.methodCaller
strMatchingAPIs = [
api
for api in STRING_MATCHING_API
if quarkResult.findMethodInCaller(caller, api)
]
if not strMatchingAPIs:
print(f"CWE-23 is detected in method, {caller.fullName}")
elif strMatchingAPIs.find("..") == -1:
print(f"CWE-23 is detected in method, {caller.fullName}")
Quark Rule: accessFileInExternalDir.json
{
"crime": "Access a file in an external directory",
"permission": [],
"api": [
{
"class": "Landroid/os/Environment;",
"method": "getExternalStorageDirectory",
"descriptor": "()Ljava/io/File;"
},
{
"class": "Ljava/io/File;",
"method": "<init>",
"descriptor": "(Ljava/io/File;Ljava/lang/String;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-23.py
CWE-23 is detected in method, Loversecured/ovaa/providers/TheftOverwriteProvider; openFile (Landroid/net/Uri; Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;
Detect CWE-338 in Android Application
This scenario seeks to find Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG).
CWE-338: Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)
We analyze the definition of CWE-338 and identify its characteristics.
See CWE-338 for more details.
Code of CWE-338 in pivaa.apk
We use the pivaa.apk sample to explain the vulnerability code of CWE-338.
Quark Script CWE-338.py
First, we design a detection rule useMethodOfPRNG.json
to spot on behavior that uses Pseudo Random Number Generator (PRNG). Then, we use API methodInstance.getXrefFrom()
to get the caller method of PRNG. Finally, we use some keywords such as “token”, “password”, and “encrypt” to check if the PRNG is for credential usage.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "pivaa.apk"
RULE_PATH = "useMethodOfPRNG.json"
CREDENTIAL_KEYWORDS = [
"token", "password", "account", "encrypt",
"authentication", "authorization", "id", "key"
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for usePRNGMethod in quarkResult.behaviorOccurList:
for prngCaller in usePRNGMethod.methodCaller.getXrefFrom():
if any(keyword in prngCaller.fullName
for keyword in CREDENTIAL_KEYWORDS):
print("CWE-338 is detected in %s" % prngCaller.fullName)
Quark Rule: useMethodOfPRNG.json
{
"crime": "Use method of PRNG",
"permission": [],
"api": [
{
"class": "Ljava/util/Random;",
"method": "<init>",
"descriptor": "()V"
},
{
"class": "Ljava/util/Random;",
"method": "nextInt",
"descriptor": "(I)I"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-338.py
CWE-338 is detected in Lcom/htbridge/pivaa/EncryptionActivity$2; onClick (Landroid/view/View;)V
Detect CWE-88 in Android Application
This scenario seeks to find Argument Injection in the APK file.
CWE-88 Improper Neutralization of Argument Delimiters in a Command
We analyze the definition of CWE-88 and identify its characteristics.
See CWE-88 for more details.
Code of CWE-88 in vuldroid.apk
We use the vuldroid.apk sample to explain the vulnerability code of CWE-88.
Quark Script: CWE-88.py
Let‘s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule ExternalStringsCommands.json
to spot on behavior using external strings as commands.
Next, we use Quark API behaviorInstance.getMethodsInArgs()
to get the methods that passed the external command.
Then we check if the method neutralizes any special elements in the argument.
If the neutralization is not complete, then it may cause CWE-88 vulnerability.
from quark.script import runQuarkAnalysis, Rule, findMethodInAPK
SAMPLE_PATH = "Vuldroid.apk"
RULE_PATH = "ExternalStringCommand.json"
STRING_MATCHING_API = set([
("Ljava/lang/String;", "contains", "(Ljava/lang/CharSequence)Z"),
("Ljava/lang/String;", "indexOf", "(I)I"),
("Ljava/lang/String;", "indexOf", "(Ljava/lang/String;)I"),
("Ljava/lang/String;", "matches", "(Ljava/lang/String;)Z"),
("Ljava/lang/String;", "replaceAll", "(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String;")
])
delimeter = "-"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for ExternalStringCommand in quarkResult.behaviorOccurList:
methodCalled = set()
caller = ExternalStringCommand.methodCaller
for method in ExternalStringCommand.getMethodsInArgs():
methodCalled.add(method.fullName)
if methodCalled.intersection(STRING_MATCHING_API) and not ExternalStringCommand.hasString(delimeter):
continue
else:
print(f"CWE-88 is detected in method, {caller.fullName}")
Quark Rule: ExternalStringCommand.json
{
"crime": "Using external strings as commands",
"permission": [],
"api": [
{
"class": "Landroid/content/Intent;",
"method": "getStringExtra",
"descriptor": "(Ljava/lang/String;)Ljava/lang/String"
},
{
"class": "Ljava/lang/Runtime;",
"method": "exec",
"descriptor": "(Ljava/lang/String;)Ljava/lang/Process"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python3 CWE-88.py
CWE-88 is detected in method, Lcom/vuldroid/application/RootDetection; onCreate (Landroid/os/Bundle;)V
Detect CWE-925 in Android Application
This scenario seeks to find Improper Verification of Intent by Broadcast Receiver in the APK file.
CWE-925 Improper Verification of Intent by Broadcast Receiver
We analyze the definition of CWE-925 and identify its characteristics.
See CWE-925 for more details.
Code of CWE-925 in InsecureBankv2.apk
We use the InsecureBankv2.apk sample to explain the vulnerability code of CWE-925.
Quark Script CWE-925.py
First, we use API getReceivers(samplePath)
and receiverInstance.isExported()
to find all the exported receivers defined in the APK.
Second, we use API checkMethodCalls(samplePath, targetMethod, checkMethods)
to check if the onReceive
method of every exported receiver obtains intent action.
If No, it could imply that the APK does not verify intent properly, potentially leading to a CWE-925 vulnerability.
from quark.script import checkMethodCalls, getReceivers
sample_path = "InsecureBankv2.apk"
TARGET_METHOD = [
'',
'onReceive',
'(Landroid/content/Context; Landroid/content/Intent;)V'
]
CHECK_METHODS = [
['Landroid/content/Intent;', 'getAction', '()Ljava/lang/String;']
]
receivers = getReceivers(sample_path)
for receiver in receivers:
if receiver.isExported():
className = "L"+str(receiver).replace('.', '/')+';'
TARGET_METHOD[0] = className
if not checkMethodCalls(sample_path, TARGET_METHOD, CHECK_METHODS):
print(f"CWE-925 is detected in method, {className}")
Quark Script Result
$ python CWE-925.py
CWE-925 is detected in method, Lcom/android/insecurebankv2/MyBroadCastReceiver;
Detect CWE-73 in Android Application
This scenario seeks to find External Control of File Name or Path in the APK file.
CWE-73 External Control of File Name or Path
We analyze the definition of CWE-73 and identify its characteristics.
See CWE-73 for more details.
Code of CWE-73 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-73.
Quark Script: CWE-73.py
Let’s use the above APIs to show how Quark script find this vulnerability.
First, we design a detection rule accessFileInExternalDir.json
to spot behavior accessing a file in an external directory.
Second, we use API methodInstance.getArguments()
to get the argument for the file path and use quarkResultInstance.isHardcoded(argument)
to check if the argument is hardcoded into the APK. If No, the argument is from external input.
Finally, we use Quark API quarkResultInstance.findMethodInCaller(callerMethod, targetMethod)
to check if any APIs in the caller method for opening files. If YES, the APK performs file operations using external input as a path, which may cause CWE-73 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "accessFileInExternalDir.json"
OPEN_FILE_API = [
"Landroid/os/ParcelFileDescriptor;", # Class name
"open", # Method name
"(Ljava/io/File; I)Landroid/os/ParcelFileDescriptor;" # Descriptor
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for accessExternalDir in quarkResult.behaviorOccurList:
filePath = accessExternalDir.secondAPI.getArguments()[2]
if quarkResult.isHardcoded(filePath):
continue
caller = accessExternalDir.methodCaller
result = quarkResult.findMethodInCaller(caller, OPEN_FILE_API)
if result:
print("CWE-73 is detected in method, ", caller.fullName)
Quark Rule: accessFileInExternalDir.json
{
"crime": "Access a file in an external directory",
"permission": [],
"api": [
{
"class": "Landroid/os/Environment;",
"method": "getExternalStorageDirectory",
"descriptor": "()Ljava/io/File;"
},
{
"class": "Ljava/io/File;",
"method": "<init>",
"descriptor": "(Ljava/io/File;Ljava/lang/String;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-73.py
CWE-73 is detected in method, Loversecured/ovaa/providers/TheftOverwriteProvider; openFile (Landroid/net/Uri; Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;
Detect CWE-78 in Android Application
This scenario seeks to find Improper Neutralization of Special Elements used in an OS Command in the APK file.
CWE-78 Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’)
We analyze the definition of CWE-78 and identify its characteristics.
See CWE-78 for more details.
Code of CWE-78 in Vuldroid.apk
We use the Vuldroid.apk sample to explain the vulnerability code of CWE-78.
Quark Script: CWE-78.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
First, we design a detection rule ExternalStringsCommands.json
to spot on behavior using external strings as commands.
Next, we use Quark API behaviorInstance.getMethodsInArgs()
to get the methods that passed the external command.
Then we check if the method neutralizes any special elements found in the argument.
If the neutralization is not complete, then it may cause CWE-78 vulnerability.
from quark.script import runQuarkAnalysis, Rule, findMethodInAPK
SAMPLE_PATH = "Vuldroid.apk"
RULE_PATH = "ExternalStringCommand.json"
STRING_MATCHING_API = set([
("Ljava/lang/String;", "contains", "(Ljava/lang/CharSequence)Z"),
("Ljava/lang/String;", "indexOf", "(I)I"),
("Ljava/lang/String;", "indexOf", "(Ljava/lang/String;)I"),
("Ljava/lang/String;", "matches", "(Ljava/lang/String;)Z"),
("Ljava/lang/String;", "replaceAll", "(Ljava/lang/String; Ljava/lang/String;)Ljava/lang/String;")
])
specialElementsPattern = r"[ ;|,>`]+"
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for ExternalStringCommand in quarkResult.behaviorOccurList:
methodCalled = set()
caller = ExternalStringCommand.methodCaller
for method in ExternalStringCommand.getMethodsInArgs():
methodCalled.add(method.fullName)
if methodCalled.intersection(STRING_MATCHING_API) and not ExternalStringCommand.hasString(specialElementsPattern):
continue
else:
print(f"CWE-78 is detected in method, {caller.fullName}")
Quark Rule: ExternalStringCommand.json
{
"crime": "Using external strings as commands",
"permission": [],
"api": [
{
"class": "Landroid/content/Intent;",
"method": "getStringExtra",
"descriptor": "(Ljava/lang/String;)Ljava/lang/String"
},
{
"class": "Ljava/lang/Runtime;",
"method": "exec",
"descriptor": "(Ljava/lang/String;)Ljava/lang/Process"
}
],
"score": 1,
"label": []
}
Quark Script Result
Vuldroid.apk
$ python3 CWE-78.py
CWE-78 is detected in method, Lcom/vuldroid/application/RootDetection; onCreate (Landroid/os/Bundle;)V
Detect CWE-117 in Android Application
This scenario seeks to find Improper Output Neutralization for Logs.
CWE-117: Improper Output Neutralization for Logs
We analyze the definition of CWE-117 and identify its characteristics.
See CWE-117 for more details.
Code of CWE-117 in allsafe.apk
We use the allsafe.apk sample to explain the vulnerability code of CWE-117.
Quark Script CWE-117.py
First, we design a detection rule writeContentToLog.json
to spot on behavior using the method that writes contents to the log file.
Then, we use methodInstance.getArguments()
to get all parameter values of this method. And we check if these parameters contain keywords of APIs for neutralization, such as escape
, replace
, format
, and setFilter
.
If the answer is YES, that may result in secret context leakage into the log file, or the attacker may perform log forging attacks.
from quark.script import Rule, runQuarkAnalysis
SAMPLE_PATH = "allsafe.apk"
RULE_PATH = "writeContentToLog.json"
KEYWORDS_FOR_NEUTRALIZATION = ["escape", "replace", "format", "setFilter"]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for logOutputBehavior in quarkResult.behaviorOccurList:
secondAPIParam = logOutputBehavior.secondAPI.getArguments()
isKeywordFound = False
for keyword in KEYWORDS_FOR_NEUTRALIZATION:
if keyword in secondAPIParam:
isKeywordFound = True
break
if not isKeywordFound:
caller = logOutputBehavior.methodCaller.fullName
print(f"CWE-117 is detected in method, {caller}")
Quark Rule: writeContentToLog.json
{
"crime": "Write contents to the log.",
"permission": [],
"api": [
{
"descriptor": "()Landroid/text/Editable;",
"class": "Lcom/google/android/material/textfield/TextInputEditText;",
"method": "getText"
},
{
"descriptor": "(Ljava/lang/String;Ljava/lang/String;)I",
"class": "Landroid/util/Log;",
"method": "d"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-117.py
CWE-117 is detected in method, Linfosecadventures/allsafe/challenges/InsecureLogging; lambda$onCreateView$0 (Lcom/google/android/material/textfield/TextInputEditText; Landroid/widget/TextView; I Landroid/view/KeyEvent;)Z
Detect CWE-940 in Android Application
This scenario seeks to find the Improper Verification of Source of a Communication Channel in the APK file.
CWE-940: Improper Verification of Source of a Communication Channel
We analyze the definition of CWE-940 and identify its characteristics.
See CWE-940 for more details.
Code of CWE-940 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-940.
Quark Script: CWE-940.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
To begin with, we create a detection rule named LoadUrlFromIntent.json
to identify behavior that loads URLs from intent data to the WebView
.
Next, we retrieve the methods that pass the URL. Then, we check if these methods are only for getting the URL, such as findViewById
, getStringExtra
, or getIntent
.
If YES, it could imply that the APK uses communication channels without proper verification, which may cause CWE-940 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "ovaa.apk"
RULE_PATH = "LoadUrlFromIntent.json"
URL_GETTING_METHODS = [
"findViewById",
"getStringExtra",
"getIntent",
]
ruleInstance = Rule(RULE_PATH)
quarkResult = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
for behaviorInstance in quarkResult.behaviorOccurList:
methodsInArgs = behaviorInstance.getMethodsInArgs()
verifiedMethodCandidates = []
for method in methodsInArgs:
if method.methodName not in URL_GETTING_METHODS:
verifiedMethodCandidates.append(method)
if verifiedMethodCandidates == []:
caller = behaviorInstance.methodCaller.fullName
print(f"CWE-940 is detected in method, {caller}")
Quark Rule: LoadUrlFromIntent.json
{
"crime": "Load Url from Intent",
"permission": [],
"api": [
{
"class": "Landroid/content/Intent;",
"method": "getStringExtra",
"descriptor": "(Ljava/lang/String;)Ljava/lang/String"
},
{
"class": "Landroid/webkit/WebView;",
"method": "loadUrl",
"descriptor": "(Ljava/lang/String;)V"
}
],
"score": 1,
"label": []
}
Quark Script Result
$ python CWE-940.py
CWE-940 is detected in method, Loversecured/ovaa/activities/WebViewActivity; onCreate (Landroid/os/Bundle;)V
Detect CWE-502 in Android Application
This scenario seeks to find Deserialization of Untrusted Data in the APK file.
CWE-502: Deserialization of Untrusted Data
We analyze the definition of CWE-502 and identify its characteristics.
See CWE-502 for more details.
Code of CWE-502 in pivaa.apk
We use the pivaa.apk sample to explain the vulnerability code of CWE-502.
Quark Script CWE-502.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
To begin with, we created a detection rule named deserializeData.json
to identify behaviors that deserialize data.
Next, we retrieve the methods that interact with the deserialization API. Following this, we check if there are any of the APIs in verificationApis
are found.
If NO, it could imply that the APK deserializes the untrusted data, potentially leading to a CWE-502 vulnerability.
from quark.script import runQuarkAnalysis, Rule
SAMPLE_PATH = "pivaa.apk"
RULE_PATH = "deserializeData.json"
ruleInstance = Rule(RULE_PATH)
result = runQuarkAnalysis(SAMPLE_PATH, ruleInstance)
verificationApis = [
["Ljava/io/File;", "exists", "()Z"],
["Landroid/content/Context;", "getFilesDir", "()Ljava/io/File;"],
["Landroid/content/Context;", "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"],
["Landroid/os/Environment;", "getExternalStorageDirectory", "()Ljava/io/File;"],
]
for dataDeserialization in result.behaviorOccurList:
apis = dataDeserialization.getMethodsInArgs()
caller = dataDeserialization.methodCaller
if not any(api in apis for api in verificationApis):
print(f"CWE-502 is detected in method, {caller.fullName}")
Quark Rule: deserializeData.json
{
"crime": "Deserialize Data",
"permission": [],
"api": [
{
"class": "Ljava/io/ObjectInputStream;",
"method": "<init>",
"descriptor": "(Ljava/io/InputStream;)V"
},
{
"class": "Ljava/io/ObjectInputStream;",
"method": "readObject",
"descriptor": "()Ljava/lang/Object;"
}
],
"score": 1,
"label": []
}
Quark Script Result
pivaa.apk
$ python CWE-502.py
CWE-502 is detected in method, Lcom/htbridge/pivaa/handlers/ObjectSerialization; loadObject ()V
Detect CWE-601 in Android Application
This scenario seeks to find URL Redirection to Untrusted Site in the APK file.
CWE-601: URL Redirection to Untrusted Site (‘Open Redirect’)
We analyze the definition of CWE-601 and identify its characteristics.
See CWE-601 for more details.
Code of CWE-601 in ovaa.apk
We use the ovaa.apk sample to explain the vulnerability code of CWE-601.
Quark Script: CWE-601.py
Let’s use the above APIs to show how the Quark script finds this vulnerability.
To detect the vulnerability, we use the API findMethodInAPK(samplePath, targetMethod)
to find all the caller methods of startActivity
. Next, we examine the arguments of each method to discover the methods receiving external input. If a method receives external input but lacks proper input validation, the CWE-601 vulnerability is identified.
from quark.script import findMethodInAPK
SAMPLE_PATH = 'ovaa.apk'
# This is the input for findMethodInAPK, formatted as class name, method name, descriptor
TARGET_METHOD = ["", "startActivity", "(Landroid/content/Intent;)V"]
"""
Due to varying descriptors and classes in smali code from different APIs,
our search relies solely on the consistent method names.
"""
EXTERNAL_INPUT_METHODS = ["getIntent", "getQueryParameter"]
INPUT_FILTER_METHODS = [
"parse",
"isValidUrl",
"Pattern",
"Matcher",
"encode",
"decode",
"escapeHtml",
"HttpURLConnection",
]
redirectMethods = findMethodInAPK(SAMPLE_PATH, TARGET_METHOD)
for redirectMethod in redirectMethods:
arguments = redirectMethod.getArguments()
for argument in arguments:
if any(
externalInput in argument
for externalInput in EXTERNAL_INPUT_METHODS
):
if not any(
filterMethod in argument
for filterMethod in INPUT_FILTER_METHODS
):
print(f"CWE-601 is detected in {redirectMethod.fullName}")
Quark Script Result
$ python CWE-601.py
CWE-601 is detected in Loversecured/ovaa/activities/DeeplinkActivity; processDeeplink (Landroid/net/Uri;)V
CWE-601 is detected in Loversecured/ovaa/activities/LoginActivity; onLoginFinished ()V