RASP Feature Overview

View product 2021.09 - Current Release

RASP (runtime application self-protection) features protect the app against several attack vectors.

Currently, Malwarelytics for Android covers the following problems:

The RASP features are configured as part of Malwarelytics for Android configurations during its initialization. Later, the RASP features can be accessed through RaspManager instance.

Configuring Detections

RASP detections are configured via RaspConfig that is a part of the AppProtectionConfig.

To configure RASP detections, use:

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

When no RaspConfig is provided, all RASP features are turned off.

When a RaspConfig is provided, all RASP configurations are enabled by default. Repackaging is checked only if signatureHashis set and by default the app exits if repackaging is detected.

A minimum RASP configuration enabling all the features requires only signatureHash to be set:

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

The configuration of RaspConfig offers two basic settings for the RASP detections.

  1. Turning certain detections on or off.
  2. Automatically exiting the app when a certain problem is detected.

Available Configuration Items

The RASP configuration contains the following detections:

val raspConfig = RaspConfig.Builder()
    .checkEmulator(Boolean)
    .exitOnEmulator(Boolean)
    .checkRoot(Boolean)
    .exitOnRoot(Boolean)
    .exitOnRootMinConfidence(Float) // value from 0.0 to 1.0
    .checkDebugger(Boolean)
    .exitOnDebugger(Boolean)
    .checkRepackaging(Boolean)
    .exitOnRepackaging(Boolean)
    .signatureHash(String)          // SHA-1 of signing certificate(s)
    .checkScreenSharing(Boolean)
    .exitOnScreenSharing(Boolean)
    .blockScreenshots(Boolean)
    .blockScreenReaders(Boolean)
    .allowedScreenReaders(Collection<RaspConfig.ApkAllowlist>)
    .customProcessName(String)      // when set, turns off useStealthyProcessName
    .useStealthyProcessName(Boolean)
    .build()

The check* methods turn certain features on or off. The exit* methods cause app exit when the corresponding detection is triggered. The block* methods blocks certain system features to shield the app from the related vulnerability.

Configuration Items Effects

Below are listed the effects and default values of all the RASP configuration items:

  • checkEmulator(Boolean) - Turn on/off automatic emulation detection. It is on by default.
  • exitOnEmulator(Boolean) - Whether to terminate the app when emulator is automatically detected. It is off by default.
  • checkRoot(Boolean) - Turns on/off automatic root detection. It is on by default.
  • exitOnRoot(Boolean) - Whether to terminate the app when rooted device is automatically detected. It is off by default.
  • exitOnRootMinConfidence(Float) - Minimum confidence value of heuristic root detections 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) - Turns on/off automatic detection of attached debuggers. It is on by default.
  • exitOnDebugger(Boolean) - Whether to terminate the app when an attached debugger is automatically detected. It is off by default.
  • checkRepackaging(Boolean) - Turns on/off automatic repackaging detection. It is on by default but works only if signatureHash is set.
  • exitOnRepackaging(Boolean) - Whether to terminate the app when repackaging is automatically detected. It is on by default but works only if signatureHash is set.
  • signatureHash(String) - SHA-1 of signing certificate(s). One or more values can be set. Expecting lowercase hex value without any byte separators. No default value is set.
  • checkScreenSharing(Boolean) - Turns on/off automatic screen sharing detection. It is on by default.
  • exitOnScreenSharing(Boolean) - Whether to terminate teh app when screen sharing is automatically detected. It is off by default.
  • blockScreenshots(Boolean) - Turns on/off blocking taking screenshots and screen recording. It is on by default.
  • blockScreenReaders(Boolean) - Turn on/off blocking screen readers. It is on by default. Screen readers are blocked only when an enabled screen reader is detected that is not allowed in allowedScreenReaders.
  • allowedScreenReaders(Collection<RaspConfig.ApkAllowlist>) - Defines collection of allowed screen readers. It is empty by default.
  • customProcessName(String) - Sets custom name to be used for the app process. When set, turns off useStealthyProcessName.
  • useStealthyProcessName(Boolean) - Whether to use a stealthy name for the app’s process. It is on by default. When true a name is selected randomly from a list of stealthy process names. It is turned off when customProcessName is set.

Obtaining Detection Results

When Malwarelytics for Android is initialized with certain configurations, the RASP features can be accessed through RaspManager. You can obtain the instance from AppProtection by calling:

val raspManager = appProtection.getRaspManager()

The RaspManager instance then offers to:

  • Register a RASP Observer
  • Trigger RASP Checks Manually

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

Observing RASP Detections

An observer can be registered in RaspManager to notify the app about any RASP detection.

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
    }
}
raspManager.registerRaspObserver(raspObserver)

The observer can be unregistered when no longer necessary:

raspManager.unregisterRaspObserver(raspObserver)

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

Any detections that are manually triggered via RaspManager are not propagated into the observer.

Triggering RASP Checks Manually

All the RASP checks can be triggered manually in RaspManager. There are usually two methods for the checks. One for simple boolean answer and one for a 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()
Last updated on Jul 21, 2021 (16:15) View product
Search

2021.09

Malwarelytics

Malwarelytics android