Aprovechando los puntos "ciegos" del EDR con Pyramid

En el Adversary Village de la Defcon30 el italiano Diego Capriotti (@naksyn) presentó "Python vs Modern Defenses" donde usaba Python para ocultarse de los EDRs. Básicamente se aprovecha de que:

  • El amplio uso de Python implica que existe una telemetría muy variada para su intérprete que se ejecuta nativamente en las API. Esto puede aumentar la dificultad para que el EDR detecte anomalías provenientes de python.exe o pythonw.exe.
  • Python carece de transparencia (ref. PEP-578) para el código dinámico ejecutado desde los binarios estándar de python.exe y pythonw.exe.
  • La Fundación Python proporciona oficialmente un "paquete embebido de Windows" que se puede utilizar para ejecutar Python con un entorno mínimo sin instalación. El paquete viene con binarios firmados.
Teniendo en cuenta ésto, Diego desarrolló Pyramid, una herramienta que se puede usar con un intérprete de Python que ya exista en una máquina, o desempaquetar el paquete oficial de Python embebido y luego ejecutar python.exe (o pythonw.exe) para levantar un servidor de descarga de Python y luego ejecutar una amplia gama de tareas de post-explotación. Esta es una forma sencilla de evitar la creación de un patrón de árbol de proceso poco común y que parezca un uso normal de la aplicación Python.
 
Pyramid que ha sido probada con éxito contra varios EDRs, demostrando que efectivamente existen puntos ciegos y es posible ejecutar una variedad de acciones aprovechándolos. 
 
La técnica que utiliza ha sido llamada Living-off-The-Blindspot (Viviendo del Punto Ciego) y nos ofrece interesantes funciones, por ejemplo:

PEP-302. Importación y ejecución dinámica de Python-BloodHound y secretsdump.

Utiliza hooks de importación para modificar la lógica en la que se localizan y cargan los módulos de Python. Esto implica definir una clase personalizada "Finder" y agregar objetos de búsqueda a sys.meta_path. sys.meta_path contiene entradas que implementan la semántica de importación predeterminada de Python

Ejecución de BOF (volcado de lsass con nanodump).

Se puede usar COFFloader y BOF2Shellcode para ejecutar Beacon Object Files vía shellcode. Luego, el shellcode se puede inyectar directamente en python.exe usando Python y ctypes.  

Podemos volcar lsass directamente desde Python.exe usando nanodump, pero necesitamos modificarlo un poco para que funcione con esa técnica. Dado que ejecutaremos un BOF sin que se ejecute Cobalt Strike Beacon, debemos deshacernos de todas las llamadas internas a la API del Beacon porque, de lo contrario, el BOF fallará. También deberíamos hardcodear los parámetros de la línea de comandos para aumentar la estabilidad de ejecución de BOF y así deshacernos de las funciones de análisis de la línea de comandos. Finalmente, podemos elegir nuestro método preferido para descargar lsass y hardcodearlo también. 

Hay que tener en cuenta que con esta técnica no se colocan archivos pyd en el disco.

Creación de un reenvío de puerto local SSH para tunelizar un agente de C2.

La ejecución de un agente C2 aumenta las posibilidades de detección mediante escaneos de memoria, sin embargo, ciertos escenarios pueden requerir la ejecución de un agente para que la operación continúe. Por esta razón, Pyramid proporciona la capacidad de ejecutar un agente C2 y canalizar su tráfico a través de SSH, todo dentro del proceso python.exe. Esto se logra primero importando dinámicamente paramiko y luego iniciando el reenvío de puerto local SSH a un servidor SSH controlado por un atacante en un nuevo subproceso local. El shellcode del agente C2 se inyecta y ejecuta en el proceso. El escenario debe generarse utilizando el host 127.0.0.1 como servidor C2 con el mismo puerto abierto localmente por el reenvío de puerto local SSH.

Módulos

En Pyramid, se usa un cradle o punto de descarga a través de HTTP/S para obtener módulos y dependencias. Los módulos son específicos para la función que desea usar y contienen:  

  1. Clase de Finder personalizada para importar en memoria las dependencias requeridas (archivos zip).  
  2. Código para descargar las dependencias requeridas.  
  3. Lógica principal del programa que desea ejecutar (bloodhound, secretsdump, paramiko, etc.).  

Las dependencias de Python ya se han corregido y modificado para que se importen en la memoria sin conflictos. Actualmente hay 8 módulos Pyramid disponibles:  

  1. bh.py importará en memoria y ejecutará python-BloodHound.  
  2. secretsdump.py importará en memoria y ejecutará secretsdump de Impacket.
  3. shellcode.py es un simple inyector de shellcode en memoria.  
  4. El script DonPAPI.py importará en memoria y ejecutará DonPAPI. Los resultados y las credenciales extraídas se guardan en el disco en el Directorio de paquetes integrados de Python.  
  5. El script LaZagne.py importará en memoria y ejecutará LaZagne  
  6. El script tunnel-socks5 importa y ejecuta paramiko en un nuevo subproceso para crear un puerto remoto SSH hacia un servidor SSH, luego un servidor proxy socks5 se ejecuta localmente en el destino y se hace accesible de forma remota a través del túnel SSH. 
  7. clr script importa Python.net para cargar y ejecutar un ensamblado .NET en memoria.  
  8. El script pythonmemorymodule importa PythonMemoryModule para cargar un dll desde la memoria.

Uso

Iniciar el servidor:

git clone https://github.com/naksyn/Pyramid

Generar certificado SSL para el servidor HTTPS:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

Ejemplo de ejecución de Pyramid HTTP Server usando un certificado SSL que proporciona autenticación básica, cifrando archivos de delivery usando ChaCha, generando automáticamente la configuración del servidor en módulos y sacando un cradle para pythonmemorymodule:

python3 pyramid.py -p 443 -ssl -u testuser -pass Sup3rP4ss! -enc "chacha20" -passenc "TestPass1" -server "192.168.1.2" -generate -setcradle pythonmemorymodule.py

Blog: https://www.naksyn.com/edr%20evasion/2022/09/01/operating-into-EDRs-blindspot.html

Proyecto: https://github.com/naksyn/Pyramid

Comentarios