Translated ['src/mobile-pentesting/android-app-pentesting/reversing-nati

This commit is contained in:
Translator 2025-09-04 09:31:18 +00:00
parent 85168df8c5
commit 81ba42372f
3 changed files with 101 additions and 101 deletions

View File

@ -2,7 +2,7 @@
{{#include ../../banners/hacktricks-training.md}}
## CheatSheets d'informatique légale
## Fiches CheatSheets d'informatique légale
[https://www.jaiminton.com/cheatsheet/DFIR/#](https://www.jaiminton.com/cheatsheet/DFIR/)
@ -22,23 +22,23 @@
```bash
sudo apt-get install -y yara
```
#### Préparer les règles
#### Préparez les règles
Utilisez ce script pour télécharger et fusionner toutes les règles yara malware depuis github: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\
Créez le répertoire _**rules**_ et exécutez-le. Cela créera un fichier appelé _**malware_rules.yar**_ qui contient toutes les règles yara pour malware.
Créez le répertoire _**rules**_ puis exécutez le script. Cela créera un fichier appelé _**malware_rules.yar**_ qui contient toutes les règles yara pour malware.
```bash
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
mkdir rules
python malware_yara_rules.py
```
#### Scan
#### Analyse
```bash
yara -w malware_rules.yar image #Scan 1 file
yara -w malware_rules.yar folder #Scan the whole folder
```
#### YaraGen : Détecter les malware et créer des règles
#### YaraGen: Détecter le malware et créer des règles
Vous pouvez utiliser l'outil [**YaraGen**](https://github.com/Neo23x0/yarGen) pour générer des yara rules à partir d'un binary. Consultez ces tutoriels : [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
Vous pouvez utiliser l'outil [**YaraGen**](https://github.com/Neo23x0/yarGen) pour générer des yara rules à partir d'un binaire. Consultez ces tutoriels : [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
```bash
python3 yarGen.py --update
python3.exe yarGen.py --excludegood -m ../../mals/
@ -57,21 +57,21 @@ clamscan folderpath #Scan the whole folder
```
### [Capa](https://github.com/mandiant/capa)
**Capa** détecte des **capabilities** potentiellement malveillantes dans les exécutables : PE, ELF, .NET. Il trouvera donc des éléments tels que les tactiques Att\&ck, ou des capacités suspectes telles que :
**Capa** détecte des **capacités** potentiellement malveillantes dans les exécutables : PE, ELF, .NET. Il trouvera donc des éléments tels que les tactiques Att\&ck, ou des capacités suspectes telles que :
- vérifier la présence d'une erreur OutputDebugString
- s'exécuter en tant que service
- créer un processus
Récupérez-le sur le [**Github repo**](https://github.com/mandiant/capa).
Récupérez-le dans le [**Github repo**](https://github.com/mandiant/capa).
### IOCs
IOC signifie Indicator Of Compromise. Un IOC est un ensemble de **conditions qui identifient** un logiciel potentiellement indésirable ou un **malware** confirmé. Les Blue Teams utilisent ce type de définition pour **rechercher ce type de fichiers malveillants** dans leurs **systèmes** et **réseaux**.\
Le partage de ces définitions est très utile : lorsqu'un malware est identifié sur un ordinateur et qu'un IOC pour ce malware est créé, d'autres Blue Teams peuvent l'utiliser pour identifier le malware plus rapidement.
IOC signifie Indicateur de compromission. Un IOC est un ensemble de **conditions qui identifient** un logiciel potentiellement indésirable ou un **malware** confirmé. Les Blue Teams utilisent ce type de définition pour **rechercher ce type de fichiers malveillants** dans leurs **systèmes** et **réseaux**.\
Partager ces définitions est très utile : lorsqu'un **malware** est identifié sur un ordinateur et qu'un IOC pour ce malware est créé, d'autres Blue Teams peuvent l'utiliser pour identifier le malware plus rapidement.
Un outil pour créer ou modifier des IOCs est [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\
Vous pouvez utiliser des outils tels que [**Redline**](https://www.fireeye.com/services/freeware/redline.html) pour **rechercher des IOCs définis sur un dispositif**.
Un outil pour créer ou modifier des IOC est [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\
Vous pouvez utiliser des outils tels que [**Redline**](https://www.fireeye.com/services/freeware/redline.html) pour **rechercher des IOC définis sur un appareil**.
### Loki
@ -92,7 +92,7 @@ Compares process connection endpoints with C2 IOCs (new since version v.10)
```
### Linux Malware Detect
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) est un scanner de malware pour Linux distribué sous licence GNU GPLv2, conçu pour les menaces rencontrées dans les environnements d'hébergement mutualisé. Il utilise des données de menace issues des systèmes de détection d'intrusion en bordure réseau pour extraire des malware utilisés activement dans des attaques et générer des signatures pour la détection. De plus, les données de menace proviennent aussi des soumissions d'utilisateurs via la fonctionnalité de checkout de LMD et des ressources communautaires sur les malware.
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/) est un scanner de malware pour Linux, publié sous licence GNU GPLv2, conçu pour les menaces rencontrées dans les environnements d'hébergement mutualisé. Il utilise des données de menace provenant de systèmes de détection d'intrusion en périphérie réseau pour extraire les malware activement utilisés dans des attaques et génère des signatures pour leur détection. De plus, des données de menace sont également dérivées des soumissions d'utilisateurs via la fonctionnalité de checkout de LMD et des ressources communautaires sur les malware.
### rkhunter
@ -102,31 +102,31 @@ sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--sk
```
### FLOSS
[**FLOSS**](https://github.com/mandiant/flare-floss) est un outil qui va tenter de trouver des strings obfuscated à l'intérieur d'executables en utilisant différentes techniques.
[**FLOSS**](https://github.com/mandiant/flare-floss) est un outil qui tente de trouver des chaînes obfusquées à l'intérieur des exécutables en utilisant différentes techniques.
### PEpper
[PEpper ](https://github.com/Th3Hurrican3/PEpper)vérifie quelques éléments basiques à l'intérieur de l'executable (binary data, entropy, URLs and IPs, some yara rules).
[PEpper ](https://github.com/Th3Hurrican3/PEpper) vérifie quelques éléments basiques dans l'exécutable (données binaires, entropie, URLs et IPs, quelques règles yara).
### PEstudio
[PEstudio](https://www.winitor.com/download) est un outil qui permet d'obtenir des informations sur les exécutables Windows telles que imports, exports, headers, mais il vérifiera aussi virus total et trouvera des potentielles Att\&ck techniques.
[PEstudio](https://www.winitor.com/download) est un outil qui permet d'obtenir des informations sur des exécutables Windows tels que imports, exports, headers, mais vérifie aussi virus total et identifie des techniques potentielles d'Att\&ck.
### Detect It Easy(DiE)
[**DiE**](https://github.com/horsicq/Detect-It-Easy/) est un outil pour détecter si un fichier est **encrypted** et aussi trouver des **packers**.
[**DiE**](https://github.com/horsicq/Detect-It-Easy/) est un outil pour détecter si un fichier est **chiffré** et aussi pour trouver des **packers**.
### NeoPI
[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)is un script Python qui utilise une variété de **statistical methods** pour détecter du contenu **obfuscated** et **encrypted** dans des fichiers texte/script. L'objectif de NeoPI est d'aider à la **detection of hidden web shell code**.
[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI) est un script Python qui utilise diverses **méthodes statistiques** pour détecter du contenu **obfusqué** et **chiffré** dans des fichiers texte/script. Le but de NeoPI est d'aider à la **détection de code web shell caché**.
### **php-malware-finder**
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) fait de son mieux pour détecter du code **obfuscated**/**dodgy code** ainsi que des fichiers utilisant des fonctions **PHP** souvent employées dans des **malwares**/webshells.
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder) fait de son mieux pour détecter du code **obfusqué**/**suspect** ainsi que des fichiers utilisant des fonctions **PHP** souvent utilisées dans des **malwares**/webshells.
### Apple Binary Signatures
When checking some **malware sample** you should always **check the signature** of the binary as the **developer** that signed it may be already **related** with **malware.**
Lorsque vous examinez un **malware sample**, vous devriez toujours **vérifier la signature** du binaire car le **developer** qui l'a signé peut déjà être **lié** au **malware.**
```bash
#Get signer
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
@ -137,27 +137,27 @@ codesign --verify --verbose /Applications/Safari.app
#Check if the signature is valid
spctl --assess --verbose /Applications/Safari.app
```
## Detection Techniques
## Techniques de détection
### File Stacking
### Empilement de fichiers
Si vous savez qu'un dossier contenant les **fichiers** d'un serveur web a été **mis à jour pour la dernière fois à une certaine date**. **Vérifiez** la **date** de création et de modification de tous les **fichiers** du **serveur web** et si une date est **suspicieuse**, examinez ce fichier.
Si vous savez qu'un dossier contenant les **fichiers** d'un serveur web a été **mis à jour pour la dernière fois à une certaine date**, **vérifiez** la **date** de création et de modification de **tous les fichiers** du **serveur web** et si une date est **suspecte**, examinez ce fichier.
### Baselines
### Lignes de base
Si les fichiers d'un dossier **n'auraient pas dû être modifiés**, vous pouvez calculer le **hash** des **fichiers originaux** du dossier et les **comparer** avec ceux **actuels**. Tout ce qui a été modifié sera **suspicieux**.
Si les fichiers d'un dossier **n'auraient pas dû être modifiés**, vous pouvez calculer le **hash** des **fichiers originaux** du dossier et les **comparer** avec ceux **actuels**. Tout élément modifié sera **suspect**.
### Statistical Analysis
### Analyse statistique
Quand l'information est enregistrée dans des logs, vous pouvez **vérifier des statistiques comme combien de fois chaque fichier d'un serveur web a été accédé, car un web shell pourrait être l'un des plus sollicités**.
Lorsque l'information est enregistrée dans des logs, vous pouvez **vérifier des statistiques**, par exemple combien de fois chaque fichier d'un serveur web a été accédé — un web shell peut être parmi les plus accédés.
---
### Android in-app native telemetry (no root)
Sur Android, vous pouvez instrumenter du code natif à l'intérieur du processus de l'application cible en préchargeant une petite librairie de logging avant l'initialisation des autres libs JNI. Cela fournit une visibilité précoce sur le comportement natif sans hooks au niveau du système ni root. Une approche populaire est SoTap : placer libsotap.so pour le bon ABI dans l'APK et injecter un appel System.loadLibrary("sotap") tôt (e.g., static initializer or Application.onCreate), puis collecter les logs depuis des chemins internes/externes ou en fallback sur Logcat.
Sur Android, vous pouvez instrumenter du code natif à l'intérieur du processus de l'application cible en préchargeant une petite librairie de logging avant l'initialisation des autres libs JNI. Cela donne une visibilité précoce sur le comportement natif sans hooks système ni root. Une approche populaire est SoTap : placez libsotap.so pour l'ABI appropriée dans l'APK et injectez un appel System.loadLibrary("sotap") tôt (par ex. initialiseur statique ou Application.onCreate), puis collectez les logs à partir des chemins internes/externes ou en fallback via Logcat.
See the Android native reversing page for setup details and log paths:
Voir la page Android native reversing pour les détails de configuration et les chemins des logs :
{{#ref}}
../../mobile-pentesting/android-app-pentesting/reversing-native-libraries.md
@ -165,13 +165,13 @@ See the Android native reversing page for setup details and log paths:
---
## Déobfuscation du Control-Flow dynamique (JMP/CALL RAX Dispatchers)
## Déobfuscation du contrôle de flux dynamique (JMP/CALL RAX Dispatchers)
Les familles de malware modernes abusent fortement de l'obfuscation du Control-Flow Graph (CFG) : au lieu d'un jump/call direct, elles calculent la destination à l'exécution et exécutent un `jmp rax` ou `call rax`. Un petit *dispatcher* (typiquement neuf instructions) définit la cible finale en fonction des flags CPU `ZF`/`CF`, brisant complètement la récupération statique du CFG.
Les familles de malware modernes abusent fortement de l'obfuscation du Control-Flow Graph (CFG) : au lieu d'un jump/call direct, elles calculent la destination à l'exécution et exécutent un `jmp rax` ou `call rax`. Un petit *dispatcher* (typiquement neuf instructions) définit la cible finale en fonction des drapeaux CPU `ZF`/`CF`, rompant complètement la récupération statique du CFG.
La technique — démontrée par le loader SLOW#TEMPEST — peut être contrecarrée par un workflow en trois étapes reposant uniquement sur IDAPython et l'émulateur CPU Unicorn.
La technique — mise en évidence par le loader SLOW#TEMPEST — peut être contrecarrée par un workflow en trois étapes qui ne s'appuie que sur IDAPython et l'émulateur CPU Unicorn.
### 1. Locate every indirect jump / call
### 1. Localiser chaque jump / call indirect
```python
import idautils, idc
@ -180,7 +180,7 @@ mnem = idc.print_insn_mnem(ea)
if mnem in ("jmp", "call") and idc.print_operand(ea, 0) == "rax":
print(f"[+] Dispatcher found @ {ea:X}")
```
### 2. Extraire le byte-code du dispatcher
### 2. Extraire le dispatcher byte-code
```python
import idc
@ -213,7 +213,7 @@ return mu.reg_read(UC_X86_REG_RAX)
```
Exécutez `run(code,0,0)` et `run(code,1,1)` pour obtenir les cibles de branche *false* et *true*.
### 4. Rétablir un jump / call direct
### 4. Patch back a direct jump / call
```python
import struct, ida_bytes
@ -222,22 +222,22 @@ op = 0xE8 if is_call else 0xE9 # CALL rel32 or JMP rel32
disp = target - (ea + 5) & 0xFFFFFFFF
ida_bytes.patch_bytes(ea, bytes([op]) + struct.pack('<I', disp))
```
Après avoir appliqué le patch, forcez IDA à réanalyser la fonction afin que le CFG complet et la sortie Hex-Rays soient restaurés :
Après le patch, forcez IDA à ré-analyser la fonction afin que le CFG complet et la sortie Hex-Rays soient restaurés :
```python
import ida_auto, idaapi
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
```
### 5. Étiqueter les appels API indirects
Une fois que la véritable destination de chaque `call rax` est connue, vous pouvez indiquer à IDA ce que c'est afin que les types de paramètres et les noms de variables soient récupérés automatiquement :
Une fois que la destination réelle de chaque `call rax` est connue, vous pouvez indiquer à IDA de quoi il s'agit afin que les types de paramètres et les noms de variables soient récupérés automatiquement :
```python
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
```
### Avantages pratiques
* Restaure le vrai CFG → la décompilation passe de *10* lignes à des milliers.
* Permet les string-cross-reference & xrefs, rendant la reconstruction du comportement triviale.
* Les scripts sont réutilisables : déposez-les dans n'importe quel loader protégé par la même astuce.
* Restaure le vrai CFG → la decompilation passe de *10* lignes à des milliers.
* Permet string-cross-reference & xrefs, rendant la reconstruction du comportement triviale.
* Les Scripts sont réutilisables : déposez-les dans n'importe quel loader protégé par le même trick.
---

View File

@ -1,16 +1,16 @@
# Rétro-ingénierie des bibliothèques natives
# Reversing Native Libraries
{{#include ../../banners/hacktricks-training.md}}
**Pour plus d'informations, consultez :** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
Les applications Android peuvent utiliser des bibliothèques natives, généralement écrites en C ou C++, pour des tâches critiques en performance. Les créateurs de malware abusent aussi de ces bibliothèques car les objets partagés ELF sont encore plus difficiles à décompiler que le byte-code DEX/OAT.
Cette page se concentre sur des workflows *pratiques* et des améliorations récentes des outils (2023-2025) qui facilitent la reversing des fichiers `.so` Android.
Les applications Android peuvent utiliser des bibliothèques natives, typiquement écrites en C ou C++, pour des tâches critiques en performance. Les créateurs de malware abusent aussi de ces bibliothèques parce que les ELF shared objects restent plus difficiles à décompiler que le byte-code DEX/OAT.
Cette page se concentre sur des workflows *pratiques* et des améliorations récentes des outils (2023-2025) qui rendent le reversing des fichiers `.so` Android plus simple.
---
### Flux de triage rapide pour un `libfoo.so` fraîchement extrait
### Quick triage-workflow for a freshly pulled `libfoo.so`
1. **Extraire la bibliothèque**
```bash
@ -30,21 +30,21 @@ checksec --file libfoo.so # (peda/pwntools)
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
```
4. **Charger dans un décompilateur** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) et lancer l'analyse automatique.
4. **Charger dans un décompilateur** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) et lancer l'auto-analyse.
Les versions récentes de Ghidra ont introduit un décompilateur AArch64 qui reconnaît les stubs PAC/BTI et les tags MTE, améliorant grandement l'analyse des bibliothèques construites avec l'Android 14 NDK.
5. **Choisir entre reverse statique et dynamique :** du code stripped/obfusqué nécessite souvent de l'*instrumentation* (Frida, ptrace/gdbserver, LLDB).
5. **Décider entre static vs dynamic reversing :** le code strippé/obfusqué nécessite souvent de l'*instrumentation* (Frida, ptrace/gdbserver, LLDB).
---
### Instrumentation dynamique (Frida ≥ 16)
La série 16 de Frida a apporté plusieurs améliorations spécifiques à Android qui aident lorsque la cible utilise les optimisations modernes de Clang/LLD :
La série 16 de Frida a apporté plusieurs améliorations spécifiques à Android qui aident lorsque la cible utilise des optimisations modernes de Clang/LLD :
* `thumb-relocator` peut désormais *hook tiny ARM/Thumb functions* générées par l'alignement agressif de LLD (`--icf=all`).
* L'énumération et le rebinding des *ELF import slots* fonctionnent sur Android, permettant le patch par module via `dlopen()`/`dlsym()` lorsque les inline hooks sont rejetés.
* Le Java hooking a été corrigé pour le nouveau **ART quick-entrypoint** utilisé lorsque les apps sont compilées avec `--enable-optimizations` sur Android 14.
* `thumb-relocator` peut maintenant *hooker de petites fonctions ARM/Thumb* générées par l'alignement agressif de LLD (`--icf=all`).
* L'énumération et le rebinding des *ELF import slots* fonctionne sur Android, permettant des patchs par-module via `dlopen()`/`dlsym()` quand les hooks inline sont rejetés.
* Le Java hooking a été corrigé pour le nouvel **ART quick-entrypoint** utilisé lorsque les apps sont compilées avec `--enable-optimizations` sur Android 14.
Exemple : énumérer toutes les fonctions enregistrées via `RegisterNatives` et dumper leurs adresses à l'exécution :
Example: enumerating all functions registered through `RegisterNatives` and dumping their addresses at runtime:
```javascript
Java.perform(function () {
var Runtime = Java.use('java.lang.Runtime');
@ -61,27 +61,27 @@ console.log('[+] RegisterNatives on ' + clazz.getName() + ' -> ' + count + ' met
});
});
```
Frida will work out of the box on PAC/BTI-enabled devices (Pixel 8/Android 14+) as long as you use frida-server 16.2 or later earlier versions failed to locate padding for inline hooks.
Frida fonctionnera immédiatement sur les appareils activés PAC/BTI (Pixel 8/Android 14+) tant que vous utilisez frida-server 16.2 ou plus récent les versions antérieures échouaient à localiser le padding pour les inline hooks.
### Process-local JNI telemetry via preloaded .so (SoTap)
When full-featured instrumentation is overkill or blocked, you can still gain native-level visibility by preloading a small logger inside the target process. SoTap is a lightweight Android native (.so) library that logs the runtime behavior of other JNI (.so) libraries within the same app process (no root required).
Quand une instrumentation complète est excessif ou bloquée, vous pouvez toujours obtenir une visibilité au niveau natif en préchargeant un petit logger dans le process cible. SoTap est une bibliothèque native Android légère (.so) qui journalise le comportement d'exécution d'autres bibliothèques JNI (.so) dans le même processus d'app (aucun root requis).
Key properties:
- Initializes early and observes JNI/native interactions inside the process that loads it.
- Persists logs using multiple writable paths with graceful fallback to Logcat when storage is restricted.
- Source-customizable: edit sotap.c to extend/adjust what gets logged and rebuild per ABI.
Propriétés clés:
- S'initialise tôt et observe les interactions JNI/native à l'intérieur du processus qui le charge.
- Persiste les logs en utilisant plusieurs chemins inscriptibles avec un repli gracieux vers Logcat lorsque le stockage est restreint.
- Personnalisable depuis la source : éditez sotap.c pour étendre/ajuster ce qui est loggé et reconstruisez par ABI.
Setup (repaquetage de l'APK):
1) Déposez le build ABI approprié dans l'APK afin que le loader puisse résoudre libsotap.so :
Setup (repack the APK):
1) Drop the proper ABI build into the APK so the loader can resolve libsotap.so:
- lib/arm64-v8a/libsotap.so (for arm64)
- lib/armeabi-v7a/libsotap.so (for arm32)
2) Assurez-vous que SoTap se charge avant les autres libs JNI. Injectez un appel tôt (par ex., static initializer de la sous-classe Application ou onCreate) afin que le logger soit initialisé en premier. Exemple de snippet Smali :
2) Ensure SoTap loads before other JNI libs. Inject a call early (e.g., Application subclass static initializer or onCreate) so the logger is initialized first. Smali snippet example:
```smali
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
```
3) Rebuild/sign/install, lancez l'app, puis collectez les logs.
3) Rebuild/sign/install, run the app, then collect logs.
Log paths (checked in order):
```
@ -92,30 +92,30 @@ Log paths (checked in order):
# If all fail: fallback to Logcat only
```
Notes et dépannage:
- L'alignement de l'ABI est obligatoire. Un désalignement déclenchera UnsatisfiedLinkError et le logger ne se chargera pas.
- Les contraintes de stockage sont courantes sur les Android modernes ; si les écritures de fichiers échouent, SoTap émettra toujours via Logcat.
- Le comportement/la verbosité est conçu·e pour être personnalisé·e ; recompilez depuis la source après avoir édité sotap.c.
- L'alignement ABI est obligatoire. Un mismatch soulèvera UnsatisfiedLinkError et le logger ne se chargera pas.
- Les contraintes de stockage sont courantes sur les Android modernes; si les écritures de fichiers échouent, SoTap émettra quand même via Logcat.
- Le comportement/la verbosité sont destinés à être personnalisés; recompilez depuis la source après avoir édité sotap.c.
Cette approche est utile pour le triage de malware et le debugging JNI lorsque l'observation des flux d'appels natifs depuis le démarrage du processus est critique mais que des hooks root/système globaux ne sont pas disponibles.
Cette approche est utile pour le triage de malware et le debugging JNI lorsque l'observation des flux d'appels natifs depuis le démarrage du process est critique mais que des hooks root/à l'échelle du système ne sont pas disponibles.
---
### Recent vulnerabilities worth hunting for in APKs
| Année | CVE | Bibliothèque affectée | Remarques |
| Year | CVE | Affected library | Notes |
|------|-----|------------------|-------|
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|Heap buffer overflow reachable from native code that decodes WebP images. Plusieurs applications Android embarquent des versions vulnérables. Lorsque vous voyez un `libwebp.so` dans un APK, vérifiez sa version et tentez une exploitation ou un correctif.| |
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|Heap buffer overflow reachable from native code that decodes WebP images. Several Android apps bundle vulnerable versions. When you see a `libwebp.so` inside an APK, check its version and attempt exploitation or patching.| |
|2024|Multiple|OpenSSL 3.x series|Several memory-safety and padding-oracle issues. Many Flutter & ReactNative bundles ship their own `libcrypto.so`.|
Lorsque vous repérez des fichiers `.so` *third-party* à l'intérieur d'un APK, vérifiez toujours leur hash par rapport aux avis upstream. SCA (Software Composition Analysis) est peu courant sur mobile, donc des builds vulnérables et obsolètes sont répandus.
Lorsque vous repérez des fichiers `.so` *third-party* à l'intérieur d'un APK, vérifiez toujours leur hash par rapport aux avis en amont. La SCA (Software Composition Analysis) est rare sur mobile, donc des builds anciens et vulnérables sont fréquents.
---
### Anti-Reversing & Hardening trends (Android 13-15)
* **Pointer Authentication (PAC) & Branch Target Identification (BTI):** Android 14 active PAC/BTI dans les bibliothèques système sur les puces ARMv8.3+ compatibles. Les décompilateurs affichent maintenant des pseudo-instructions liées à PAC ; pour l'analyse dynamique Frida injecte des trampolines *après* avoir enlevé PAC, mais vos trampolines personnalisés devraient appeler `pacda`/`autibsp` lorsque nécessaire.
* **MTE & Scudo hardened allocator:** le memory-tagging est opt-in mais beaucoup d'apps compatibles Play-Integrity sont compilées avec `-fsanitize=memtag` ; utilisez `setprop arm64.memtag.dump 1` plus `adb shell am start ...` pour capturer les tag faults.
* **LLVM Obfuscator (opaque predicates, control-flow flattening):** des packers commerciaux (e.g., Bangcle, SecNeo) protègent de plus en plus le code *native*, pas seulement Java ; attendez-vous à du control-flow bidon et des blobs de chaînes chiffrés dans `.rodata`.
* **Pointer Authentication (PAC) & Branch Target Identification (BTI):** Android 14 active PAC/BTI dans les libraries système sur les siliciums ARMv8.3+ supportés. Les décompilateurs affichent désormais des pseudo-instructions liées à PAC; pour l'analyse dynamique Frida injecte des trampolines *after* stripping PAC, mais vos trampolines personnalisés doivent appeler `pacda`/`autibsp` si nécessaire.
* **MTE & Scudo hardened allocator:** le memory-tagging est optionnel mais beaucoup d'apps compatibles Play-Integrity sont compilées avec `-fsanitize=memtag`; utilisez `setprop arm64.memtag.dump 1` plus `adb shell am start ...` pour capturer les tag faults.
* **LLVM Obfuscator (opaque predicates, control-flow flattening):** les packers commerciaux (par ex. Bangcle, SecNeo) protègent de plus en plus le code *native*, pas seulement Java; attendez-vous à du bogus control-flow et des blobs de chaînes chiffrées dans `.rodata`.
---

View File

@ -1,37 +1,37 @@
# Smali - Décompilation/[Modification]/Recompilation
# Smali — Décompilation/[Modification]/Compilation
{{#include ../../banners/hacktricks-training.md}}
Parfois il est intéressant de modifier le code de l'application pour accéder à des informations cachées pour vous (peutêtre des mots de passe fortement obfusqués ou des flags). Dans ce cas, il peut être utile de décompiler l'apk, modifier le code et le recompiler.
Parfois, il est intéressant de modifier le code de l'application pour accéder à des informations cachées pour vous (par exemple des mots de passe fortement obfusqués ou des flags). Dans ce cas, il peut être utile de décompiler l'apk, modifier le code et recompiler.
**Référence des opcodes :** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
## Méthode rapide
En utilisant **Visual Studio Code** et l'extension [APKLab](https://github.com/APKLab/APKLab), vous pouvez **décompiler automatiquement**, modifier, **recompiler**, signer et installer l'application sans exécuter de commande.
En utilisant **Visual Studio Code** et l'extension [APKLab](https://github.com/APKLab/APKLab), vous pouvez **décompiler automatiquement**, modifier, **recompiler**, signer et installer l'application sans exécuter la moindre commande.
Un autre **script** qui facilite grandement cette tâche est [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)
## Décompiler l'APK
Avec APKTool vous pouvez accéder au **smali code et aux resources** :
En utilisant APKTool vous pouvez accéder au **smali code and resources**:
```bash
apktool d APP.apk
```
Si **apktool** vous donne une erreur, essayez[ installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)
Si **apktool** vous renvoie une erreur, essayez [installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)
Some **interesting files you should look are**:
- _res/values/strings.xml_ (et tous les xml à l'intérieur de res/values/*)
- _res/values/strings.xml_ (and all xmls inside res/values/*)
- _AndroidManifest.xml_
- Any file with extension _.sqlite_ or _.db_
If `apktool` has **problems decoding the application** take a look to [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) or try using the argument **`-r`** (Ne pas décoder les ressources).
If `apktool` has **problems decoding the application** take a look to [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) or try using the argument **`-r`** (Do not decode resources). Then, if the problem was in a resource and not in the source code, you won't have the problem (you won't also decompile the resources).
## Modifier le code smali
Vous pouvez **modifier** les **instructions**, changer la **valeur** de certaines variables ou **ajouter** de nouvelles instructions. Je modifie le code Smali en utilisant [**VS Code**](https://code.visualstudio.com), installez ensuite l'**extension smalise** et l'éditeur vous indiquera si une **instruction est incorrecte**.\
Vous pouvez **modifier** des **instructions**, changer la **valeur** de certaines variables ou **ajouter** de nouvelles instructions. Je modifie le code Smali en utilisant [**VS Code**](https://code.visualstudio.com), you then install the **smalise extension** and the editor will tell you if any **instruction is incorrect**.\
Some **examples** can be found here:
- [Smali changes examples](smali-changes.md)
@ -45,13 +45,13 @@ Après avoir modifié le code, vous pouvez **recompiler** le code en utilisant:
```bash
apktool b . #In the folder generated when you decompiled the application
```
Cela va **compiler** le nouvel APK **dans** le dossier _**dist**_.
Il va **compiler** le nouvel APK **dans** le dossier _**dist**_.
Si **apktool** renvoie une **erreur**, essayez [d'installer la **dernière version**](https://ibotpeaches.github.io/Apktool/install/)
Si **apktool** génère une **erreur**, try[ installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)
### **Signer le nouvel APK**
Ensuite, vous devez **générer une clé** (on vous demandera un mot de passe et quelques informations que vous pouvez remplir aléatoirement) :
Ensuite, vous devez **générer une clé** (il vous sera demandé un mot de passe et quelques informations que vous pouvez remplir aléatoirement) :
```bash
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
```
@ -61,18 +61,18 @@ jarsigner -keystore key.jks path/to/dist/* <your-alias>
```
### Optimiser la nouvelle application
**zipalign** est un outil d'alignement d'archives qui apporte une optimisation importante aux fichiers d'application Android (APK). [Plus d'informations ici](https://developer.android.com/studio/command-line/zipalign).
**zipalign** est un outil d'alignement d'archives qui apporte une optimisation importante aux fichiers d'application Android (APK). [More information here](https://developer.android.com/studio/command-line/zipalign).
```bash
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
zipalign -v 4 infile.apk
```
### **Signer le nouvel APK (encore ?)**
Si vous **préférez** utiliser [**apksigner**](https://developer.android.com/studio/command-line/) au lieu de jarsigner, **vous devriez signer l'apk** après avoir appliqué **l'optimisation avec** zipaling. MAIS REMARQUEZ QUE VOUS N'AVEZ QU'À **SIGNER L'APPLICATION UNE SEULE FOIS** AVEC jarsigner (avant zipalign) OU AVEC aspsigner (après zipaling).
Si vous **préférez** utiliser [**apksigner**](https://developer.android.com/studio/command-line/) au lieu de jarsigner, **vous devez signer l'apk** après avoir appliqué **l'optimisation avec** zipaling. MAIS REMARQUEZ QUE VOUS N'AVEZ À **SIGNER L'APPLICATION QU'UNE FOIS** AVEC jarsigner (avant zipalign) OU AVEC aspsigner (après zipaling).
```bash
apksigner sign --ks key.jks ./dist/mycompiled.apk
```
## Modifier Smali
## Modification de Smali
Pour le code Java Hello World suivant :
```java
@ -80,7 +80,7 @@ public static void printHelloWorld() {
System.out.println("Hello World")
}
```
Le code Smali serait :
Le code Smali serait:
```java
.method public static printHelloWorld()V
.registers 2
@ -90,13 +90,13 @@ invoke-virtual {v0,v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method
```
Le jeu d'instructions Smali est disponible [here](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions).
L'ensemble d'instructions Smali est disponible [ici](https://source.android.com/devices/tech/dalvik/dalvik-bytecode#instructions).
### Modifications légères
### Modifier les valeurs initiales d'une variable dans une fonction
Certaines variables sont définies au début de la fonction en utilisant l'opcode _const_; vous pouvez modifier leurs valeurs, ou en définir de nouvelles :
Certaines variables sont définies au début de la fonction en utilisant l'opcode _const_. Vous pouvez modifier leurs valeurs, ou en définir de nouvelles :
```bash
#Number
const v9, 0xf4240
@ -127,7 +127,7 @@ iput v0, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Save v0 inside
if-ne v0, v9, :goto_6 #If not equals, go to: :goto_6
goto :goto_6 #Always go to: :goto_6
```
### Modifications majeures
### Changements majeurs
### Journalisation
```bash
@ -138,19 +138,19 @@ move-result-object v1 #Move to v1
const-string v5, "wins" #Save "win" inside v5
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"
```
Recommandations :
Recommendations:
- Si vous allez utiliser des variables déclarées à l'intérieur de la fonction (déclarées v0,v1,v2...) placez ces lignes entre le _.local <number>_ et les déclarations des variables (_const v0, 0x1_)
- Si vous voulez insérer le logging code au milieu du code d'une fonction :
- Si vous allez utiliser des variables déclarées à l'intérieur de la fonction (déclarées v0, v1, v2...) placez ces lignes entre le _.local <number>_ et les déclarations des variables (_const v0, 0x1_)
- Si vous voulez insérer le code de logging au milieu du code d'une fonction :
- Ajoutez 2 au nombre de variables déclarées : Ex : de _.locals 10_ à _.locals 12_
- Les nouvelles variables doivent utiliser les numéros suivants des variables déjà déclarées (dans cet exemple elles doivent être _v10_ et _v11_, souvenez-vous que la numérotation commence à v0).
- Modifiez le code de la fonction de logging et utilisez _v10_ et _v11_ à la place de _v5_ et _v1_.
- Les nouvelles variables doivent être les numéros suivants des variables déjà déclarées (dans cet exemple il devrait s'agir de _v10_ et _v11_, souvenez-vous que ça commence en v0).
- Modifiez le code de la fonction de logging et utilisez _v10_ et _v11_ au lieu de _v5_ et _v1_.
### Toasting
N'oubliez pas d'ajouter 3 au nombre de _.locals_ au début de la fonction.
Ce code est prêt à être inséré dans le **milieu d'une fonction** (**changez** le nombre des **variables** si nécessaire). Il prendra la **valeur de this.o**, la **transformera** en **String** et ensuite **fera** un **toast** avec sa valeur.
Ce code est prêt à être inséré au **milieu d'une fonction** (**changez** le nombre des **variables** si nécessaire). Il prendra la **valeur de this.o**, la **transformera** en **String** puis affichera un **toast** avec sa valeur.
```bash
const/4 v10, 0x1
const/4 v11, 0x1
@ -164,7 +164,7 @@ invoke-virtual {v12}, Landroid/widget/Toast;->show()V
```
### Chargement d'une bibliothèque native au démarrage (System.loadLibrary)
Parfois vous devez précharger une bibliothèque native afin qu'elle s'initialise avant les autres libs JNI (p. ex. pour activer la télémétrie/journalisation locale du processus). Vous pouvez injecter un appel à System.loadLibrary() dans un initialiseur statique ou tôt dans Application.onCreate(). Exemple smali pour un initialiseur de classe statique (<clinit>):
Parfois, il est nécessaire de précharger une bibliothèque native afin qu'elle s'initialise avant d'autres libs JNI (par ex., pour activer la télémétrie/logging locale du processus). Vous pouvez injecter un appel à System.loadLibrary() dans un static initializer ou tôt dans Application.onCreate(). Exemple smali pour un static class initializer (<clinit>):
```smali
.class public Lcom/example/App;
.super Landroid/app/Application;
@ -176,7 +176,7 @@ invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
return-void
.end method
```
Alternativement, placez les mêmes deux instructions au début de votre Application.onCreate() pour garantir que la bibliothèque se charge le plus tôt possible :
Sinon, placez les mêmes deux instructions au début de votre Application.onCreate() pour vous assurer que la bibliothèque se charge le plus tôt possible :
```smali
.method public onCreate()V
.locals 1
@ -189,11 +189,11 @@ return-void
.end method
```
Remarques :
- Assurez-vous que la variante ABI correcte de la bibliothèque existe sous lib/<abi>/ (par ex., arm64-v8a/armeabi-v7a) pour éviter UnsatisfiedLinkError.
- Le chargement très tôt (initialiseur statique de classe) garantit que le logger natif peut observer l'activité JNI ultérieure.
- Assurez-vous que la variante ABI correcte de la bibliothèque existe sous lib/<abi>/ (par ex., arm64-v8a/armeabi-v7a) afin d'éviter UnsatisfiedLinkError.
- Le chargement très précoce (class static initializer) garantit que le native logger peut observer l'activité JNI ultérieure.
## Références
- SoTap : logger léger in-app du comportement JNI (.so) [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
- SoTap : enregistreur léger in-app du comportement JNI (.so) [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
{{#include ../../banners/hacktricks-training.md}}