mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-17 06:28:27 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/mac
This commit is contained in:
parent
99949789a8
commit
dfa4f1e847
3 changed files with 81 additions and 57 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||||
|
||||
* Vous travaillez dans une **entreprise de cybersécurité** ? Vous souhaitez voir votre **entreprise annoncée dans HackTricks** ? ou vous souhaitez avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
|
||||
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
|
||||
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
|
||||
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||||
|
@ -13,65 +13,75 @@
|
|||
</details>
|
||||
|
||||
{% hint style="danger" %}
|
||||
Le code de **dyld est open source** et peut être trouvé dans [https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/) et peut être téléchargé sous forme de tar en utilisant une **URL telle que** [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)
|
||||
Le code de **dyld est open source** et peut être trouvé sur [https://opensource.apple.com/source/dyld/](https://opensource.apple.com/source/dyld/) et peut être téléchargé sous forme de tar en utilisant une **URL telle que** [https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)
|
||||
{% endhint %}
|
||||
|
||||
## **DYLD\_INSERT\_LIBRARIES**
|
||||
|
||||
> Ceci est une liste de bibliothèques dynamiques séparées par des deux-points à charger avant celles spécifiées dans le programme. Cela vous permet de tester de nouveaux modules de bibliothèques partagées dynamiques existantes utilisées dans des images de l'espace de noms plat en chargeant une bibliothèque partagée dynamique temporaire avec seulement les nouveaux modules. Notez que cela n'a aucun effet sur les images construites avec un espace de noms à deux niveaux utilisant une bibliothèque partagée dynamique, à moins que DYLD\_FORCE\_FLAT\_NAMESPACE ne soit également utilisé.
|
||||
> Ceci est une liste de bibliothèques dynamiques séparées par des deux-points à charger avant celles spécifiées dans le programme. Cela vous permet de tester de nouveaux modules de bibliothèques partagées dynamiques existantes utilisées dans des images de l'espace de noms plat en chargeant une bibliothèque partagée dynamique temporaire contenant uniquement les nouveaux modules. Notez que cela n'a aucun effet sur les images construites avec un espace de noms à deux niveaux utilisant une bibliothèque partagée dynamique, sauf si DYLD\_FORCE\_FLAT\_NAMESPACE est également utilisé.
|
||||
|
||||
C'est comme le [**LD\_PRELOAD sur Linux**](../../../../linux-hardening/privilege-escalation#ld\_preload).
|
||||
|
||||
Cette technique peut également être **utilisée comme technique ASEP** car chaque application installée a un fichier plist appelé "Info.plist" qui permet **d'assigner des variables d'environnement** en utilisant une clé appelée `LSEnvironmental`.
|
||||
Cette technique peut également être **utilisée comme technique ASEP** car chaque application installée a un fichier plist appelé "Info.plist" qui permet l'**attribution de variables d'environnement** en utilisant une clé appelée `LSEnvironmental`.
|
||||
|
||||
{% hint style="info" %}
|
||||
Depuis 2012, **Apple a considérablement réduit la puissance** de **`DYLD_INSERT_LIBRARIES`**.
|
||||
|
||||
Allez dans le code et **vérifiez `src/dyld.cpp`**. Dans la fonction **`pruneEnvironmentVariables`**, vous pouvez voir que les variables **`DYLD_*`** sont supprimées.
|
||||
|
||||
Dans la fonction **`processRestricted`**, la raison de la restriction est définie. En vérifiant ce code, vous pouvez voir que les raisons sont les suivantes :
|
||||
Dans la fonction **`processRestricted`**, la raison de la restriction est définie. En vérifiant ce code, vous pouvez voir que les raisons sont :
|
||||
|
||||
* Le binaire est `setuid/setgid`
|
||||
* Existence de la section `__RESTRICT/__restrict` dans le binaire macho.
|
||||
* Le logiciel a des attributs (runtime renforcé) sans l'attribut [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables) ou [`com.apple.security.cs.disable-library-validation`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_disable-library-validation)`/` [`com.apple.private.security.clear-library-validation`](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/).
|
||||
* Le logiciel a des attributs (runtime renforcé) sans l'attribut [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com\_apple\_security\_cs\_allow-dyld-environment-variables)
|
||||
* Vérifiez les **attributs** d'un binaire avec : `codesign -dv --entitlements :- </path/to/bin>`
|
||||
* Si la bibliothèque est signée avec un certificat différent du binaire
|
||||
* Si la bibliothèque et le binaire sont signés avec le même certificat, cela contournera les restrictions précédentes
|
||||
* Les programmes avec les attributs **`system.install.apple-software`** et **`system.install.apple-software.standar-user`** peuvent **installer des logiciels** signés par Apple sans demander à l'utilisateur un mot de passe (élévation de privilèges)
|
||||
|
||||
Dans les versions plus récentes, vous pouvez trouver cette logique dans la deuxième partie de la fonction **`configureProcessRestrictions`**. Cependant, ce qui est exécuté dans les versions plus récentes, ce sont les **vérifications initiales de la fonction** (vous pouvez supprimer les ifs liés à iOS ou à la simulation car ils ne seront pas utilisés dans macOS.
|
||||
Dans les versions plus récentes, vous pouvez trouver cette logique dans la deuxième partie de la fonction **`configureProcessRestrictions`.** Cependant, ce qui est exécuté dans les versions plus récentes, ce sont les **vérifications initiales de la fonction** (vous pouvez supprimer les ifs liés à iOS ou à la simulation car ils ne seront pas utilisés dans macOS.
|
||||
{% endhint %}
|
||||
|
||||
Vous pouvez vérifier si un binaire a **un runtime renforcé** avec `codesign --display --verbose <bin>` en vérifiant le drapeau runtime dans **`CodeDirectory`** comme : **`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
|
||||
### Validation de la bibliothèque
|
||||
|
||||
Trouvez un exemple de (détournement) utilisation de cette technique et vérifiez les restrictions dans :
|
||||
Même si le binaire permet d'utiliser la variable d'environnement **`DYLD_INSERT_LIBRARIES`**, si le binaire vérifie la signature de la bibliothèque à charger, il ne chargera pas une bibliothèque personnalisée.
|
||||
|
||||
Pour charger une bibliothèque personnalisée, le binaire doit avoir **l'un des attributs suivants** :
|
||||
|
||||
*  [`com.apple.security.cs.disable-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.security.cs.disable-library-validation)
|
||||
* [`com.apple.private.security.clear-library-validation`](../../macos-security-protections/macos-dangerous-entitlements.md#com.apple.private.security.clear-library-validation)
|
||||
|
||||
ou le binaire **ne doit pas** avoir le **flag runtime renforcé** ou le **flag de validation de la bibliothèque**.
|
||||
|
||||
Vous pouvez vérifier si un binaire a le **runtime renforcé** avec `codesign --display --verbose <bin>` en vérifiant le flag runtime dans **`CodeDirectory`** comme : **`CodeDirectory v=20500 size=767 flags=0x10000(runtime) hashes=13+7 location=embedded`**
|
||||
|
||||
Vous pouvez également charger une bibliothèque si elle est **signée avec le même certificat que le binaire**.
|
||||
|
||||
Trouvez un exemple sur la façon d'utiliser (abuser) cela et vérifiez les restrictions dans :
|
||||
|
||||
{% content-ref url="../../macos-dyld-hijacking-and-dyld_insert_libraries.md" %}
|
||||
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](../../macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Détournement de Dylib
|
||||
## Dylib Hijacking
|
||||
|
||||
{% hint style="danger" %}
|
||||
N'oubliez pas que les **restrictions précédentes s'appliquent également** pour effectuer des attaques de détournement de Dylib.
|
||||
N'oubliez pas que les restrictions de **Validation de bibliothèque précédentes s'appliquent également** pour effectuer des attaques de détournement de dylib.
|
||||
{% endhint %}
|
||||
|
||||
Comme sous Windows, sous MacOS, vous pouvez également **détourner les dylibs** pour faire exécuter du **code arbitraire** par des **applications**.\
|
||||
Cependant, la façon dont les applications **MacOS** chargent les bibliothèques est **plus restreinte** que sous Windows. Cela implique que les développeurs de logiciels malveillants peuvent toujours utiliser cette technique pour **se camoufler**, mais la probabilité de pouvoir **abuser de cela pour escalader les privilèges est beaucoup plus faible**.
|
||||
Comme dans Windows, sur MacOS, vous pouvez également **détourner les dylibs** pour faire **exécuter du code arbitraire** par les **applications**.\
|
||||
Cependant, la façon dont les applications **MacOS** chargent les bibliothèques est **plus restreinte** que sur Windows. Cela implique que les développeurs de logiciels malveillants peuvent toujours utiliser cette technique pour **se camoufler**, mais la probabilité de pouvoir **abuser de cela pour escalader les privilèges est beaucoup plus faible**.
|
||||
|
||||
Tout d'abord, il est **plus courant** de trouver que les **binaires MacOS indiquent le chemin complet** des bibliothèques à charger. Et deuxièmement, **MacOS ne recherche jamais** dans les dossiers du **$PATH** les bibliothèques.
|
||||
Tout d'abord, il est **plus courant** de trouver que les **binaires MacOS indiquent le chemin complet** des bibliothèques à charger. Et deuxièmement, **MacOS ne recherche jamais** dans les dossiers du **$PATH** pour les bibliothèques.
|
||||
|
||||
La **partie principale** du **code** liée à cette fonctionnalité se trouve dans **`ImageLoader::recursiveLoadLibraries`** dans `ImageLoader.cpp`.
|
||||
|
||||
Il existe **4 commandes d'en-tête différentes** qu'un binaire macho peut utiliser pour charger des bibliothèques :
|
||||
|
||||
* La commande **`LC_LOAD_DYLIB`** est la commande courante pour charger une dylib.
|
||||
* La commande **`LC_LOAD_WEAK_DYLIB`** fonctionne comme la précédente, mais si la dylib n'est pas trouvée, l'exécution se poursuit sans aucune erreur.
|
||||
* La commande **`LC_LOAD_DYLIB`** est la commande courante pour charger un dylib.
|
||||
* La commande **`LC_LOAD_WEAK_DYLIB`** fonctionne comme la précédente, mais si le dylib n'est pas trouvé, l'exécution se poursuit sans aucune erreur.
|
||||
* La commande **`LC_REEXPORT_DYLIB`** permet de faire proxy (ou réexporter) les symboles d'une bibliothèque différente.
|
||||
* La commande **`LC_LOAD_UPWARD_DYLIB`** est utilisée lorsque deux bibliothèques dépendent l'une de l'autre (on parle de _dépendance ascendante_).
|
||||
* La commande **`LC_LOAD_UPWARD_DYLIB`** est utilisée lorsque deux bibliothèques dépendent l'une de l'autre (on parle de dépendance ascendante).
|
||||
|
||||
Cependant, il existe **2 types de détournement de dylib** :
|
||||
* **Bibliothèques liées faibles manquantes**: Cela signifie que l'application essaiera de charger une bibliothèque qui n'existe pas configurée avec **LC\_LOAD\_WEAK\_DYLIB**. Ensuite, **si un attaquant place un dylib là où il est attendu, il sera chargé**.
|
||||
|
||||
* **Bibliothèques liées faibles manquantes** : Cela signifie que l'application va essayer de charger une bibliothèque qui n'existe pas, configurée avec **LC\_LOAD\_WEAK\_DYLIB**. Ensuite, **si un attaquant place un dylib là où il est attendu, il sera chargé**.
|
||||
* Le fait que le lien soit "faible" signifie que l'application continuera de s'exécuter même si la bibliothèque n'est pas trouvée.
|
||||
* Le **code associé** à cela se trouve dans la fonction `ImageLoaderMachO::doGetDependentLibraries` de `ImageLoaderMachO.cpp`, où `lib->required` est seulement `false` lorsque `LC_LOAD_WEAK_DYLIB` est vrai.
|
||||
* **Trouver des bibliothèques liées faibles** dans les binaires avec (vous avez ensuite un exemple de création de bibliothèques de détournement) :
|
||||
|
@ -83,10 +93,10 @@ time stamp 2 Wed Jun 21 12:23:31 1969
|
|||
current version 1.0.0
|
||||
compatibility version 1.0.0
|
||||
```
|
||||
* **Configuré avec @rpath**: Les binaires Mach-O peuvent avoir les commandes **`LC_RPATH`** et **`LC_LOAD_DYLIB`**. En fonction des **valeurs** de ces commandes, des **bibliothèques** vont être **chargées** à partir de **différents répertoires**.
|
||||
* **Configuré avec @rpath** : Les binaires Mach-O peuvent avoir les commandes **`LC_RPATH`** et **`LC_LOAD_DYLIB`**. En fonction des **valeurs** de ces commandes, les **bibliothèques** vont être **chargées** à partir de **différents répertoires**.
|
||||
* **`LC_RPATH`** contient les chemins de certains dossiers utilisés pour charger les bibliothèques par le binaire.
|
||||
* **`LC_LOAD_DYLIB`** contient le chemin des bibliothèques spécifiques à charger. Ces chemins peuvent contenir **`@rpath`**, qui sera **remplacé** par les valeurs dans **`LC_RPATH`**. Si plusieurs chemins sont présents dans **`LC_RPATH`**, chacun sera utilisé pour rechercher la bibliothèque à charger. Exemple :
|
||||
* Si **`LC_LOAD_DYLIB`** contient `@rpath/library.dylib` et **`LC_RPATH`** contient `/application/app.app/Contents/Framework/v1/` et `/application/app.app/Contents/Framework/v2/`. Les deux dossiers seront utilisés pour charger `library.dylib`**.** Si la bibliothèque n'existe pas dans `[...]/v1/`, un attaquant pourrait la placer là pour détourner le chargement de la bibliothèque dans `[...]/v2/` car l'ordre des chemins dans **`LC_LOAD_DYLIB`** est suivi.
|
||||
* **`LC_LOAD_DYLIB`** contient le chemin des bibliothèques spécifiques à charger. Ces chemins peuvent contenir **`@rpath`**, qui sera **remplacé** par les valeurs dans **`LC_RPATH`**. S'il y a plusieurs chemins dans **`LC_RPATH`**, chacun sera utilisé pour rechercher la bibliothèque à charger. Exemple :
|
||||
* Si **`LC_LOAD_DYLIB`** contient `@rpath/library.dylib` et **`LC_RPATH`** contient `/application/app.app/Contents/Framework/v1/` et `/application/app.app/Contents/Framework/v2/`. Les deux dossiers vont être utilisés pour charger `library.dylib`**.** Si la bibliothèque n'existe pas dans `[...]/v1/` et que l'attaquant peut la placer là pour détourner le chargement de la bibliothèque dans `[...]/v2/`, car l'ordre des chemins dans **`LC_LOAD_DYLIB`** est suivi.
|
||||
* **Trouver les chemins rpath et les bibliothèques** dans les binaires avec : `otool -l </chemin/vers/binaire> | grep -E "LC_RPATH|LC_LOAD_DYLIB" -A 5`
|
||||
|
||||
{% hint style="info" %}
|
||||
|
@ -95,14 +105,14 @@ compatibility version 1.0.0
|
|||
**`@loader_path`** : Est le **chemin** vers le **répertoire** contenant le **binaire Mach-O** qui contient la commande de chargement.
|
||||
|
||||
* Lorsqu'il est utilisé dans un exécutable, **`@loader_path`** est effectivement le **même** que **`@executable_path`**.
|
||||
* Lorsqu'il est utilisé dans une **dylib**, **`@loader_path`** donne le **chemin** vers la **dylib**.
|
||||
* Lorsqu'il est utilisé dans un **dylib**, **`@loader_path`** donne le **chemin** vers le **dylib**.
|
||||
{% endhint %}
|
||||
|
||||
La façon de **escalader les privilèges** en abusant de cette fonctionnalité serait dans le cas rare où une **application** exécutée **par** **root** recherche une **bibliothèque dans un dossier où l'attaquant a des permissions d'écriture**.
|
||||
La façon d'**escalader les privilèges** en abusant de cette fonctionnalité serait dans le cas rare où une **application** exécutée **par** **root** recherche une **bibliothèque** dans un **dossier** où l'attaquant a des **permissions d'écriture**.
|
||||
|
||||
{% hint style="success" %}
|
||||
Un bon **scanner** pour trouver des **bibliothèques manquantes** dans les applications est [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) ou une [**version CLI**](https://github.com/pandazheng/DylibHijack).\
|
||||
Un bon **rapport avec des détails techniques** sur cette technique peut être trouvé [**ici**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x).
|
||||
Un **scanner** pratique pour trouver des **bibliothèques manquantes** dans les applications est [**Dylib Hijack Scanner**](https://objective-see.com/products/dhs.html) ou une [**version CLI**](https://github.com/pandazheng/DylibHijack).\
|
||||
Un **rapport avec des détails techniques** intéressants sur cette technique peut être trouvé [**ici**](https://www.virusbulletin.com/virusbulletin/2015/03/dylib-hijacking-os-x).
|
||||
{% endhint %}
|
||||
|
||||
**Exemple**
|
||||
|
@ -111,11 +121,15 @@ Un bon **rapport avec des détails techniques** sur cette technique peut être t
|
|||
[macos-dyld-hijacking-and-dyld\_insert\_libraries.md](../../macos-dyld-hijacking-and-dyld\_insert\_libraries.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Détournement de Dlopen
|
||||
## Dlopen Hijacking
|
||||
|
||||
{% hint style="danger" %}
|
||||
N'oubliez pas que les restrictions de **Validation de bibliothèque précédentes s'appliquent également** pour effectuer des attaques de détournement de Dlopen.
|
||||
{% endhint %}
|
||||
|
||||
D'après **`man dlopen`** :
|
||||
|
||||
* Lorsque le chemin **ne contient pas de caractère slash** (c'est-à-dire qu'il s'agit simplement d'un nom de feuille), **dlopen() effectuera une recherche**. Si **`$DYLD_LIBRARY_PATH`** était défini au lancement, dyld cherchera d'abord dans ce répertoire. Ensuite, si le fichier mach-o appelant ou l'exécutable principal spécifie un **`LC_RPATH`**, alors dyld cherchera dans ces répertoires. Ensuite, si le processus est **non restreint**, dyld recherchera dans le **répertoire de travail actuel**. Enfin, pour les anciens binaires, dyld essaiera quelques solutions de repli. Si **`$DYLD_FALLBACK_LIBRARY_PATH`** était défini au lancement, dyld cherchera dans ces répertoires, sinon, dyld cherchera dans **`/usr/local/lib/`** (si le processus est non restreint), puis dans **`/usr/lib/`** (ces informations ont été prises à partir de **`man dlopen`**).
|
||||
* Lorsque le chemin **ne contient pas de caractère slash** (c'est-à-dire qu'il s'agit simplement d'un nom de feuille), **dlopen() effectuera une recherche**. Si **`$DYLD_LIBRARY_PATH`** était défini au lancement, dyld cherchera d'abord dans ce répertoire. Ensuite, si le fichier mach-o appelant ou l'exécutable principal spécifie un **`LC_RPATH`**, alors dyld cherchera dans ces répertoires. Ensuite, si le processus est **non restreint**, dyld recherchera dans le **répertoire de travail actuel**. Enfin, pour les anciens binaires, dyld essaiera quelques solutions de repli. Si **`$DYLD_FALLBACK_LIBRARY_PATH`** était défini au lancement, dyld cherchera dans **ces répertoires**, sinon, dyld cherchera dans **`/usr/local/lib/`** (si le processus est non restreint), puis dans **`/usr/lib/`** (ces informations ont été extraites de **`man dlopen`**).
|
||||
1. `$DYLD_LIBRARY_PATH`
|
||||
2. `LC_RPATH`
|
||||
3. `CWD` (si non restreint)
|
||||
|
@ -127,42 +141,42 @@ D'après **`man dlopen`** :
|
|||
S'il n'y a pas de slash dans le nom, il y aurait 2 façons de faire un détournement :
|
||||
|
||||
* Si un **`LC_RPATH`** est **modifiable** (mais la signature est vérifiée, donc pour cela, vous avez également besoin que le binaire soit non restreint)
|
||||
* Si le binaire est **non restreint**, il est alors possible de charger quelque chose depuis le CWD (ou en abusant des variables d'environnement mentionnées)
|
||||
* Si le binaire est **non restreint**, il est alors possible de charger quelque chose depuis le CWD (ou en abusant de l'une des variables d'environnement mentionnées)
|
||||
{% endhint %}
|
||||
|
||||
* Lorsque le chemin **ressemble à un chemin de framework** (par exemple `/stuff/foo.framework/foo`), si **`$DYLD_FRAMEWORK_PATH`** était défini au lancement, dyld cherchera d'abord dans ce répertoire pour le **chemin partiel du framework** (par exemple `foo.framework/foo`). Ensuite, dyld essaiera le **chemin fourni tel quel** (en utilisant le répertoire de travail actuel pour les chemins relatifs). Enfin, pour les anciens binaires, dyld essaiera quelques solutions de repli. Si **`$DYLD_FALLBACK_FRAMEWORK_PATH`** était défini au lancement, dyld cherchera dans ces répertoires. Sinon, il cherchera dans **`/Library/Frameworks`** (sur macOS si le processus est non restreint), puis dans **`/System/Library/Frameworks`**.
|
||||
* Lorsque le chemin ressemble à un chemin de framework (par exemple, `/stuff/foo.framework/foo`), si `$DYLD_FRAMEWORK_PATH` a été défini au lancement, dyld cherchera d'abord dans ce répertoire le chemin partiel du framework (par exemple, `foo.framework/foo`). Ensuite, dyld essaiera le chemin fourni tel quel (en utilisant le répertoire de travail actuel pour les chemins relatifs). Enfin, pour les anciens binaires, dyld essaiera quelques solutions de repli. Si `$DYLD_FALLBACK_FRAMEWORK_PATH` a été défini au lancement, dyld recherchera dans ces répertoires. Sinon, il recherchera dans `/Library/Frameworks` (sur macOS si le processus n'est pas restreint), puis dans `/System/Library/Frameworks`.
|
||||
1. `$DYLD_FRAMEWORK_PATH`
|
||||
2. chemin fourni (en utilisant le répertoire de travail actuel pour les chemins relatifs si non restreint)
|
||||
2. chemin fourni (en utilisant le répertoire de travail actuel pour les chemins relatifs si le processus n'est pas restreint)
|
||||
3. `$DYLD_FALLBACK_FRAMEWORK_PATH`
|
||||
4. `/Library/Frameworks` (si non restreint)
|
||||
4. `/Library/Frameworks` (si le processus n'est pas restreint)
|
||||
5. `/System/Library/Frameworks`
|
||||
|
||||
{% hint style="danger" %}
|
||||
S'il s'agit d'un chemin de framework, la façon de le détourner serait :
|
||||
Si le chemin est un chemin de framework, la façon de le pirater serait :
|
||||
|
||||
* Si le processus est **non restreint**, en abusant du **chemin relatif depuis le CWD** et des variables d'environnement mentionnées (même si cela n'est pas précisé dans la documentation, si le processus est restreint, les variables d'environnement DYLD\_\* sont supprimées)
|
||||
* Si le processus n'est pas restreint, en abusant du chemin relatif à partir du CWD et des variables d'environnement mentionnées (même si les documents ne précisent pas si le processus est restreint, les variables d'environnement DYLD\_\* sont supprimées)
|
||||
{% endhint %}
|
||||
|
||||
* Lorsque le chemin **contient un slash mais n'est pas un chemin de framework** (c'est-à-dire un chemin complet ou un chemin partiel vers une dylib), dlopen() recherche d'abord (si défini) dans **`$DYLD_LIBRARY_PATH`** (avec la partie feuille du chemin). Ensuite, dyld **essaie le chemin fourni** (en utilisant le répertoire de travail actuel pour les chemins relatifs (mais seulement pour les processus non restreints)). Enfin, pour les anciens binaires, dyld essaiera des solutions de repli. Si **`$DYLD_FALLBACK_LIBRARY_PATH`** était défini au lancement, dyld cherchera dans ces répertoires, sinon, dyld cherchera dans **`/usr/local/lib/`** (si le processus est non restreint), puis dans **`/usr/lib/
|
||||
2. chemin fourni (utilisation du répertoire de travail actuel pour les chemins relatifs si non restreint)
|
||||
* Lorsque le chemin contient un slash mais n'est pas un chemin de framework (c'est-à-dire un chemin complet ou un chemin partiel vers une dylib), dlopen() cherche d'abord (si défini) dans `$DYLD_LIBRARY_PATH` (avec la partie terminale du chemin). Ensuite, dyld essaie le chemin fourni (en utilisant le répertoire de travail actuel pour les chemins relatifs, mais uniquement pour les processus non restreints). Enfin, pour les anciens binaires, dyld essaiera des solutions de repli. Si `$DYLD_FALLBACK_LIBRARY_PATH` a été défini au lancement, dyld recherchera dans ces répertoires, sinon, dyld cherchera dans `/usr/local/lib/` (si le processus n'est pas restreint), puis dans `/usr/lib/`.
|
||||
1. `$DYLD_LIBRARY_PATH`
|
||||
2. chemin fourni (en utilisant le répertoire de travail actuel pour les chemins relatifs si le processus n'est pas restreint)
|
||||
3. `$DYLD_FALLBACK_LIBRARY_PATH`
|
||||
4. `/usr/local/lib/` (si non restreint)
|
||||
4. `/usr/local/lib/` (si le processus n'est pas restreint)
|
||||
5. `/usr/lib/`
|
||||
|
||||
{% hint style="danger" %}
|
||||
Si les barres obliques sont présentes dans le nom et qu'il ne s'agit pas d'un framework, la façon de le pirater serait la suivante :
|
||||
Si le nom contient des slashes et n'est pas un framework, la façon de le pirater serait :
|
||||
|
||||
* Si le binaire est **non restreint**, il est possible de charger quelque chose à partir du CWD ou de `/usr/local/lib` (ou en abusant l'une des variables d'environnement mentionnées)
|
||||
* Si le binaire n'est pas restreint, il est possible de charger quelque chose à partir du CWD ou de `/usr/local/lib` (ou d'abuser de l'une des variables d'environnement mentionnées)
|
||||
{% endhint %}
|
||||
|
||||
{% hint style="info" %}
|
||||
Remarque : Il n'y a **aucun** fichier de configuration pour **contrôler la recherche de dlopen**.
|
||||
|
||||
Remarque : Si l'exécutable principal est un binaire **set\[ug]id ou signé avec des entitlements**, alors **toutes les variables d'environnement sont ignorées**, et seul un chemin complet peut être utilisé ([vérifier les restrictions de DYLD\_INSERT\_LIBRARIES](../../macos-dyld-hijacking-and-dyld\_insert\_libraries.md#check-dyld\_insert\_librery-restrictions) pour plus d'informations détaillées)
|
||||
Remarque : Si l'exécutable principal est un binaire **set\[ug]id ou signé avec des entitlements**, alors **toutes les variables d'environnement sont ignorées**, et seul un chemin complet peut être utilisé (consultez les restrictions de DYLD\_INSERT\_LIBRARIES pour plus d'informations détaillées)
|
||||
|
||||
Remarque : Les plates-formes Apple utilisent des fichiers "universels" pour combiner les bibliothèques 32 bits et 64 bits. Cela signifie qu'il n'y a **pas de chemins de recherche séparés pour les bibliothèques 32 bits et 64 bits**.
|
||||
|
||||
Remarque : Sur les plates-formes Apple, la plupart des dylibs du système sont **combinées dans le cache dyld** et n'existent pas sur le disque. Par conséquent, l'appel à **`stat()`** pour pré-vérifier si une dylib du système existe **ne fonctionnera pas**. Cependant, **`dlopen_preflight()`** utilise les mêmes étapes que **`dlopen()`** pour trouver un fichier mach-o compatible.
|
||||
Remarque : Sur les plates-formes Apple, la plupart des dylibs du système d'exploitation sont **combinées dans le cache dyld** et n'existent pas sur le disque. Par conséquent, l'appel à **`stat()`** pour vérifier si une dylib du système d'exploitation existe **ne fonctionnera pas**. Cependant, **`dlopen_preflight()`** utilise les mêmes étapes que **`dlopen()`** pour trouver un fichier mach-o compatible.
|
||||
{% endhint %}
|
||||
|
||||
**Vérifier les chemins**
|
||||
|
@ -261,7 +275,7 @@ Ce qui signifie essentiellement que si le binaire est **suid** ou **sgid**, ou s
|
|||
|
||||
Notez que si CS\_REQUIRE\_LV est vrai, alors les variables ne seront pas élaguées mais la validation de la bibliothèque vérifiera qu'elles utilisent le même certificat que le binaire d'origine.
|
||||
|
||||
## Vérifier les restrictions
|
||||
## Vérification des restrictions
|
||||
|
||||
### SUID & SGID
|
||||
```bash
|
||||
|
@ -278,11 +292,11 @@ sudo chmod -s hello
|
|||
|
||||
Le segment `__restrict` est une section spéciale dans les binaires macOS qui est utilisée pour restreindre l'accès à certaines fonctionnalités sensibles du système d'exploitation. Cette section est conçue pour empêcher les processus non autorisés d'interférer avec des fonctionnalités critiques et de compromettre la sécurité du système.
|
||||
|
||||
Lorsqu'un binaire est compilé avec le flag `-fno-strict-aliasing`, le compilateur ajoute automatiquement le segment `__restrict` au binaire. Ce segment contient des instructions spécifiques qui restreignent l'accès aux fonctionnalités sensibles du système d'exploitation.
|
||||
Lorsqu'un binaire est compilé avec le flag `-fno-strict-aliasing`, le compilateur ajoute automatiquement le segment `__restrict` au binaire. Ce segment contient des instructions spécifiques qui restreignent l'accès aux fonctionnalités sensibles du système.
|
||||
|
||||
L'objectif principal de la section `__restrict` est de prévenir les attaques de type "privilege escalation" en empêchant les processus non autorisés d'injecter du code dans des bibliothèques système ou d'accéder à des fonctionnalités sensibles du système.
|
||||
L'objectif principal du segment `__restrict` est de prévenir les attaques de type "library injection" où un processus malveillant tente d'injecter du code dans une bibliothèque système pour obtenir des privilèges élevés. En restreignant l'accès à ces bibliothèques, le segment `__restrict` réduit considérablement les chances de succès de telles attaques.
|
||||
|
||||
Il est important de noter que la présence de la section `__restrict` dans un binaire ne garantit pas à elle seule la sécurité du système. D'autres mesures de sécurité doivent également être mises en place pour protéger efficacement le système contre les attaques potentielles.
|
||||
Il est important de noter que la présence du segment `__restrict` dans un binaire ne garantit pas une sécurité absolue. Les attaquants peuvent toujours trouver des moyens de contourner ces restrictions, il est donc essentiel de mettre en place d'autres mesures de sécurité pour renforcer la protection du système.
|
||||
```bash
|
||||
gcc -sectcreate __RESTRICT __restrict /dev/null hello.c -o hello-restrict
|
||||
DYLD_INSERT_LIBRARIES=inject.dylib ./hello-restrict
|
||||
|
|
|
@ -44,7 +44,7 @@ Cette autorisation permet de **charger des frameworks, des plug-ins ou des bibli
|
|||
|
||||
### `com.apple.private.security.clear-library-validation`
|
||||
|
||||
Cette autorisation est très similaire à **`com.apple.security.cs.disable-library-validation`** mais **au lieu de désactiver directement** la validation de la bibliothèque, elle permet au processus d'appeler un appel système `csops` pour la désactiver.\
|
||||
Cette autorisation est très similaire à **`com.apple.security.cs.disable-library-validation`** mais **au lieu de désactiver directement** la validation de la bibliothèque, elle permet au processus d'**appeler un appel système `csops` pour la désactiver**.\
|
||||
Consultez [**ceci pour plus d'informations**](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/).
|
||||
|
||||
### `com.apple.security.cs.allow-dyld-environment-variables`
|
||||
|
@ -55,7 +55,11 @@ Cette autorisation permet d'**utiliser des variables d'environnement DYLD** qui
|
|||
|
||||
[**Selon ce blog**](https://objective-see.org/blog/blog\_0x4C.html), ces autorisations permettent de **modifier** la **base de données TCC**.
|
||||
|
||||
### com.apple.private.security.kext-management
|
||||
### **`system.install.apple-software`** et **`system.install.apple-software.standar-user`**
|
||||
|
||||
Ces autorisations permettent d'**installer des logiciels sans demander la permission** de l'utilisateur, ce qui peut être utile pour une **escalade de privilèges**.
|
||||
|
||||
### `com.apple.private.security.kext-management`
|
||||
|
||||
Autorisation nécessaire pour demander au **noyau de charger une extension de noyau**.
|
||||
|
||||
|
@ -66,13 +70,13 @@ TODO: Je ne sais pas ce que cela permet de faire
|
|||
### `com.apple.private.apfs.revert-to-snapshot`
|
||||
|
||||
TODO: Dans [**ce rapport**](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/), il est mentionné que cela pourrait être utilisé pour mettre à jour les contenus protégés par SSV après un redémarrage. Si vous savez comment faire, envoyez une PR s'il vous plaît !
|
||||
|
||||
### `com.apple.private.apfs.create-sealed-snapshot`
|
||||
|
||||
TODO: Dans [**ce rapport**](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/), il est mentionné que cela pourrait être utilisé pour mettre à jour les contenus protégés par SSV après un redémarrage. Si vous savez comment faire, envoyez une PR s'il vous plaît !
|
||||
TODO: Dans [**ce rapport**](https://jhftss.github.io/The-Nightmare-of-Apple-OTA-Update/), il est mentionné que cela pourrait être utilisé pour mettre à jour les contenus protégés par SSV après un redémarrage. Si vous savez comment l'envoyer, veuillez soumettre une demande de pull (PR) s'il vous plaît !
|
||||
|
||||
### `keychain-access-groups`
|
||||
|
||||
Cette liste d'autorisations **keychain** regroupe les groupes d'accès auxquels l'application a accès:
|
||||
Cette liste d'attribution de privilèges **keychain** regroupe les groupes auxquels l'application a accès :
|
||||
```xml
|
||||
<key>keychain-access-groups</key>
|
||||
<array>
|
||||
|
@ -85,11 +89,11 @@ Cette liste d'autorisations **keychain** regroupe les groupes d'accès auxquels
|
|||
```
|
||||
### **`kTCCServiceSystemPolicyAllFiles`**
|
||||
|
||||
Donne des permissions d'accès complet au disque, l'une des permissions les plus élevées de TCC que vous pouvez avoir.
|
||||
Donne les permissions d'accès complet au disque, l'une des permissions les plus élevées de TCC que vous pouvez avoir.
|
||||
|
||||
### **`kTCCServiceAppleEvents`**
|
||||
|
||||
Permet à l'application d'envoyer des événements à d'autres applications couramment utilisées pour automatiser des tâches. En contrôlant d'autres applications, elle peut abuser des permissions accordées à ces autres applications.
|
||||
Permet à l'application d'envoyer des événements à d'autres applications couramment utilisées pour l'automatisation des tâches. En contrôlant d'autres applications, elle peut abuser des permissions accordées à ces autres applications.
|
||||
|
||||
### **`kTCCServiceSystemPolicySysAdminFiles`**
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ Permissions dans un **répertoire** :
|
|||
* Le **propriétaire du répertoire parent** dans le chemin est un **groupe d'utilisateurs** avec un **accès en écriture**
|
||||
* Un **groupe d'utilisateurs** a un **accès en écriture** au **fichier**
|
||||
|
||||
Avec l'une des combinaisons précédentes, un attaquant pourrait **injecter** un **lien sym/hard** dans le chemin attendu pour obtenir une écriture arbitraire privilégiée.
|
||||
Avec l'une de ces combinaisons précédentes, un attaquant pourrait **injecter** un **lien sym/hard** dans le chemin attendu pour obtenir une écriture arbitraire privilégiée.
|
||||
|
||||
### Cas spécial du répertoire racine R+X
|
||||
|
||||
|
@ -182,6 +182,12 @@ Cependant, il existe certains fichiers dont la signature ne sera pas vérifiée,
|
|||
...
|
||||
</dict>
|
||||
```
|
||||
Il est possible de calculer la signature d'une ressource à partir de la ligne de commande avec :
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
openssl dgst -binary -sha1 /System/Cryptexes/App/System/Applications/Safari.app/Contents/Resources/AppIcon.icns | openssl base64
|
||||
```
|
||||
## Monter des fichiers DMG
|
||||
|
||||
Un utilisateur peut monter un fichier DMG personnalisé même par-dessus certains dossiers existants. Voici comment vous pouvez créer un package DMG personnalisé avec un contenu personnalisé :
|
||||
|
|
Loading…
Add table
Reference in a new issue