
Proxy reverso C2 do Cobalt Strike que repele Equipes Azuis, AVs, EDRs, scanners através de inspeção de pacotes e correlação de perfil maleável.
(anteriormente conhecido como plugin malleable_redirector do proxy2)
Vamos elevar o nível da resiliência de redirecionadores C2 contra IR, não é mesmo?

O negócio de Red Teaming já viu várias ideias excelentes sobre como combater respondedores de incidentes e desencaminhá-los, ao mesmo tempo que oferece uma rede de redirecionadores C2 resilientes.
Este trabalho combina muitas dessas grandes ideias numa única ferramenta leve, imitando o Apache2 nas suas raízes como um simples proxy reverso HTTP(S).
Combinar a compreensão de perfis Malleable C2, conhecimento de um pool de endereços IP maliciosos e a flexibilidade de adicionar facilmente nova lógica de inspeção e desencaminhamento resultou num repelente astuto para inspeções de IR.

Caso algum pacote de entrada inválido atinja o RedWarden - pode redirecionar, reiniciar ou apenas proxy para longe!
Este programa atua como um proxy reverso HTTP/HTTPS com várias restrições impostas sobre pedidos C2 HTTP de entrada, selecionando quais pacotes direcionar para o Teamserver e quais descartar, de forma semelhante às restrições do arquivo .htaccess impostas no mod_rewrite do Apache2.
O RedWarden foi criado para resolver o problema de evasão de IR/AV/EDRs/Sandboxes na camada de redirecionador C2. A sua intenção é substituir as configurações clássicas de Apache2 + mod_rewrite usadas para esse fim.
Características:
O RedWarden recebe o perfil Malleable C2 e o hostname:porta do teamserver como entrada. De seguida, analisa as secções do perfil malleable fornecido para compreender o contrato e passar apenas os pedidos de entrada que o satisfazem, enquanto desencaminha outros.
Secções como http-stager, http-get, http-post e os seus uris, cabeçalhos, padrões de prepend/append, User-Agent correspondentes são todas utilizadas para distinguir entre um pedido legítimo de um beacon e ruído não relacionado da Internet ou pacotes fora de alcance de IR/AV/EDRs.
O programa beneficia das maravilhosas listas de IPs maliciosos conhecidos provenientes de: curi0usJack e outros: https://gist.github.com/curi0usJack/971385e8334e189d93a6cb4671238b10
Usar uma lista negra de endereços IP juntamente com pesquisa de palavras-chave maliciosas através de consultas de DNS reverso e inspeção de cabeçalhos HTTP, aumenta a fiabilidade para aumentar consideravelmente a resiliência do redirecionador contra pares não autorizados que queiram examinar as infraestruturas do atacante.
Pacotes inválidos podem ser desencaminhados de acordo com três estratégias:
Esta configuração é definida no ficheiro de configuração:```yaml
drop_action: redirect
O exemplo abaixo mostra o resultado do `redirect` para `https://googole.com`:

Use com sabedoria, fique seguro.
### Requisitos
Este programa pode ser executado apenas em sistemas Linux, pois usa fork para gerar múltiplos processos.
Além disso, espera-se que o comando de sistema `openssl` esteja instalado, pois é usado para gerar certificados SSL.
Finalmente, instale todos os requisitos do Python3 PIP facilmente com:```shell
bash $ sudo pip3 install -r requirements.txt
O mínimo arquivo de configuração config.yaml do RedWarden poderia conter:```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
Em seguida, o programa pode ser iniciado fornecendo um caminho para o arquivo de configuração:
``````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]
[...]
A saída acima contém uma linha apontando que houve uma requisição de entrada não autorizada, não compatível com nosso perfil C2, que foi descartada devido à string User-Agent incompatível apresentada:``` [...] [DROP, reason:1] inbound User-Agent differs from the one defined in C2 profile. [...]
## Casos de Uso
### Impor Geolocalização IP nos originadores de tráfego do Beacon
Você fez seu Pre-Phish e OSINT muito bem. Agora você sabe onde seus alvos vivem e tem algumas pistas de onde o tráfego deve se originar, ou pelo menos como detectar tráfego completamente auxiliar.
Como impor Geolocalização IP nas requisições Beacon em um redirecionador?
RedWarden vem ajudar!
Digamos que você queira aceitar apenas tráfego originado da Polônia, Europa.
Seus resultados de Pre-Phish/OSINT indicam que:
- `89.64.64.150` é um IP legítimo de um dos seus alvos, originado da Polônia
- `59.99.140.76` enquanto este não é e alcançou seus sistemas como um pacote regular de ruído da Internet.
Você pode usar o utilitário do RedWarden `lib/ipLookupHelper.py` para coletar metadados IP Geo sobre esses dois endereços:```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
O primeiro traz:```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" }
e o último dá:```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": ""
}
Agora você vê que o primeiro tinha "country": "Poland" enquanto o último tinha "country": "India". Com esse conhecimento, estamos prontos para elaborar nossas restrições na forma de um grande dicionário YAML:```yaml
ip_geolocation_requirements:
organization:
continent:
continent_code:
country:
- Poland
- PL
- Polska
country_code:
city:
timezone:
Cada entrada desse dicionário aceita uma expressão regular para ser correspondida com metadados de Geo IP determinados do endereço IP do peer de entrada.
Usamos três entradas na propriedade `country` para permitir requisições que tenham um dos valores especificados.
Com isso definido na sua configuração, você pode verificar se outro endereço IP passaria pelo discriminador de Geolocalização IP do RedWarden ou não com o utilitário `ipLookupHelper` que aceita um segundo parâmetro:

A última linha informa se o pacote será bloqueado ou aceito.
E é isso! Configure suas restrições de Geolocalização IP de forma sábia e segura, inspecione cuidadosamente os logs do RedWarden em busca de entradas DROP relacionadas a Geo IP e mantenha seu tráfego C2 organizado!
### Reparar requisições Beacon adulteradas
Se você utiliza sistemas intermediários como AWS Lambda ou CloudFlare como seus frontais de domínio / redirecionadores, certamente já se deparou com uma situação em que alguns de seus pacotes não puderam ser aceitos pelo Teamserver por terem se desviado do contrato maleável acordado. Foi um cabeçalho HTTP adulterado ou removido, cookies reordenados ou qualquer outra coisa — aposto que isso desperdiçou muitas horas da sua vida.
Para combater problemas no processo de configuração de canais C2 e adulterações de sistemas intermediários, o RedWarden oferece funcionalidade para reparar pacotes Beacon.
Ele faz isso verificando o que o Perfil Maleável espera que o pacote seja e pode restaurar cabeçalhos HTTP configurados para seus valores acordados de acordo com os requisitos do perfil.
Considere o seguinte perfil simples:```
http-get {
set uri "/api/abc";
client {
header "Accept-Encoding" "gzip, deflate";
metadata {
base64url;
netbios;
base64url;
parameter "auth";
}
}
...
Você vê este Accept-Encoding? Toda requisição do Beacon precisa ter esse cabeçalho e esse valor. O que acontece se seu Beacon atingir sistemas CloudFlare e eles emitirem uma requisição que será removida desse cabeçalho ou terá Accept-Encoding: gzip no lugar? O Teamserver rejeitará a requisição na hora.
Ao definir este cabeçalho na seção de configuração do RedWarden chamada repair_these_headers, você pode proteger sua conexão.:```yaml
repair_these_headers:
### Remover cabeçalhos de resposta problemáticos
Com o Cobalt Strike 4.7+, notei que o Teamserver remove automaticamente o cabeçalho Content-Encoding sem qualquer aviso, violando assim nosso contrato `http-(get|post).server` malleable.
Como o RedWarden seguia o contrato, o Beacon estava descartando respostas ou as descomprimindo incorretamente.
Esta opção especifica quais cabeçalhos das respostas do Teamserver devem ser removidos antes de chegarem ao processo Beacon:```yaml
remove_these_response_headers:
- Content-Encoding
RedWarden removerá agora o cabeçalho Content-Encoding por padrão das respostas do Teamserver, para manter a operabilidade com versões CS4.7+.
Vamos dar uma olhada na saída que o proxy produz.
Com a opção verbose: True, a verbosidade será definida como INFO no máximo, informando requisições aceitas e descartadas.
A requisição pode ser aceita se atender a todos os critérios configurados no arquivo de configuração do RedWarden. Tal situação será seguida por um log de entrada [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]
Caso a solicitação falhe em qualquer uma das verificações que o RedWarden realiza em cada solicitação, a linha `[DROP, ...]` correspondente será emitida contendo informações sobre o **motivo** da rejeição.:```
[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 /
Há várias razões que determinam se uma requisição pode ser descartada. Cada uma dessas verificações pode ser ativada ou desativada independentemente, conforme os requisitos ou em um processo de ajuste fino ou correção de decisões errôneas:
Trecho 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 padrão, todas essas verificações são aplicadas.
Ativar `debug: True` inundará seu buffer de console com muitas linhas de log descrevendo cada etapa que o RedWarden toma em seu complexo processo de decisão.
Se você quiser ver os corpos completos de suas requisições e respostas, ative `debug` e `trace` como true e prepare-se para ser soterrado em logs!
## FAQ
**- Este programa pode funcionar sem um Perfil Malleable?**
Sim, pode. No entanto, a lógica de inspeção de requisições será desativada; o restante deve funcionar normalmente: imposição de Geolocalização de IP, lógica de reverse-lookup, lista de IPs banidos, etc.
**- Este programa pode ser facilmente adaptado para outros frameworks C2? Como Mythic, Covenant, etc?**
Facilmente, não. Com algum esforço, sim. Como descrevi abaixo, a ferramenta foi escrita de forma ruim, o que tornará a adaptação para outros C2s um pouco dolorosa. No entanto, é totalmente possível, dado tempo e esforço.
**- Meus pacotes estão sendo descartados. Por quê?**
Tente ativar `debug: True` e `trace: True` para coletar o máximo de logs possível. Depois, você precisará revisar os logs e inspecionar o que está acontecendo. Os pacotes estão exatamente como você esperava no seu perfil Malleable? Ou talvez tenha havido uma adulteração sutil ao longo da rede que fez o RedWarden descartar o pacote (e poderia fazer o Teamserver descartá-lo também?).
## Problemas Conhecidos
- Pode adicionar uma leve sobrecarga à taxa de transferência do sleep interativo
- A lógica de processamento do ProxyPass está longe de ser perfeita e é _realmente_ cheia de bugs (e, meu Deus, é feia!).
- Formas estranhas de arquivos de configuração podem desviar o parser do RedWarden e fazê-lo reclamar. A abordagem mais fácil para contornar isso seria copiar `example-config.yaml` e trabalhar nele.
## Oh meu Deus, por que esse código é uma porcaria de engenharia?
O código é _UMA GRANDE BAGUNÇA DO CARALHO_ — eu admito — e há uma razão honesta para isso também: o projeto foi desenvolvido 90% durante compromissos reais de Red Team. Como todos sabemos, esses tipos de compromissos envolvem tantas coisas para fazer, deixando quase nenhum tempo para um desenvolvimento adequado de ferramentas complexas. Sem mencionar a criticidade deste programa na configuração do projeto. A ferramenta inicialmente começou como um script proxy simples escrito em Python2, para depois evoluir como um proxy com plugins, recebeu o plugin `malleable_redirector` — e desde então tenho me esforçado muito para manter a `proxy2` compatível com versões anteriores (coitado de mim, eu era tipo a Microsoft!) com outros plugins que fiz para ela e manter seu propósito original.
No entanto, chegou a hora de deixá-la ir, renomeá-la e começar a corrigir todos os maus cheiros de código introduzidos.
Com tudo isso dito, por favor, mostre um pouco de compaixão por mim ao abrir issues, enviar pull requests e tente ajudar em vez de julgar! :-)
Obrigado!
## TODO
- Pesquisar a possibilidade de usar feeds de Inteligência de Ameaças para fins nefastos — como, por exemplo, detectar Fornecedores de Segurança com base em IPs
- Adicionar suporte para banco de dados/API MaxMind GeoIP
- Implementar suporte para assinaturas JA3 tanto na detecção & bloqueio quanto na falsificação para simular setups nginx/Apache2/personalizados.
- Adicionar alguma lógica única de rastreamento de beacons para oferecer flexibilidade de recusar processos de staging e comunicação a critério do próprio proxy
- Introduzir restrição de horário do dia ao oferecer capacidades de redirecionamento (_proxy apenas durante o horário comercial_)
- Adicionar lógica de autenticação e autorização de proxy no CONNECT/relay.
- Adicionar redirecionamento direcionado a usuários móveis
- Adicionar opções de configuração para definir cabeçalhos HTTP personalizados a serem injetados, ou aqueles a serem removidos
- Adicionar opções de configuração para exigir cabeçalhos HTTP específicos a serem apresentados em requisições passando pelos critérios do ProxyPass.
- Interface interativa permitindo digitar caracteres simples controlando a verbosidade do log de saída, semelhante ao Nmap
- Reescrever a lógica do parser de perfil Malleable para [pyMalleableC2](https://github.com/Porchetta-Industries/pyMalleableC2). Quando comecei a codificar minha própria lógica de parser, não existia tal toolkit no Github.
- Refatorar toda a base de código
---
### ☕ Mostre Apoio ☕
Este e outros projetos são resultado de noites sem dormir e **muito trabalho duro**. Se você gosta do que faço e aprecia que sempre retribuo para a comunidade,
[Considere me pagar um café](https://github.com/sponsors/mgeeky) _(ou melhor, uma cerveja)_ apenas para agradecer! 💪
---
## Autor```
Mariusz Banach / mgeeky, '19-'21
<mb [at] binary-offensive.com>
(https://github.com/mgeeky)