RASP Feature Overview

RASP (runtime application self-protection) features protect the app against several attack vectors at runtime. Here is a list of available features:

Configuration

RASP features can be initially configured by building a RaspConfig instance and passing it to the raspConfig method in the general AppProtectionConfig:

val config = AppProtectionConfig.Builder(appContext)
        .raspConfig(
            RaspConfig.Builder()
                // RASP feature configuration
                .build()
        )
        // other Malwarelytics configuration
        .build()

When no RaspConfig instance is provided, all RASP features are turned off. When a RaspConfig instance is provided, all RASP configurations are enabled by default. However, the repackaging detection feature requires a signatureHash to be set.

A minimum RASP configuration with all features enabled requires only signatureHash to be set:

val config = AppProtectionConfig.Builder(appContext)
        .raspConfig(
            RaspConfig.Builder()
            .signatureHash(SIGNATURE_HASH)
            .build()
        )
        // …
        .build()

Available Configuration Items

val raspConfig = RaspConfig.Builder()
    .checkEmulator(Boolean)
    .exitOnEmulator(Boolean)
    .exitOnEmulatorUrl(String)
    .checkRoot(Boolean)
    .exitOnRoot(Boolean)
    .exitOnRootUrl(String)
    .exitOnRootMinConfidence(Float) // value from 0.0 to 1.0
    .checkDebugger(Boolean)
    .exitOnDebugger(Boolean)
    .exitOnDebuggerUrl(String)
    .checkRepackaging(Boolean)
    .exitOnRepackaging(Boolean)
    .exitOnRepackagingUrl(String)
    .signatureHash(String)          // SHA-1 of signing certificate(s)
    .checkScreenSharing(Boolean)
    .exitOnScreenSharing(Boolean)
    .exitOnScreenSharingUrl(String)
    .blockScreenshots(Boolean)
    .blockScreenReaders(Boolean)
    .allowedScreenReaders(Collection<RaspConfig.ApkAllowlistItem>)
    .customProcessName(String)      // when set, turns off useStealthyProcessName
    .useStealthyProcessName(Boolean)
    .blockTapjacking(Boolean)
    .ignoreTapjackingSystemApps(Boolean)
    .blockTapjackingSensitivity(ThreatIndex)
    .allowedTapjackingApps(Collection<RaspConfig.ApkAllowlistItem>)
    .checkHttpProxy(Boolean)
    .exitOnHttpProxy(Boolean)
    .exitOnHttpProxyUrl(String)
    .checkVpn(Boolean)
    .exitOnVpn(Boolean)
    .exitOnVpnUrl(String)
    .exitOnAdbEnabled(Boolean)
    .exitOnAdbEnabledUrl(String)
    .checkActiveCall(Boolean)
    .build()
Method Description
checkEmulator(Boolean) indicates whether emulators should be detected automatically. Defaults to true.
exitOnEmulator(Boolean) indicates whether the app should be terminated when an emulator is automatically detected. Defaults to false.
exitOnEmulatorUrl(String) defines a URL to be opened when the app is terminated because of emulator detection. Defaults to null.
checkRoot(Boolean) indicates whether rooted device should be detected automatically. Defaults to true.
exitOnRoot(Boolean) indicates whether the app should be terminated when a rooted device is automatically detected. Defaults to false.
exitOnRootUrl(String) defines a URL to be opened when the app is terminated because of root detection. Defaults to null.
exitOnRootMinConfidence(Float) gives the minimum confidence value of a heuristic root detection that triggers app termination. Works only if exitOnRoot is true. Possible values are between 0.0 (inclusive) and 1.0 (inclusive). The default value is 1.0.
checkDebugger(Boolean) indicates whether debuggers should be detected automatically. Defaults to true.
exitOnDebugger(Boolean) indicates whether the app should be terminated when a debugger is automatically detected. Defaults to false.
exitOnDebuggerUrl(String) defines a URL to be opened when the app is terminated because of debugger detection. Defaults to null.
signatureHash(String) SHA-1 of signing certificate(s). One or more values can be set. A lowercase hex value without any byte separators is expected. No default value is set.
checkRepackaging(Boolean) indicates whether repackaging should be detected automatically. Defaults to true but works only if signatureHash is set.
exitOnRepackaging(Boolean) indicates whether the app should be terminated when repackaging is automatically detected. Defaults to true but works only if signatureHash is set.
exitOnRepackagingUrl(String) defines a URL to be opened when the app is terminated because of repackaging detection. Defaults to null.
checkScreenSharing(Boolean) indicates whether screen sharing should be detected automatically. Defaults to true.
exitOnScreenSharing(Boolean) indicates whether the app should be terminated when screen sharing is automatically detected. Defaults to false.
exitOnScreenSharingUrl(String) defines a URL to be opened when the app is terminated because of screen sharing detection. Defaults to null.
blockScreenshots(Boolean) indicates whether taking screenshots and screen recordings should be blocked. Defaults to true.
allowedScreenReaders(
Collection<RaspConfig.ApkAllowlistItem>)
defines a collection of allowed screen readers. It is empty by default.
blockScreenReaders(Boolean) indicates whether screen readers should be blocked. Defaults to true. However, screen readers are only blocked if Malwarelytics detects an enabled screen reader that is not whitelisted in allowedScreenReaders.
customProcessName(String) sets a custom name which will be used for the app process. When the name is set, the useStealthyProcessName option is automatically turned off.
useStealthyProcessName(Boolean) indicates whether a stealthy name should be used for the app process. Defaults to true.
blockTapjacking(Boolean) indicates whether tapjacking should be blocked. Defaults to true. However, tapjacking is not blocked unless a “problematic” app is installed on the device. An app is deemed “problematic” when it meets sensitivity criteria defined by blockTapjackingSensitivity.
ignoreTapjackingSystemApps(Boolean) indicates whether tapjacking protection should ignore system apps in the checks. Defaults to false.
blockTapjackingSensitivity(ThreatIndex) defines tapjacking protection sensitivity. Defaults to ThreatIndex.HIGHLY_DANGEROUS.
allowedTapjackingApps(Collection<RaspConfig.ApkAllowlistItem>) defines a collection of allowed app capable of tapjacking. It is empty by default.
checkHttpProxy(Boolean) indicates whether HTTP proxy use should be detected automatically. Defaults to true.
exitOnHttpProxy(Boolean) indicates whether the app should be terminated when the use of an HTTP proxy is detected. Defaults to false.
exitOnHttpProxyUrl(String) defines a URL to be opened when the app is terminated because of detection of HTTP proxy. Defaults to null.
checkVpn(Boolean) indicates whether VPN use should be detected automatically. Defaults to true.
exitOnVpn(Boolean) indicates whether the app should be terminated when the use of a VPN is detected. Defaults to false.
exitOnVpnUrl(String) defines a URL to be opened when the app is terminated because of detection of a VPN. Defaults to null.
exitOnAdbEnabled(Boolean) indicates whether the app should be terminated when ADB (Android Debug Bridge) is enabled on the device. Defaults to false.
exitOnAdbEnabledUrl(String) defines a URL to be opened when the app is terminated because of detection of enabled ADB. Defaults to null.
checkActiveCall(Boolean) indicates whether active call should be detected automatically. Defaults to true.

The behavior of all the configuration items can be summarized with these rules:

  • The check- methods turn certain features on or off.
  • The exitOn- methods cause the app to be terminated when the corresponding check- method is on and the detection is triggered.
  • The related exitOn-Url methods define URLs to be opened in the system web browser when the app is terminated as a result of the corresponding exitOn- configuration. It is used only when both related check- and exitOn- configurations are set to on.
  • The block- methods turn blocking of certain system features on or off in order to shield the app against the related vulnerability.

Detailed information about these configuration items can be found on the documentation pages of individual features.

Obtaining Detection Results

After Malwarelytics for Android has been initialized with certain configurations, RASP features can be accessed with RaspManager. You can obtain an instance from AppProtection by calling:

val raspManager = appProtection.getRaspManager()

When RaspConfig is not provided, all RASP features are turned off and the RaspManager instance cannot be used to access RASP features.

You can use the RaspManager instance to register and unregister a RASP observer or to trigger RASP checks manually.

Observing RASP Detections

An observer can be registered in RaspManager to notify the app about any RASP detections. This is an example of registering an observer in which all available detections are handled:

val raspObserver = object : RaspObserver {
    override fun onEmulatorDetected(emulatorDetection: EmulatorDetection) {
        // handle emulator detection
    }

    override fun onRootDetected(rootDetection: RootDetection) {
        // handle root detection
    }

    override fun onDebuggerDetected(debuggerDetected: Boolean) {
        // handle debugger detection
    }

    override fun onRepackagingDetected(repackagingResult: RepackagingResult) {
        // handle repackaging detection
    }

    override fun onScreenSharingDetected(screenSharingDetected: Boolean) {
        // handle screen sharing detection
    }

    override fun onTapjackingDetected(tapjackingDetection: TapjackingDetection) {
        // handle tapjacking detection
    }

    override fun onHttpProxyDetected(httpProxyDetected: Boolean) {
        // handle http proxy detection
    }

    override fun onVpnDetected(vpnEnabled: Boolean) {
        // handle VPN detection
    }

    override fun onAdbStatusDetected(adbStatus: Boolean) {
        // handle ADB status detection
    }
    
    override fun onActiveCallDetected(activeCallDetection: ActiveCallDetection) {
        // handle active call detection
    }
}
raspManager.registerRaspObserver(raspObserver)

The observer can be unregistered when it is no longer necessary:

raspManager.unregisterRaspObserver(raspObserver)

The observer callbacks are always called on a background thread before the app exits. It’s recommended to perform only a quick lightweight processing in the callback as any heavy processing or threading is not guaranteed to be completed.

Any detections that are manually triggered via RaspManager (see section below) are not propagated into the observer.

Triggering RASP Checks Manually

All RASP checks can be triggered manually with RaspManager. There are two types of manual checks: the is- methods give a simple boolean answer whereas the get- methods provide more detailed information.

// root detection
val rootDetection = raspManager.getRootDetection()
val isRooted = raspManager.isDeviceRooted()

// emulator detection
val emulatorDetection = raspManager.getEmulatorDetection()
val isDeviceEmulator = raspManager.isDeviceEmulator()

// debugger
val debuggerDetection = raspManager.getDebuggerDetection()
val isDebuggerAttached = raspManager.isDebuggerAttached()

// repackaging
val repackagingResult = raspManager.isAppRepackaged()

// screen sharing
val screenSharingDetection = raspManager.getScreenSharingDetection()
val isScreenShared = raspManager.isScreenShared()

// screen lock usage
val isDeviceUsingScreenLock = raspManager.isDeviceUsingScreenLock()

// Play Protect status
val isPlayProtectEnabled = raspManager.isPlayProtectEnabled()

// tapjacking
val isBadTapjackingCapableAppPresent = raspManager.isBadTapjackingCapableAppPresent()
val tapjackingDetection = raspManager.getTapjackingDetection()

// http proxy detection
val isHttpProxyEnabled = raspManager.isHttpProxyEnabled()
val httpProxyDetection = raspManager.getHttpProxyDetection()

// VPN
val isVpnEnabled = raspManager.isVpnEnabled()

// ADB status
val isAdbEnabled = raspManager.isAdbEnabled()

// developer options status
val isDeveloperOptionsEnabled = raspManager.isDeveloperOptionsEnabled()

// biometry enrollment status
val biometryDetection = raspManager.getBiometryDetection()

// active call
val isCallActive = raspManager.isCallActive()
val activeCallDetection = raspManager.getActiveCallDetection()
Last updated on May 05, 2023 (15:08) View product
Search

0.24.x

Malwarelytics for Android