Cobalt Strike C2 Reverse proxy que repele a Blue Teams, AVs, EDRs, scanners mediante la inspección de paquetes y la correlación de perfiles maleables
(anteriormente conocido como el plugin malleable_redirector de proxy2's )
Elevemos el listón en la resiliencia de los redirectores C2 frente a IR, ¿de acuerdo?

El mundo del Red Teaming ha visto varias ideas excelentes sobre cómo combatir a los respondedores de incidentes y desviarlos, mientras se ofrece al mismo tiempo una red de redirectores C2 resistente.
Este trabajo combina muchas de esas grandes ideas en una utilidad ligera, que imita a Apache2 en su esencia de ser un proxy inverso HTTP(S) simple.
La combinación de la comprensión de los perfiles Malleable C2, el conocimiento de un pool de direcciones IP maliciosas y la flexibilidad para añadir fácilmente nueva lógica de inspección y desvío, ha dado como resultado un repelente astuto para las inspecciones de IR.

Si algún paquete entrante no válido llega a RedWarden, ¡puedes redirigir, resetear o simplemente hacia otro lado!
proxyEste programa actúa como un proxy inverso HTTP/HTTPS con varias restricciones impuestas a las solicitudes HTTP C2 entrantes, seleccionando qué paquetes dirigir al Teamserver y cuáles descartar, de manera similar a las restricciones del archivo .htaccess en el mod_rewrite de Apache2.
RedWarden fue creado para resolver el problema de la evasión de IR/AV/EDRs/Sandboxes en la capa de redirector C2. Su objetivo es reemplazar las configuraciones clásicas de Apache2 + mod_rewrite utilizadas para ese fin.
Características:
RedWarden toma como entrada el perfil Malleable C2 y el hostname:puerto del teamserver. Luego analiza las secciones del perfil malleable proporcionado para entender el contrato y solo permitir el paso de aquellas solicitudes entrantes que lo satisfagan, mientras desvía las demás.
Secciones como http-stager, http-get, http-post y sus correspondientes uris, cabeceras, patrones de prepend/append, User-Agent; todo se utiliza para distinguir entre una solicitud legítima de beacon y ruido de Internet no relacionado o paquetes fuera de límites de IR/AV/EDRs.
El programa se beneficia de los maravillosos rangos IP maliciosos conocidos provenientes de: curi0usJack y los demás: https://gist.github.com/curi0usJack/971385e8334e189d93a6cb4671238b10
El uso de una lista negra de direcciones IP junto con la búsqueda de palabras clave maliciosas conocidas a través de consultas Reverse-IP DNS e inspección de cabeceras HTTP, aumenta la fiabilidad para incrementar considerablemente la resiliencia del redirector frente a pares no autorizados que deseen examinar las infraestructuras de los atacantes.
Los paquetes inválidos pueden ser redirigidos según tres estrategias:
Esta configuración se establece en el archivo de configuración:```yaml
drop_action: redirect
El siguiente ejemplo muestra el resultado de `redirect` a `https://googole.com`:

Úsalo con prudencia, mantente seguro.
### Requisitos
Este programa solo puede ejecutarse en sistemas Linux, ya que utiliza fork para generar múltiples procesos.
Además, se espera que el comando del sistema `openssl` esté instalado, ya que se utiliza para generar certificados SSL.
Finalmente, instala todos los requisitos de Python3 PIP fácilmente con:```shell
bash $ sudo pip3 install -r requirements.txt
El archivo de configuración config.yaml mínimo de RedWarden podría contener:```yaml port:
profile: jquery-c2.3.14.profile
ssl_cacert: /etc/letsencrypt/live/attacker.com/fullchain.pem ssl_cakey: /etc/letsencrypt/live/attacker.com/privkey.pem
teamserver_url:
drop_action: reset
Luego, el programa se puede lanzar proporcionándole una ruta al archivo de configuración:```shell
bash$ sudo python3 RedWarden.py -c config.yaml
[INFO] 19:21:42: Loading 1 plugin...
[INFO] 19:21:42: Plugin "malleable_redirector" has been installed.
[INFO] 19:21:42: Preparing SSL certificates and keys for https traffic interception...
[INFO] 19:21:42: Using provided CA key file: ca-cert/ca.key
[INFO] 19:21:42: Using provided CA certificate file: ca-cert/ca.crt
[INFO] 19:21:42: Using provided Certificate key: ca-cert/cert.key
[INFO] 19:21:42: Serving http proxy on: 0.0.0.0, port: 80...
[INFO] 19:21:42: Serving https proxy on: 0.0.0.0, port: 443...
[INFO] 19:21:42: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:21:42: == Valid malleable http-get request inbound.
[INFO] 19:21:42: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[INFO] 19:21:42: [RESPONSE] HTTP 200 OK, length: 5543
[INFO] 19:21:45: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:21:45: == Valid malleable http-get request inbound.
[INFO] 19:21:45: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[INFO] 19:21:45: [RESPONSE] HTTP 200 OK, length: 5543
[INFO] 19:21:46: [REQUEST] GET /
[...]
[ERROR] 19:24:46: [DROP, reason:1] inbound User-Agent differs from the one defined in C2 profile.
[...]
[INFO] 19:24:46: [RESPONSE] HTTP 301 Moved Permanently, length: 212
[INFO] 19:24:48: [REQUEST] GET /jquery-3.3.1.min.js
[INFO] 19:24:48: == Valid malleable http-get request inbound.
[INFO] 19:24:48: Plugin redirected request from [code.jquery.com] to [1.2.3.4:8080]
[...]
El resultado anterior contiene una línea que señala que ha habido una solicitud entrante no autorizada y no compatible con nuestro perfil C2, que fue descartada debido a que se presentó una cadena User-Agent incompatible:``` [...] [DROP, reason:1] inbound User-Agent differs from the one defined in C2 profile. [...]
## Casos de Uso
### Imponer geolocalización IP a los originadores de tráfico Beacon
Has hecho muy bien tu Pre-Phish y OSINT. Ahora sabes dónde viven tus objetivos y tienes algunas pistas sobre dónde debería originarse el tráfico, o al menos cómo detectar tráfico completamente auxiliar.
¿Cómo imponer geolocalización IP en las solicitudes Beacon en un redireccionador?
¡RedWarden viene al rescate!
Digamos que solo quieres aceptar tráfico originado desde Polonia, Europa.
Tus resultados de Pre-Phish/OSINT indican que:
- `89.64.64.150` es una IP legítima de uno de tus objetivos, originada desde Polonia
- `59.99.140.76` mientras que esta no lo es y llegó a tus sistemas como un paquete de ruido de Internet normal.
Puedes usar la utilidad de RedWarden `lib/ipLookupHelper.py` para recopilar metadatos de geolocalización IP sobre estas dos direcciones:```shell
bash$ python3 ipLookupHelper.py
Usage: ./ipLookupHelper.py <ipaddress> [malleable-redirector-config]
Use this small utility to collect IP Lookup details on your target IPv4 address and verify whether
your 'ip_geolocation_requirements' section of proxy2 malleable-redirector-config.yaml would match that
IP address. If second param is not given - no
El primero trae:```shell bash$ python3 ipLookupHelper.py 89.64.64.150 [dbg] Following IP Lookup providers will be used: ['ip_api_com', 'ipapi_co'] [.] Lookup of: 89.64.64.150 [dbg] Calling IP Lookup provider: ipapi_co [dbg] Calling IP Lookup provider: ip_api_com [dbg] New IP lookup entry cached: 89.64.64.150 [.] Output: { "organization": [ "UPC Polska Sp. z o.o.", "UPC.pl", "AS6830 Liberty Global B.V." ], "continent": "Europe", "continent_code": "EU", "country": "Poland", "country_code": "PL", "ip": "89.64.64.150", "city": "Warsaw", "timezone": "Europe/Warsaw", "fulldata": { "status": "success", "country": "Poland", "countryCode": "PL", "region": "14", "regionName": "Mazovia", "city": "Warsaw", "zip": "00-202", "lat": 52.2484, "lon": 21.0026, "timezone": "Europe/Warsaw", "isp": "UPC.pl", "org": "UPC Polska Sp. z o.o.", "as": "AS6830 Liberty Global B.V.", "query": "89.64.64.150" }, "reverse_ip": "89-64-64-150.dynamic.chello.pl" }
y el último da:```shell
bash$ python3 ipLookupHelper.py 59.99.140.76
[dbg] Following IP Lookup providers will be used: ['ip_api_com', 'ipapi_co']
[dbg] Read 1 cached entries from file.
[.] Lookup of: 59.99.140.76
[dbg] Calling IP Lookup provider: ip_api_com
[dbg] New IP lookup entry cached: 59.99.140.76
[.] Output:
{
"organization": [
"",
"BSNL Internet",
"AS9829 National Internet Backbone"
],
"continent": "Asia",
"continent_code": "AS",
"country": "India",
"country_code": "IN",
"ip": "59.99.140.76",
"city": "Palakkad",
"timezone": "Asia/Kolkata",
"fulldata": {
"status": "success",
"country": "India",
"countryCode": "IN",
"region": "KL",
"regionName": "Kerala",
"city": "Palakkad",
"zip": "678001",
"lat": 10.7739,
"lon": 76.6487,
"timezone": "Asia/Kolkata",
"isp": "BSNL Internet",
"org": "",
"as": "AS9829 National Internet Backbone",
"query": "59.99.140.76"
},
"reverse_ip": ""
}
Ahora ves que el primero tenía "country": "Poland" mientras que el segundo "country": "India". Con ese conocimiento estamos listos para diseñar nuestras restricciones en forma de un voluminoso diccionario YAML:```yaml
ip_geolocation_requirements:
organization:
continent:
continent_code:
country:
- Poland
- PL
- Polska
country_code:
city:
timezone:
Cada una de las entradas de ese diccionario acepta una expresión regular para coincidir con los metadatos Geo IP determinados de la dirección IP del par entrante.
Usamos tres entradas en la propiedad `country` para permitir solicitudes que tengan uno de los valores especificados.
Con eso configurado, puedes verificar si otra dirección IP pasaría o no por el discriminador de Geolocalización IP de RedWarden con la utilidad `ipLookupHelper` que acepta un segundo parámetro:

La última línea te indica si el paquete sería bloqueado o aceptado.
¡Y eso es todo! Configura tus restricciones de Geolocalización IP de manera prudente y segura, inspecciona cuidadosamente los registros de RedWarden en busca de entradas DROP relacionadas con IP Geo y ¡mantén tu tráfico C2 limpio y ordenado!
### Reparar solicitudes Beacon manipuladas
Si utilizas sistemas intermedios como AWS Lambda o CloudFlare como tus redireccionadores / Domain Fronting, seguramente te has encontrado con situaciones en las que algunos de tus paquetes no pudieron ser aceptados por el Teamserver porque se desviaban del contrato maleable acordado. Ya sea una cabecera HTTP alterada o eliminada, cookies reordenadas o cualquier otra cosa — apuesto que te hizo perder muchas horas de tu vida.
Para combatir los problemas del proceso de configuración de canales C2 y las manipulaciones de los sistemas intermedios, RedWarden ofrece funcionalidad para reparar paquetes Beacon.
Lo hace comprobando lo que el Perfil Maleable espera que sea el paquete y puede restaurar las cabeceras HTTP configuradas a sus valores acordados según los requisitos del perfil.
Considera el siguiente perfil simple:```
http-get {
set uri "/api/abc";
client {
header "Accept-Encoding" "gzip, deflate";
metadata {
base64url;
netbios;
base64url;
parameter "auth";
}
}
...
¿Ves este Accept-Encoding? Cada solicitud de Beacon debe incluir ese encabezado y ese valor. ¿Qué sucede si tu Beacon llega a sistemas de CloudFlare y ellos emiten una solicitud que será despojada de ese encabezado o tendrá Accept-Encoding: gzip en su lugar? Teamserver descartará la solicitud en el acto.
Al configurar este encabezado en la sección de configuración de RedWarden llamada repair_these_headers, puedes proteger tu conexión.:```yaml
repair_these_headers:
### Eliminar encabezados de respuesta problemáticos
Con Cobalt Strike 4.7+ noté que Teamserver elimina automáticamente el encabezado Content-Encoding sin previo aviso, violando así nuestro contrato `http-(get|post).server` maleable.
Dado que RedWarden seguía el contrato, Beacon estaba descartando respuestas o descomprimiéndolas incorrectamente.
Esta opción especifica qué encabezados provenientes de las respuestas de Teamserver deben eliminarse antes de llegar al proceso de Beacon:```yaml
remove_these_response_headers:
- Content-Encoding
RedWarden ahora eliminará el encabezado Content-Encoding por defecto de las respuestas del Teamserver, para mantener la operatividad con versiones CS4.7+.
Echemos un vistazo a la salida que produce el proxy.
Con la opción verbose: True, la verbosidad se establecerá como máximo en INFO, indicando las solicitudes aceptadas de las rechazadas.
La solicitud puede ser aceptada si cumple con todos los criterios configurados en el archivo de configuración de RedWarden. Dicha situación será seguida con una entrada de registro [ALLOW, ...]:```
[INFO] 2021-04-24/17:30:48: [REQUEST] GET /js/scripts.js
[INFO] 2021-04-24/17:30:48: == Valid malleable http-get (variant: default) request inbound.
[INFO] 2021-04-24/17:30:48: [ALLOW, 2021-04-24/19:30:48, 111.222.223.224] "/js/scripts.js" - UA: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
[INFO] 2021-04-24/17:30:48: Connected peer sent 2 valid http-get and 0 valid http-post requests so far, out of 15/5 required to consider him temporarily trusted
[INFO] 2021-04-24/17:30:48: Plugin redirected request from [attacker.com] to [127.0.0.1:5555]
Si la solicitud falla en alguna de las comprobaciones que RedWarden realiza en cada solicitud, se emitirá la línea `[DROP, ...]` correspondiente que contiene información sobre la **razón** del descarte.:```
[INFO] 2021-04-24/16:48:28: [REQUEST] GET /
[ERROR] 2021-04-24/16:48:29: [DROP, 2021-04-24/18:48:28, reason:1, 128.14.211.186] inbound User-Agent differs from the one defined in C2 profile.
[INFO] 2021-04-24/16:48:29: [DROP, 2021-04-24/18:48:28, 128.14.211.186] "/" - UA: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36"
[ERROR] 2021-04-24/16:48:29: [REDIRECTING invalid request from 128.14.211.186 (zl-dal-us-gp3-wk107.internet-census.org)] GET /
Hay muchas razones que determinan si una solicitud puede ser descartada. Cada una de estas comprobaciones puede activarse o desactivarse de forma independiente según los requisitos o en un proceso de ajuste fino o corrección de decisiones erróneas:
Extracto de example-config.yaml:```yaml
policy:
allow_proxy_pass: True
allow_dynamic_peer_whitelisting: True
drop_invalid_useragent: True
drop_http_banned_header_names: True
drop_http_banned_header_value: True
drop_dangerous_ip_reverse_lookup: True
drop_ipgeo_metadata_containing_banned_keywords: True
drop_malleable_without_expected_header: True
drop_malleable_without_expected_header_value: True
drop_malleable_without_expected_request_section: True
drop_malleable_without_request_section_in_uri: True
drop_malleable_without_prepend_pattern: True
drop_malleable_without_apppend_pattern: True
drop_malleable_unknown_uris: True
drop_malleable_with_invalid_uri_append: True
Por defecto, todas estas comprobaciones están habilitadas.
Activar `debug: True` inundará tu búfer de consola con muchas líneas de registro que describen cada paso que RedWarden toma en su complejo proceso de toma de decisiones.
Si quieres ver los cuerpos completos de tus solicitudes y respuestas, establece `debug` y `trace` en true y ¡entierra tu consola en una carga de registros!
## FAQ
**- ¿Puede este programa ejecutarse sin un perfil Malleable?**
Sí, puede. Sin embargo, la lógica de inspección de solicitudes estará desactivada; el resto debería funcionar bien: aplicación de geolocalización IP, lógica de búsqueda inversa, lista de IPs prohibidas, etc.
**- ¿Puede este programa adaptarse fácilmente a otros frameworks C2? ¿Como Mythic, Covenant, etc.?**
No, fácilmente no. Con algo de esfuerzo, sí. Como he descrito más abajo, la herramienta está mal escrita, lo que hará que la adaptación a otros C2 sea un dolor. Sin embargo, es totalmente factible con algo de tiempo y esfuerzo.
**- Mis paquetes están siendo descartados. ¿Por qué?**
Intenta activar `debug: True` y `trace: True` para recopilar tantos registros como sea posible. Luego deberías revisar los registros e inspeccionar qué está sucediendo. ¿Los paquetes se ven exactamente como esperabas en tu perfil Malleable? ¿O tal vez hubo una manipulación sutil en la red que hace que RedWarden descarte el paquete (y podría hacer que Teamserver también lo descarte)?
## Problemas conocidos
- Puede _agregar_ una ligera sobrecarga al rendimiento del sueño interactivo
- La lógica de procesamiento de ProxyPass está lejos de ser perfecta y es _realmente_ buggy (¡y vaya que es fea!).
- Formas extrañas de archivos de configuración pueden descarrilar el analizador de RedWarden y hacer que se queje. La forma más fácil de superar esto sería copiar `example-config.yaml` y trabajar en su lugar.
## Oh Dios mío, ¿por qué este código es una mierda ingenieril?
El código es _UN GRAN CAOS DE MIERDA_ – lo admito – y también hay una razón honesta para ello: el proyecto se desarrolló un 90% durante compromisos reales de Red Team. Como todos sabemos, este tipo de compromisos implican tantas cosas que hacer que apenas queda tiempo para un desarrollo adecuado de herramientas complejas. Sin mencionar la criticidad de este programa en la configuración del proyecto. La herramienta comenzó inicialmente como un script proxy simple escrito en Python2, para luego evolucionar como un proxy con plugins, recibió el plugin `malleable_redirector` – y desde entonces he estado tratando muy duro de mantener `proxy2` con compatibilidad hacia atrás (¡pobre de mí, era como Microsoft!) con otros plugins que he creado para él y mantenerme fiel a su propósito original.
Sin embargo, ha llegado el momento de dejarlo ir, cambiarlo de marca y empezar a arreglar todos los malos olores de código introducidos.
Con todo lo dicho, por favor, muestra algo de compasión hacia mí al plantear problemas, enviar pull requests y trata de ayudar en lugar de juzgar. :-)
¡Gracias!
## TODO
- Investigar la posibilidad de usar feeds de inteligencia de amenazas con fines nefastos, como por ejemplo detectar proveedores de seguridad basados en IPs
- Agregar soporte para la base de datos/API de MaxMind GeoIP
- Implementar soporte para firmas JA3 tanto en detección y bloqueo como en suplantación para falsificar configuraciones de nginx/Apache2/personalizadas
- Agregar lógica de seguimiento de balizas únicas para ofrecer flexibilidad para rechazar los procesos de staging y comunicación a discreción del proxy
- Introducir restricciones de día/hora al ofrecer capacidades de redirección (_proxy solo durante horas de oficina_)
- Agregar lógica de autenticación y autorización de proxy en CONNECT/relé
- Agregar redirección dirigida a usuarios móviles
- Agregar opciones de configuración para definir encabezados HTTP personalizados a inyectar o eliminar
- Agregar opciones de configuración para requerir la presencia de encabezados HTTP específicos en solicitudes que pasan los criterios de ProxyPass
- Interfaz interactiva que permite escribir caracteres simples para controlar la verbosidad del registro de salida, similar a la de Nmap
- Reescribir la lógica del analizador de perfiles Malleable utilizando [pyMalleableC2](https://github.com/Porchetta-Industries/pyMalleableC2). Cuando empecé a programar mi propia lógica de análisis, no existía tal herramienta en Github.
- Refactorizar toda la base de código
---
### ☕ Muestra tu apoyo ☕
Este y otros proyectos son el resultado de noches sin dormir y **mucho trabajo duro**. Si te gusta lo que hago y aprecias que siempre devuelvo a la comunidad, [Considera invitarme a un café](https://github.com/sponsors/mgeeky) _(o mejor una cerveza)_ solo para darte las gracias! 💪
---
## Autor```
Mariusz Banach / mgeeky, '19-'21
<mb [at] binary-offensive.com>
(https://github.com/mgeeky)