Skip to content

Commit

Permalink
Enabled parallelization & updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
cioccarellia committed Dec 23, 2022
1 parent d492651 commit 9aa9537
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 15 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions docs/pages/modules/rooting/implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,41 @@ You go ahead and request whichever attestation(s) you need. The will produce two
We go ahead and create a working single-attestation example (for system modifications aka targets). For two attestations refer to the sample code in the `:showcase` module of the github repository.


## Configuration
As we said, the kinds of checks you can run are divided in two different categories, `targets` and `status`.
The first is to check for eventual system modification, the former to check for eventual in-system status.

The following complete configuration runs every check that kevlar disposes.

In details:

- `flagPermissive()`, if enabled, will report `DetectableSystemStatus.SELINUX` also if selinux status is set to permissive status (which is a stricter criteria), while by default it will only trip if selinux is disabled;
- `allowExplicitRootCheck()`, if enabled, will use more aggressive checks to determine if any of the required targets is installed, including explicitly trying to acquire root access.


```kotlin
private val rooting = KevlarRooting {
targets {
root()
magisk()
busybox()
toybox()
xposed()
}

allowExplicitRootCheck()

status {
testKeys()
emulator()
selinux {
flagPermissive()
}
}
}
```


## In-Place
This is the most concise way to implement rooting.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/modules/rooting/rooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ To [implement](implementation.md) this, you initialize `KevlarRooting` and provi
}
}

allowRootCheck()
allowExplicitRootCheck()
}
```

Expand Down
7 changes: 4 additions & 3 deletions rooting/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ dependencies {
testImplementation "com.google.truth:truth:1.1.3"
testImplementation "org.robolectric:robolectric:4.9"

// libsu
implementation("com.github.topjohnwu.libsu:core:5.0.3") {
// exclude group: 'androidx.annotation', module: 'annotation'
// libsu, fixed at 5.0.2
//noinspection GradleDependency
implementation("com.github.topjohnwu.libsu:core:5.0.2") {
exclude group: 'androidx.annotation', module: 'annotation'
}
implementation "androidx.annotation:annotation:1.5.0"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ package com.kevlar.rooting.detection.status

import android.os.Build

/**
* Analyzes environment DEVICE, FINGERPRINT, HARDWARE, MODEL, MANUFACTURER and PRODUCT to
* search for some specific emulator characteristics
* */
internal fun detectEmulator(): Boolean =
(Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| Build.FINGERPRINT.startsWith("generic")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ internal enum class SelinuxGetenforceStatus {
DISABLED, PERMISSIVE, ENFORCING;
}

private const val SX_DISABLED = """disabled"""
private const val SX_PERMISSIVE = """permissive"""

/**
* This command may fail under different circumstances.
* We want to have no false positives. Thus, in case of unknown output
Expand All @@ -32,9 +35,9 @@ internal enum class SelinuxGetenforceStatus {
* we can infer some information.
* */
internal suspend fun detectSelinux(): SelinuxGetenforceStatus = withContext(Dispatchers.IO) {
when (Shell.cmd("getenforce").exec().out.joinToString().lowercase()) {
"disabled" -> SelinuxGetenforceStatus.DISABLED
"permissive" -> SelinuxGetenforceStatus.PERMISSIVE
when (Shell.cmd("getenforce").exec().out.joinToString().lowercase().trim()) {
SX_DISABLED -> SelinuxGetenforceStatus.DISABLED
SX_PERMISSIVE -> SelinuxGetenforceStatus.PERMISSIVE
else -> SelinuxGetenforceStatus.ENFORCING
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ package com.kevlar.rooting.detection.status

import android.os.Build

/**
* Simply detects whether test keys are present in the build tags.
* */
internal fun detectTestKeys(): Boolean {
val buildTags = Build.TAGS
return buildTags != null && buildTags.contains("test-keys")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ import com.kevlar.rooting.dsl.settings.target.SystemTargetsBuilder
* Current available settings include:
* - System targets (allows to target the detection of specific system modifications)
* - System status (allows to detect system conditions)
* - Allow explicit root check (whether kevlar will try to acquire explicit root access to detect
* certain targets, instead of using just passive reconnaissance)
* */
public data class RootingSettings(
val systemTargets: SystemTargets,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public data class XposedTarget(
@RootingDslMarker
public class RootTargetBuilder {
private var enabled: Boolean = false
private var allowExplicitRootCheck: Boolean = false

internal fun enable() {
enabled = true
Expand All @@ -62,6 +63,17 @@ public class RootTargetBuilder {
enabled = false
}

/**
* By default kevlar does not run the `su` binary. Instead, it passively analyzes the
* system environment to detect root access.
*
* If you don't mind having your application ask for root permission, you can enable this
* flag, so that kevlar will be trying to acquire root access as an additional check.
* */
public fun allowExplicitRootCheck() {
allowExplicitRootCheck = true
}

public fun build(): RootTarget = RootTarget(enabled)
}

Expand Down
2 changes: 1 addition & 1 deletion rooting/src/main/kotlin/com/kevlar/rooting/shell/Dumper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ internal suspend fun BinaryDump(
Shell.sh("run-as $packageName $binaryName").exec()
}

//awaitAll(shellId, binaryPathExtraction, binaryTest)
awaitAll(shellId, binaryPathExtraction, binaryTest)

This comment has been minimized.

Copy link
@Nek-12

Nek-12 Dec 26, 2022

Contributor

Seems that you don't understand how coroutines work. Your checks were already parallel and you literally made no difference by uncommenting this line. async {} blocks are launched when lambda scope is left (on creation) @cioccarellia

This comment has been minimized.

Copy link
@Nek-12

Nek-12 Dec 26, 2022

Contributor

image


BinaryDump(
binaryName = binaryName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ class RootingRepository @Inject constructor(
allowExplicitRootCheck()
}

/**
* This uses the default settings, only targets/root and status/emulator
* */
private val defaultRooting = KevlarRooting()

suspend fun attestateRoot(): TargetRootingAttestation = withContext(externalDispatcher) {
rooting.attestateTargets(context)
}
Expand Down

0 comments on commit 9aa9537

Please sign in to comment.