RASP Feature Overview
RASP (runtime application self-protection) features protect the app against several attack vectors.
Currently, Malwarelytics for Apple covers the following problems:
- Jailbreak Detection
- Debugger Detection
- Reverse Engineering Tools Detection
- HTTP Proxy Detection
- Repackaging Detection
- Screen Capture Detection
- VPN Detection
- Active Call Detection
- App Presence Detection
- User Screenshot Detection
- System Passcode Detection
- System Biometry Detection
Configuring Detections
RASP detections are configured via AppProtectionRaspConfig
and AppProtectionEventConfig
classes that are a part of the AppProtectionConfig
.
To configure RASP detections, use:
// Prepare the RASP feature configuration
let raspConfig = AppProtectionRaspConfig(
jailbreak: .exit("https://myurl.com/jalibreak-explained"), // exit on jailbroken phone
debugger: .block, // block debugger
reverseEngineeringTools: .notify, // let me know when the user installed reverse engineering tools
httpProxy: .notify, // notify me via delegate when HTTP proxy is enabled
repackage: .exit([AppProtectionTrustedCert(withBase64EncodedString: "BASE_64_ENCODED_CERT")!], "https://myurl.com/repackage-explained"), // follow documentation how to obtain certificate string
screenCapture: .hide(), // will hide the app contents when the screen is captured (for example shared via airplay),
vpnDetection: .notify, // notify me when the VPN is connected or disconnected
callDetection: .notify, // notify me when about an active call
appPresence: .notify([.KnownApps.anyDesk]) // notify me when AnyDesk application is installed. Note that you also have to specify the deeplink in your Info.plist (more in the feature documentation)
)
// Prepare the configuration for events
let eventConfig = AppProtectionEventConfig(
enableEventCollection: true, // enable event collection in general
enableAppLifecycleCollection: true, // track lifecycle events in the Malwarelytics console on the server
enableScreenshotTakenCollection: true // track screenshot events in the Malwarelytics console on the server
)
// Prepare a configuration for service
let config = AppProtectionConfig(
username: "$USERNAME", // username for the Malwarelytics service
password: "$PASSWORD", // password for the Malwarelytics service
signaturePublicKey: "$PUBKEY", // public key for the Malwarelytics service
clientIdentification: nil, // user identification (unique within your systems)
raspConfig: raspConfig,
eventsConfig: eventConfig,
customerGroupingConfig: nil // Configuration of customer grouping and naming in the web application.
)
How to configure appPresence
App presence allows you to verify whether a specific app is installed on a device. To successfully detect such an application, you need to configure the AppProtectionRaspConfig
with the appPresence
parameter.
In addition to that, you also need to add a query URL scheme to your application Info.plist
.
For example, if you want to add detection for AnyDesk application, you need to configure the appPresense
parameter with appPresence: .notify([.KnownApps.anyDesk])
and then add anydesk
scheme into your Info.plist
Queried URL Schemes
item.
You can add anydesk
scheme to the query with these few steps:
- Open your Xcode project.
- In the Project Navigator, find your app’s Info.plist file and open it.
- Click the “+” button in the top-right corner of the Info.plist editor.
- In the new row, set the key to “Queried URL Schemes”
- Click the arrow next to “Queried URL Schemes” to expand it.
- Click the “+” button next to “Queried URL Schemes” and add
anydesk
scheme. - Save your changes.
By following these steps, you’ll configure app presence for your application to detect the presence of specific apps, like AnyDesk.
Obtaining Detection Results
When Malwarelytics for Apple is initialized with certain configurations,
the RASP features can be accessed through AppProtectionRaspDelegate
or by proactively checking for the status of a certain feature.
Observing RASP Detections
An observer can be registered in RaspManager
to notify the app about any RASP detection change.
// Set the delegate to the existing `AppProtectionService` instance
// to obtain RASP callbacks
appProtection.rasp.addDelegate(self)
Delegate then receives the following callbacks:
func debuggerDetected() {
// react to a debugger
}
func jailbreakDetected() {
// react to jailbreak
}
func repackageDetected() {
// react to repackage
}
func httpProxyEnabled() {
// react to HTTP proxy enabled
}
func userScreenshotDetected() {
// react to user screenshot
}
func reverseEngineeringToolsDetected() {
// react to reverse engineering tools
}
func systemPasscodeConfigurationChanged(enabled: Bool) {
// react to system passcode change
}
func systemBiometryConfigurationChanged(enabled: Bool) {
// react to biometry configuration changed
}
func screenCapturedChanged(isCaptured: Bool) {
// react to screen capturing (casting to different device)
}
func vpnChanged(active: Bool) {
// react to VPN state changes
}
func onCallChanged(isOnCall: Bool) {
// react to call change
}
func installedAppsChanged(installedApps: [DetectableApp]) {
// installed apps list has changed
}
Triggering RASP Checks Manually
All the RASP checks can be triggered manually in RaspManager
. There are mostly two methods for the checks. One for a simple boolean answer
and one for more detailed information.
// root detection
let isJailbroken = appProtection.rasp.isJailbroken
// debugger
let isDebuggerConnected = appProtection.rasp.isDebuggerConnected
// repackaging
let isRepackaged = appProtection.rasp.isRepackaged
// screen sharing
let isScreenCaptured = appProtection.rasp.isScreenCaptured
// system passcode
let isSystemPasscodeEnabled = appProtection.rasp.isSystemPasscodeEnabled
// system biometry
let isSystemBiometryEnabled = appProtection.rasp.isSystemBiometryEnabled
// simulator build
let isEmulator = appProtection.rasp.isEmulator
// reverse engineering
let isReverseEngineeringToolsPresent = appProtection.rasp.isReverseEngineeringToolsPresent
// http proxy present
let isHttpProxyEnabled = appProtection.rasp.isHttpProxyEnabled
// VPN active
let isVpnActive = appProtection.rasp.isVpnActive
// on call
let isOnCall = appProtection.rasp.isOnCall
// detected apps
let detectedApps = appProtection.rasp.installedApps