This commit is contained in:
parent
3b5df50248
commit
ca4e7703e1
6 changed files with 2781 additions and 623 deletions
|
|
@ -13,6 +13,6 @@ We show how these attacks can confuse the tools of the reverser when he performs
|
||||||
The chapter is structured as follows.
|
The chapter is structured as follows.
|
||||||
@sec:cl-loading investigates the internal mechanisms of class loading and presents how a reverser can be confused by these mechanisms.
|
@sec:cl-loading investigates the internal mechanisms of class loading and presents how a reverser can be confused by these mechanisms.
|
||||||
Then, in @sec:cl-obfuscation, we design obfuscation techniques and show their effect on static analysis tools.
|
Then, in @sec:cl-obfuscation, we design obfuscation techniques and show their effect on static analysis tools.
|
||||||
Next, @sec:cl-wild evaluates if these obfuscation techniques are used in the wild by scanning #nbapk APKs.
|
Next, @sec:cl-wild evaluates whether these obfuscation techniques are used in the wild by scanning #nbapk APKs.
|
||||||
@sec:cl-conclusion extends on the possible countermeasures against those shadow attacks, how they interact with other obfuscation techniques, as well as the limitations of this work and avenues left to explore.
|
@sec:cl-conclusion extends on the possible countermeasures against those shadow attacks, how they interact with other obfuscation techniques, as well as the limitations of this work and avenues left to explore.
|
||||||
Finally, @sec:cl-conclusion concludes the chapter.
|
Finally, @sec:cl-conclusion concludes the chapter.
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ With the increasing complexity of Android applications, the need arose to load m
|
||||||
To solve this problem, Android started storing classes in multiple files named `classesX.dex` as illustrated by the @lst:cl-dexname that generates the filenames read by class loaders.
|
To solve this problem, Android started storing classes in multiple files named `classesX.dex` as illustrated by the @lst:cl-dexname that generates the filenames read by class loaders.
|
||||||
Android starts loading the file `GetMultiDexClassesDexName(0)` (`classes.dex`), then `GetMultiDexClassesDexName(1)` (`classes2.dex`), and continues until finding a value `n` for which `GetMultiDexClassesDexName(n)` does not exist.
|
Android starts loading the file `GetMultiDexClassesDexName(0)` (`classes.dex`), then `GetMultiDexClassesDexName(1)` (`classes2.dex`), and continues until finding a value `n` for which `GetMultiDexClassesDexName(n)` does not exist.
|
||||||
Even if Android emits a warning message when it finds more than 100 #dexfiles, it will still load any number of #dexfiles that way.
|
Even if Android emits a warning message when it finds more than 100 #dexfiles, it will still load any number of #dexfiles that way.
|
||||||
This change had the unintended consequence of permitting two classes with the same name but different implementations to be stored in the same `.apk` file using two #dexfiles (#eg the class `Foo` can be defined both in `classes.dex` and `classes2.dex`).
|
This change has the unintended consequence of permitting two classes with the same name but different implementations to be stored in the same `.apk` file using two #dexfiles (#eg the class `Foo` can be defined both in `classes.dex` and `classes2.dex`).
|
||||||
|
|
||||||
Android explicitly performs checks that prevent several classes from using the same name inside a #dexfile.
|
Android explicitly performs checks that prevent several classes from using the same name inside a #dexfile.
|
||||||
However, this check does not apply to multiple #dexfiles in the same `.apk` file, and a `.dex` can contain a class with a name already used by another class in another #dexfile of the application.
|
However, this check does not apply to multiple #dexfiles in the same `.apk` file, and a `.dex` can contain a class with a name already used by another class in another #dexfile of the application.
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,8 @@ Such shadow attacks are more difficult to detect by a reverse engineer, who may
|
||||||
|
|
||||||
=== Impact on Static Analysis Tools <sec:cl-evaltools>
|
=== Impact on Static Analysis Tools <sec:cl-evaltools>
|
||||||
|
|
||||||
#figure(
|
#figure({
|
||||||
|
set text(size: 10pt)
|
||||||
```java
|
```java
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(Activity ac) {
|
public static void main(Activity ac) {
|
||||||
|
|
@ -77,7 +78,7 @@ Such shadow attacks are more difficult to detect by a reverse engineer, who may
|
||||||
public class Obfuscation {
|
public class Obfuscation {
|
||||||
public static String hide_flow(String personal_data) { ... }
|
public static String hide_flow(String personal_data) { ... }
|
||||||
}
|
}
|
||||||
```,
|
```},
|
||||||
caption: [Main body of test apps]
|
caption: [Main body of test apps]
|
||||||
)<lst:cl-testapp>
|
)<lst:cl-testapp>
|
||||||
|
|
||||||
|
|
@ -102,7 +103,7 @@ We used 4 versions of this application:
|
||||||
We used the #SDK class `Pair` as the class to shadow.
|
We used the #SDK class `Pair` as the class to shadow.
|
||||||
We put data in a new `Pair` instance and reread the data from the `Pair`.
|
We put data in a new `Pair` instance and reread the data from the `Pair`.
|
||||||
The colliding `Pair` class we created discards the data at the initialisation and stores `null` instead of the argument values.
|
The colliding `Pair` class we created discards the data at the initialisation and stores `null` instead of the argument values.
|
||||||
This decoy class break the flow of information: Flowdroid will detect the information flow if it uses the actual #SDK implementation of `Pair` to compute the #DFG, but not if it uses the decoy.
|
This decoy class breaks the flow of information: Flowdroid will detect the information flow if it uses the actual #SDK implementation of `Pair` to compute the #DFG, but not if it uses the decoy.
|
||||||
+ The last version tests for Hidden #API shadowing.
|
+ The last version tests for Hidden #API shadowing.
|
||||||
Like for the third one, we similarly store data in `com.android.okhttp.Request` and then retrieve it.
|
Like for the third one, we similarly store data in `com.android.okhttp.Request` and then retrieve it.
|
||||||
Again, the shadowing implementation discards the data.
|
Again, the shadowing implementation discards the data.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
In this section, we evaluate in the wild if applications that can be found in the Play Store or other markets use one of the shadow techniques.
|
In this section, we evaluate in the wild if applications that can be found in the Play Store or other markets use one of the shadow techniques.
|
||||||
Our goal is to explore the usage of shadow techniques in real applications.
|
Our goal is to explore the usage of shadow techniques in real applications.
|
||||||
Because we modelled the behaviour of a recent version of Android (#SDK 34), we decided not to use our dataset from @sec:rasta.
|
Because we modelled the behaviour of a recent version of Android (#SDK 34), we decided not to use our dataset from @sec:rasta.
|
||||||
The applications in the RASTA dataset span over more than 10 years, and we cannot guarantee that sandow attacks behaved the same during those 10 years.
|
The applications in the RASTA dataset span over more than 10 years, and we cannot guarantee that shadow attacks behaved the same during those 10 years.
|
||||||
At the very least, self-shadowing would not be possible before the introduction of multi-dex in 2014 -- about a fourth of the applications in the RASTA dataset.
|
At the very least, self-shadowing would not be possible before the introduction of multi-dex in 2014 -- about a fourth of the applications in the RASTA dataset.
|
||||||
Instead, we sampled another dataset of recent applications.
|
Instead, we sampled another dataset of recent applications.
|
||||||
This way, we can also include malicious applications (in case such techniques would be used to hide malicious code), so we selected #num(50000) applications randomly from AndroZoo~@allixAndroZooCollectingMillions2016 that appeared in 2023.
|
This way, we can also include malicious applications (in case such techniques would be used to hide malicious code), so we selected #num(50000) applications randomly from AndroZoo~@allixAndroZooCollectingMillions2016 that appeared in 2023.
|
||||||
|
|
@ -89,7 +89,7 @@ We report in the upper part of @tab:cl-shadow the statistics about the whole dat
|
||||||
We observe that, on average, a few classes are shadowed by another class.
|
We observe that, on average, a few classes are shadowed by another class.
|
||||||
Note that the median value is 0, meaning that few apps shadow a lot of classes, but the majority of apps do not shadow anything.
|
Note that the median value is 0, meaning that few apps shadow a lot of classes, but the majority of apps do not shadow anything.
|
||||||
The number of applications shadowing a hidden #API is low, which is an expected result as these classes should not be known by the developer.
|
The number of applications shadowing a hidden #API is low, which is an expected result as these classes should not be known by the developer.
|
||||||
We observe a consequent number of applications, 23.52%, of applications that perform #SDK shadowing.
|
We observe a consequent number of applications, 23.52%, that perform #SDK shadowing.
|
||||||
It can be explained by the fact that some classes that newly appear are embedded in the #APK for end users that have old versions of Android: it is suggested by the average value of Min #SDK which is 21.7 for the whole dataset: on average, an application can be run inside a smartphone with #API 21, which would require to embed all new classes from 22 to 34.
|
It can be explained by the fact that some classes that newly appear are embedded in the #APK for end users that have old versions of Android: it is suggested by the average value of Min #SDK which is 21.7 for the whole dataset: on average, an application can be run inside a smartphone with #API 21, which would require to embed all new classes from 22 to 34.
|
||||||
This hypothesis about missing classes is further investigated later in this section.
|
This hypothesis about missing classes is further investigated later in this section.
|
||||||
|
|
||||||
|
|
@ -241,7 +241,7 @@ All these hidden shadow classes are libraries included by the developers who pro
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```,
|
```,
|
||||||
caption: [Implementation of Reflection found un `classes11.dex` (shadows @lst:cl-refl1)],
|
caption: [Implementation of Reflection found in `classes11.dex` (shadows @lst:cl-refl1)],
|
||||||
) <lst:cl-refl2>
|
) <lst:cl-refl2>
|
||||||
|
|
||||||
#figure(
|
#figure(
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
=== Countermeasures <sec:cl-countermeasures>
|
=== Countermeasures <sec:cl-countermeasures>
|
||||||
|
|
||||||
Countermeasures against shadow attacks depend on each tool and its objectives.
|
Countermeasures against shadow attacks depend on each tool and its objectives.
|
||||||
The first important recommendation is to implement the class selection algorithm according to the algorithm described in Listing @lst:cl-loading-alg.
|
The first important recommendation is to implement the class selection algorithm according to the algorithm described in @lst:cl-loading-alg.
|
||||||
It should solve any case of self-shadowing, except for tools like Apktool, which do not have to select a class for computing the result, but show the whole application's content.
|
It should solve any case of self-shadowing, except for tools like Apktool, that do not have to select a class for computing the result, but show the whole application's content.
|
||||||
For those tools, a clear warning should be added, pointing out that multiple implementations have been found and displaying the one that will be used at runtime.
|
For those tools, a clear warning should be added, pointing out that multiple implementations have been found and displaying the one that will be used at runtime.
|
||||||
|
|
||||||
Countermeasures against #SDK shadow and Hidden shadow attacks are more complex to handle: they require the list of platform classes on the target smartphone and, in some cases, their implementation.
|
Countermeasures against #SDK shadow and Hidden shadow attacks are more complex to handle: they require the list of platform classes on the target smartphone and, in some cases, their implementation.
|
||||||
|
|
@ -72,7 +72,7 @@ In addition, platform classes are stored differently in older versions of Androi
|
||||||
For this reason, we did not compare the classes found in applications to their versions older than #SDK 32 to avoid producing unreliable statistics for those versions.
|
For this reason, we did not compare the classes found in applications to their versions older than #SDK 32 to avoid producing unreliable statistics for those versions.
|
||||||
|
|
||||||
|
|
||||||
=== Futur Works <sec:cl-futur>
|
=== Future Works <sec:cl-future>
|
||||||
|
|
||||||
As we just said, our Smali-based comparison of class implementation is quite naive and could use more work.
|
As we just said, our Smali-based comparison of class implementation is quite naive and could use more work.
|
||||||
It could be insightful to be able to detect exactly when two classes are from the same source file, or which version of a library a class belong to.
|
It could be insightful to be able to detect exactly when two classes are from the same source file, or which version of a library a class belong to.
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 126 KiB |
Loading…
Add table
Add a link
Reference in a new issue