This commit is contained in:
parent
1b461338b7
commit
6f7afe73a7
6 changed files with 3814 additions and 81 deletions
|
|
@ -125,7 +125,7 @@ The contributions of this thesis are the following:
|
|||
+ We propose an approach to allow static analysis tools to analyse applications that perform dynamic code loading:
|
||||
We collect at runtime the bytecode dynamically loaded and the reflection calls information, and patch the #APK file to perform those operations statically.
|
||||
Finally, we evaluate the impact this transformation has on the tools we containerised previously.
|
||||
+ We released under the AGPL licence #todo[Still waiting for CS to validate] the software we used in the experiments presented in this thesis.
|
||||
+ We released under the GPL licence the software we used in the experiments presented in this thesis.
|
||||
For @sec:rasta, this includes the code used to test the output of each tool and the code to analyse the results of the experiment, in addition to the containers to run the tested tools.
|
||||
We also released Androscalpel, a Rust crate to manipulate Dalvik bytecode, that we used to create Theseus, a set of scripts that implement the approach presented in @sec:th.
|
||||
The complete list and location of the software we release are available in @sec:soft.
|
||||
|
|
|
|||
310
slides.typ
310
slides.typ
|
|
@ -453,6 +453,7 @@
|
|||
"static-vs-dyn",
|
||||
"theseus",
|
||||
).at(i)
|
||||
if i != 0 { counter("logical-slide").update( n => n - 1 ) }
|
||||
slide(
|
||||
//foreground: rotate(30deg, smallcaps(text(fill: pirat-color.red, size: 50pt)[#stage]))
|
||||
)[
|
||||
|
|
@ -921,12 +922,6 @@
|
|||
title: [MultiDex]
|
||||
)[
|
||||
#set align(center + horizon)
|
||||
#let apk-block = block.with(
|
||||
//fill: green.lighten(50%),
|
||||
stroke: black,
|
||||
inset: 10pt,
|
||||
radius: 12pt,
|
||||
)
|
||||
|
||||
#only(1)[
|
||||
#apk-block[
|
||||
|
|
@ -1036,25 +1031,22 @@
|
|||
]
|
||||
)
|
||||
]
|
||||
]
|
||||
|
||||
#only(5)[
|
||||
#for i in range(3) {
|
||||
counter("logical-slide").update( n => n - 1 )
|
||||
show table.cell: c => {
|
||||
if c.y >= 1 and ((i < 2 and c.x == 2) or (i < 1 and c.x == 1)) {
|
||||
[]
|
||||
} else {
|
||||
c
|
||||
}
|
||||
}
|
||||
slide(
|
||||
title: [Self-Shadowing],
|
||||
)[
|
||||
#grid(
|
||||
columns: (1fr, 1fr),
|
||||
apk-block[
|
||||
#set align(left+top)
|
||||
|
||||
=== `app.apk`
|
||||
#line(length: 30%)
|
||||
```
|
||||
AndroidManifest.xml
|
||||
resources.arsc
|
||||
META-INF/
|
||||
res/
|
||||
classes.dex
|
||||
classes2.dex
|
||||
classes3.dex
|
||||
```
|
||||
],
|
||||
columns: (2fr, 0.5em, 3fr),
|
||||
yes-codly[
|
||||
#set list(spacing: 0.5em)
|
||||
#scale(100%, reflow: true,
|
||||
|
|
@ -1065,15 +1057,40 @@
|
|||
else:
|
||||
return f"classes{index+1}.dex"
|
||||
```)
|
||||
- `classes0.dex` ?
|
||||
- `classes02.dex` ?
|
||||
- `classes10.dex` ?
|
||||
]
|
||||
#align(bottom, text(size: 0.75em)[#sym.star estimation, non-deterministic])
|
||||
], [], {
|
||||
set text(size: 24pt)
|
||||
show table.cell: set align(center+horizon)
|
||||
let r = text.with(fill: pirat-color.red.darken(10%))
|
||||
table(
|
||||
columns: (1fr, 1fr, 1fr),
|
||||
//inset: (x,y) => if y == 0 { 10pt } else { 3pt },
|
||||
stroke: none,
|
||||
table.header(
|
||||
[Android],
|
||||
table.vline(),
|
||||
[Soot],
|
||||
table.vline(),
|
||||
[Androguard#super[#sym.star]]
|
||||
),
|
||||
table.hline(),
|
||||
[`classes.dex`], [`classes.dex`], [`classes10.dex`],
|
||||
..if (i != 0) {(
|
||||
[], r[`classes1.dex`], [],
|
||||
[], r[`classes10.dex`], [],
|
||||
)},
|
||||
[`classes2.dex`], [`classes2.dex`], [`classes9.dex`],
|
||||
[`classes3.dex`], [`classes3.dex`], [`classes8.dex`],
|
||||
|
||||
table.cell(colspan: 3, inset: -3pt)[...],
|
||||
|
||||
[`classes9.dex`], [`classes9.dex`], [`classes2.dex`],
|
||||
[`classes10.dex`], [], [`classes1.dex`],
|
||||
strike[`classes1.dex`], [], [`classes.dex`],
|
||||
)}
|
||||
)
|
||||
#ghost-4(x: 2%, y: 2%, mirror: true)
|
||||
]
|
||||
]
|
||||
|
||||
}
|
||||
#for i in range(4) {
|
||||
if i != 0 { counter("logical-slide").update( n => n - 1 ) }
|
||||
slide(
|
||||
|
|
@ -1084,12 +1101,12 @@
|
|||
codly(
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 1 {
|
||||
} else if i == 2 {
|
||||
codly(
|
||||
highlighted-lines: (7, 8),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 2 {
|
||||
} else if i == 1 {
|
||||
codly(
|
||||
highlighted-lines: (1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15),
|
||||
..default-codly
|
||||
|
|
@ -1144,17 +1161,17 @@
|
|||
#set align(left)
|
||||
#set text(size: 18pt)
|
||||
#partial-hide(i, hidden: (0,), partial: (2,))[
|
||||
=== Self Shadowing
|
||||
Trick the tool into using an APK class instead of another APK class
|
||||
]
|
||||
#partial-hide(i, hidden: (0, 1))[
|
||||
=== SDK shadowing
|
||||
Trick the tool into using an APK class instead of an SDK class
|
||||
]
|
||||
#partial-hide(i, hidden: (0,), partial: (2,))[
|
||||
#partial-hide(i, hidden: (0, 1))[
|
||||
=== Hidden API shadowing
|
||||
Trick the tool into using an APK class instead of an hidden API class
|
||||
]
|
||||
#partial-hide(i, hidden: (0,1))[
|
||||
=== Self Shadowing
|
||||
Trick the tool into using an APK class instead of another APK class
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
|
|
@ -1180,17 +1197,27 @@
|
|||
]
|
||||
|
||||
#slide(
|
||||
title: [Example: Androguard],
|
||||
title: [Androguard on Toy Malware],
|
||||
foreground: eye-4(x: 97%, y: 85%, mirror: true)
|
||||
)[
|
||||
#set align(center+horizon)
|
||||
#show image: scale.with(250%)
|
||||
#set figure(gap: 4em)
|
||||
//#show image: scale.with(250%)
|
||||
//#set figure(gap: 4em)
|
||||
#v(3em)
|
||||
#grid(
|
||||
columns: (1fr, 1fr),
|
||||
get_figure(<fig:cl-andro_non_obf_cg>),
|
||||
get_figure(<fig:cl-andro_obf_cg>)
|
||||
//get_figure(<fig:cl-andro_non_obf_cg>),
|
||||
figure(
|
||||
image("slides/imgs/call_graph_expected.svg", width: 100%),
|
||||
caption: [Expected],
|
||||
supplement: none,
|
||||
),
|
||||
//get_figure(<fig:cl-andro_obf_cg>)
|
||||
figure(
|
||||
image("slides/imgs/call_graph_obf.svg", width: 100%),
|
||||
caption: [Computed],
|
||||
supplement: none,
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
|
@ -1267,7 +1294,7 @@
|
|||
- We did not find deliberate shadow attacks
|
||||
]
|
||||
#v(1fr)
|
||||
#align(center, text(fill: pirat-color.blue.darken(30%))[Digital Threats: Research and Practice])
|
||||
#align(center, text(fill: pirat-color.blue.darken(30%))[Digital Threats: Research and Practice, vol. 6 (3), 2025])
|
||||
#v(0.5em)
|
||||
]
|
||||
|
||||
|
|
@ -1276,18 +1303,29 @@
|
|||
// TODO put everywhere Theseus Transformeur
|
||||
|
||||
#slide(
|
||||
title: [State of the Art],
|
||||
title: [Dexhunter: Zang #etal (2015)],
|
||||
)[
|
||||
#align(center+horizon, text(fill: pirat-color.red, size: 30pt)[INSERT SoA])
|
||||
#align(center+horizon, dexhunter-outline(
|
||||
small_icon_size: 75pt,
|
||||
big_icon_size: 200pt,
|
||||
))
|
||||
]
|
||||
|
||||
#slide(
|
||||
title: [Overview],
|
||||
foreground: rotate(30deg, text(fill: pirat-color.red, size: 50pt)[FINIR DESSIN]),
|
||||
title: [DroidRA: Li #etal (2016)],
|
||||
)[
|
||||
#align(center+horizon, droidra-outline(
|
||||
small_icon_size: 75pt,
|
||||
big_icon_size: 200pt,
|
||||
))
|
||||
]
|
||||
|
||||
#slide(
|
||||
title: [Theseus: Overview],
|
||||
)[
|
||||
// TODO: bien tout rappeler l'objectif
|
||||
#set align(center+horizon)
|
||||
#theseus-outline()
|
||||
#only(1, theseus-outline(stage: "theseus-no-static"))
|
||||
#only(2, theseus-outline(stage: "theseus"))
|
||||
]
|
||||
|
||||
#slide(
|
||||
|
|
@ -1387,32 +1425,62 @@
|
|||
)[
|
||||
#show: yes-codly
|
||||
#set align(center+horizon)
|
||||
|
||||
#if i == 1 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlighted-lines: (6,),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 4 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlights: (
|
||||
(line: 6, start: 0, end: 25, fill: pirat-color.blue),
|
||||
),
|
||||
..default-codly
|
||||
)
|
||||
} else {
|
||||
codly(
|
||||
offset: 5,
|
||||
..default-codly
|
||||
)
|
||||
}
|
||||
```java
|
||||
String retData = (String) mth.invoke(obj, args);
|
||||
```
|
||||
|
||||
#v(-0.5em)
|
||||
#align(center+horizon, sym.arrow.b.stroked)
|
||||
#v(-0.5em)
|
||||
|
||||
#if i == 1 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlighted-lines: (10,),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 2 {
|
||||
} else if i == 3 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlights: (
|
||||
(line: 6, start: 0, end: 13, fill: pirat-color.blue),
|
||||
(line: 8, start: 3, end: 8, fill: pirat-color.blue),
|
||||
(line: 10, start: 3, end: 8, fill: pirat-color.blue),
|
||||
(line: 12, start: 18, end: 32, fill: pirat-color.blue),
|
||||
),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 3 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlights: (
|
||||
(line: 8, start: 12, end: 19, fill: pirat-color.blue),
|
||||
(line: 12, start: 18+9, end: 32, fill: pirat-color.blue),
|
||||
),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 4 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlights: (
|
||||
(line: 8, start: 12, end: 19, fill: pirat-color.blue),
|
||||
(line: 12, start: 0, end: 25, fill: pirat-color.blue),
|
||||
),
|
||||
..default-codly
|
||||
)
|
||||
} else if i == 2 {
|
||||
codly(
|
||||
offset: 5,
|
||||
highlights: (
|
||||
|
|
@ -1442,7 +1510,41 @@
|
|||
}
|
||||
|
||||
#slide(
|
||||
foreground: rotate(30deg, text(fill: pirat-color.red, size: 50pt)[MOCHE]),
|
||||
foreground: {
|
||||
arrow(
|
||||
stroke: 10pt + pirat-color.red,
|
||||
(
|
||||
250pt,
|
||||
-400pt,
|
||||
),
|
||||
(
|
||||
250pt,
|
||||
-350pt,
|
||||
)
|
||||
)
|
||||
arrow(
|
||||
stroke: 10pt + pirat-color.red,
|
||||
(
|
||||
130pt,
|
||||
-400pt,
|
||||
),
|
||||
(
|
||||
180pt,
|
||||
-320pt,
|
||||
)
|
||||
)
|
||||
arrow(
|
||||
stroke: 10pt + pirat-color.red,
|
||||
(
|
||||
370pt,
|
||||
-400pt,
|
||||
),
|
||||
(
|
||||
320pt,
|
||||
-320pt,
|
||||
)
|
||||
)
|
||||
}
|
||||
)[
|
||||
#set align(center+horizon)
|
||||
#theseus-outline()
|
||||
|
|
@ -1475,6 +1577,11 @@
|
|||
title: [Collected Bytecode],
|
||||
foreground: eye-1(x: 5%, y: 70%, height: 70pt)
|
||||
)[
|
||||
/*
|
||||
* Explications, give example of Google Services:
|
||||
* whithout service: does not work
|
||||
* with service: service recognize the app as malware and block it
|
||||
*/
|
||||
#set align(center+horizon)
|
||||
#show link.where(dest: <acr-apk>): it => it.body
|
||||
#show link.where(dest: <acr-dex>): it => it.body
|
||||
|
|
@ -1494,10 +1601,33 @@
|
|||
]
|
||||
|
||||
#slide(
|
||||
foreground: rotate(30deg, text(fill: pirat-color.red, size: 50pt)[MOCHE]),
|
||||
foreground: {
|
||||
arrow(
|
||||
stroke: 10pt + pirat-color.red,
|
||||
(
|
||||
770pt,
|
||||
-250pt,
|
||||
),
|
||||
(
|
||||
620pt,
|
||||
-350pt,
|
||||
)
|
||||
)
|
||||
arrow(
|
||||
stroke: 10pt + pirat-color.red,
|
||||
(
|
||||
620pt,
|
||||
-350pt,
|
||||
),
|
||||
(
|
||||
770pt,
|
||||
-250pt,
|
||||
)
|
||||
)
|
||||
}
|
||||
)[
|
||||
#set align(center+horizon)
|
||||
#theseus-outline()
|
||||
#theseus-outline(stage: "theseus-vs-static")
|
||||
]
|
||||
|
||||
#for i in range(3) {
|
||||
|
|
@ -1506,25 +1636,45 @@
|
|||
slide(
|
||||
title: [Added Method Calls],
|
||||
)[
|
||||
// TODO: remove Before After
|
||||
#set align(center+horizon)
|
||||
#show link.where(dest: <acr-apk>): it => it.body
|
||||
#show link.where(dest: <acr-dex>): it => it.body
|
||||
#show figure.caption: none
|
||||
#set table(
|
||||
fill: (x, y) => {
|
||||
if (
|
||||
i == 1 and (x == 3 and y > 1)
|
||||
//#show link.where(dest: <acr-apk>): it => it.body
|
||||
//#show link.where(dest: <acr-dex>): it => it.body
|
||||
//#show figure.caption: none
|
||||
|
||||
//#scale(90%, reflow: true, get_figure(<tab:th-compare-cg>))
|
||||
#import "5_theseus/X_var.typ": compared_callgraph
|
||||
#import "lib.typ": num
|
||||
#let nb_col = 3
|
||||
#table(
|
||||
columns: (1fr, 1.1fr, 1fr),
|
||||
align: center+horizon,
|
||||
stroke: none,
|
||||
fill: (x, y) => if (
|
||||
i == 1 and (x == 1 and y > 1 and y != 9)
|
||||
) or (
|
||||
i == 2 and (x == 4 and y > 1)
|
||||
i == 2 and (x == 2 and y > 1)
|
||||
){
|
||||
highlight-color
|
||||
} else {
|
||||
none
|
||||
}
|
||||
}
|
||||
},
|
||||
table.hline(),
|
||||
table.header(
|
||||
//[SHA 256], [Original CG edges], [New CG edges], [Edges added], [Reflection edges added],
|
||||
table.cell(rowspan: 2)[APK SHA 256],
|
||||
table.cell(colspan: nb_col - 1)[Number of Call Graph edges], [Diff (Total After - Before)], [Added Reflection],
|
||||
),
|
||||
table.hline(),
|
||||
..compared_callgraph.map(
|
||||
(e) => (
|
||||
[#lower(e.sha256).slice(0, 10)...],
|
||||
num(e.added),
|
||||
num(e.added_ref_only)
|
||||
)).flatten(),
|
||||
[#lower("5D2CD1D10ABE9B1E8D93C4C339A6B4E3D75895DE1FC49E248248B5F0B05EF1CE").slice(0, 10)...], table.cell(colspan: nb_col - 1)[_Transformation Crashed_],
|
||||
table.hline(),
|
||||
)
|
||||
#scale(90%, reflow: true, get_figure(<tab:th-compare-cg>))
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1549,14 +1699,18 @@
|
|||
foreground: {
|
||||
let strk = 3pt + pirat-color.blue
|
||||
import "slides/icons.typ": arrow
|
||||
arrow((360pt, 330pt), (380pt, 310pt), strk: strk)
|
||||
arrow((420pt, 330pt), (400pt, 310pt), strk: strk)
|
||||
arrow((290pt, -335pt), (320pt, -310pt), strk: strk)
|
||||
arrow((400pt, -335pt), (340pt, -310pt), strk: strk)
|
||||
}
|
||||
)[
|
||||
#set align(center+horizon)
|
||||
#show figure.caption: none
|
||||
|
||||
Original #h(2em) Transformed
|
||||
#move(dx: -70pt)[Original #h(2em) Transformed]
|
||||
|
||||
/*
|
||||
* JFL bet on a question about SAAF
|
||||
*/
|
||||
|
||||
#box(width: 80%, get_figure(<fig:th-status-npatched-vs-patched>))
|
||||
]
|
||||
|
|
@ -1578,7 +1732,7 @@
|
|||
We showed that:
|
||||
|
||||
#item-by-item[
|
||||
- After five years, more than half the static analysis tools are no longer usable.
|
||||
- Most Static analysis tools are no longer usable after a few years.
|
||||
The size of the application seems to be the most significant factor.
|
||||
- Android behaviour is complex and not well known.
|
||||
In the specific case of class loading, we showed that state-of-the-art tools do not match Android, leading to invalid analyses.
|
||||
|
|
|
|||
1782
slides/imgs/call_graph_expected.svg
Normal file
1782
slides/imgs/call_graph_expected.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 70 KiB |
1782
slides/imgs/call_graph_obf.svg
Normal file
1782
slides/imgs/call_graph_obf.svg
Normal file
File diff suppressed because it is too large
Load diff
|
After Width: | Height: | Size: 70 KiB |
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#import "../lib.typ": pb1-text, pb2-text, pb3-text
|
||||
#import "icons.typ": arrow
|
||||
#import "outlines.typ": theseus-outline
|
||||
#import "outlines.typ": theseus-outline, dexhunter-outline, droidra-outline
|
||||
|
||||
#let pirat-color = (
|
||||
black: rgb("#000000"),
|
||||
|
|
@ -35,6 +35,14 @@ pirat-color.red,
|
|||
)
|
||||
}
|
||||
|
||||
#let apk-block = block.with(
|
||||
//fill: green.lighten(50%),
|
||||
stroke: black,
|
||||
inset: 10pt,
|
||||
radius: 12pt,
|
||||
)
|
||||
|
||||
|
||||
#let colortest = [
|
||||
#for th in (
|
||||
sns-polylux-template_sns-pirat,
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@
|
|||
box(
|
||||
width: width,
|
||||
height: height,
|
||||
stroke: black,
|
||||
//stroke: black,
|
||||
{
|
||||
place(
|
||||
left+bottom,
|
||||
|
|
@ -221,6 +221,13 @@
|
|||
)
|
||||
}
|
||||
|
||||
#let droidra-outline(
|
||||
small_icon_size: 100pt,
|
||||
big_icon_size: 200pt,
|
||||
) = context {
|
||||
text(fill: red, size: 40pt)[TODO]
|
||||
}
|
||||
|
||||
#let theseus-outline(
|
||||
small_icon_size: 60pt,
|
||||
big_icon_size: 90pt,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue