Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2010-4221-lab — Da correção ao RCE: exploit construído à mão para CVE-2010-4221 (estouro de pilha TELNET IAC no ProFTPD), com toda a jornada orientada por falhas documentada | Kitploit
Ferramentas/GitHubGitHub/diegslva/cve-2010-4221-lab
Frameworks de ExploraçãoAnálise de VulnerabilidadesExploraçãoEngenharia ReversaTestes de PenetraçãoAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHubdiegslva/cve-2010-4221-lab

cve-2010-4221-lab

Da correção ao RCE: exploit construído à mão para CVE-2010-4221 (estouro de pilha TELNET IAC no ProFTPD), com toda a jornada orientada por falhas documentada

19há 20 diasAinda não revisado
Ver Repositório

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2010-4221 — Estouro de Pilha TELNET IAC no ProFTPD: Do Patch ao RCE

Um laboratório totalmente reproduzível e um exploit escrito à mão, usando raw sockets, para CVE-2010-4221 — o estouro de buffer na pilha pré-autenticação em pr_netio_telnet_gets() do ProFTPD — construído como exercício de aprendizado em pesquisa de vulnerabilidades e desenvolvimento de exploits.

Cada falha está documentada. O caminho feliz é uma mentira; os desvios são a lição.


Aviso legal e ético — leia isto primeiro

Este repositório é um artefato educacional. Ele existe para que pessoas que não podem pagar por um mentor ou treinamento possam aprender como um exploit de corrupção de memória realmente nasce: de um patch, através de falhas, até uma prova de conceito funcional dentro de um laboratório que você possui.

Trabalho de Red Team — segurança ofensiva real e profissional — é definido por uma palavra: autorização. Tudo o que um profissional faz acontece dentro de um acordo escrito: um documento de Regras de Engajamento assinado que nomeia o escopo, os alvos, as técnicas permitidas, a janela de tempo e as pessoas que o aprovaram. Sem esse papel, exatamente as mesmas teclas digitadas não são uma profissão — são um crime em praticamente todas as jurisdições da Terra.

Então aqui está o contrato para este repositório, inegociável:

  • Execute isto apenas contra o laboratório Docker incluído ou sistemas que você possui.
  • Nunca contra qualquer coisa sem autorização explícita e por escrito.
  • Se você está aprendendo: bem-vindo, isto foi construído para você.
  • Se você está procurando uma arma para usar contra outros: feche esta aba. Este bug é de 2010; ele não lhe trará nada além de uma ficha criminal.

O ofício vale a pena ser aprendido. O ofício só vale algo com a disciplina que o acompanha.


O bug

O ProFTPD fala sequências de escape TELNET no canal de controle FTP. Em TELNET, 0xFF (IAC, "Interpret As Command") é o byte de escape; um 0xFF literal é enviado como 0xFF 0xFF.

pr_netio_telnet_gets() copia bytes do cliente para um buffer na pilha (char buf[PR_DEFAULT_CMD_BUFSZ+1] do pr_cmd_read, 4104 bytes com MAXPATHLEN=4096 do glibc), rastreando o espaço restante em buflen — um size_t, sem sinal.

O caminho vulnerável (1.3.3a, netio.c):

root@kitploit:~
case TELNET_IAC:
  switch (cp) {
    ...
    default:
      *bp++ = TELNET_IAC;   // escrita #1
      buflen--;             // decremento #1
      telnet_mode = 0;
      break;
  }
  break;
...
*bp++ = cp;                 // escrita #2
buflen--;                   // decremento #2  <-- nenhuma verificação entre eles

Duas escritas, dois decrementos, nenhuma verificação de zero entre eles. Quando buflen é exatamente 1, o par o decrementa para 0, então sofre underflow para SIZE_MAX (18 quintilhões). O loop agora acredita que o buffer é infinito e continua escrevendo bytes controlados pelo atacante pilha acima — sobre registradores salvos, RBP salvo e o endereço de retorno.

Pré-autenticação. A função é executada antes de USER/PASS serem sequer processados.

O patch

A correção (commit 3cc69b8388, "Bug#3521 - Telnet IAC processing stack overflow", lançado em 1.3.3c) tem doze linhas. Toda a fronteira de segurança é:

root@kitploit:~
if (buflen == 0) {
  break;
}

Veja patch.diff. Ler o patch lhe diz onde estava a ferida — essa é a habilidade.

O laboratório

O Dockerfile compila o ProFTPD 1.3.3a a partir do código-fonte do snapshot histórico do Debian, deliberadamente inseguro (é assim que 2010 parecia):

  • -fno-stack-protector — sem canário
  • -z execstack — pilha executável (sem NX)
  • -no-pie — endereços binários fixos
  • executado sob gdb, que desativa ASLR por padrão → pilha determinística
root@kitploit:~
docker build -t proftpd-133a .
docker rm -f lab133 2>/dev/null
docker run -d --name lab133 --cap-add SYS_PTRACE \
  --security-opt seccomp=unconfined -p 127.0.0.1:2122:21 \
  proftpd-133a sh -c 'gdb -batch -ex "set follow-fork-mode child" \
  -ex "run" -ex "continue" --args /usr/local/sbin/proftpd -n -d1 \
  > /tmp/gdb.txt 2>&1; sleep 600'
python3 exploit.py

Saída esperada:

root@kitploit:~
[S] 220 ProFTPD 1.3.3a Server (lab-iac) ...
[S] THE SERVER SAID: b'PWNED!!PWNED!!'

(O shellcode escreve nos fds 0, 1 e 2 porque não queríamos depender de saber qual deles carrega o canal de controle — dois deles respondem.)

A arquitetura do exploit

root@kitploit:~
"SITE " + trenó de NOPs + shellcode + [inundação \xff\xff] + preenchimento + [ret] + "\n"
 ^^^^^^^^^^^^^^^^^^^^                             ^^^^
 o shellcode vive DENTRO do buffer              a cauda do estouro apenas
 do comando — a região que ninguém toca         entrega UM endereço
  1. "SITE " mantém o parser FTP vivo — o comando é processado limpo.
  2. O shellcode é o conteúdo do comando. O buffer é o lugar mais seguro na pilha: após a leitura, apenas buf[4102] é tocado (NUL de truncamento). Tudo abaixo das variáveis locais vivas do frame está calmo.
  3. A inundação IAC leva buflen ao underflow (veja "A jornada" para o problema de paridade).
  4. O slot de ret (buf + 4152) recebe o endereço do meio do trenó de NOPs. Quando pr_cmd_read atinge return 0 após o parsing, a CPU aterrissa no trenó e desliza para dentro do shellcode.

Esta arquitetura invertida — payload primeiro, inundação em segundo, endereço por último — foi validada contra o módulo canônico do Metasploit (proftp_telnet_iac), que usa o mesmo layout. Os alvos deles tinham NX, então precisavam de uma cadeia ROP com um "quádruplo deref" do ponteiro res; nosso laboratório tem pilha executável, então um único retorno direto é suficiente.

A jornada (o ponto real deste repositório)

O exploit final tem 60 linhas. O que custou:

  1. Inundação \xff cega → nada. O servidor educadamente fechou a sessão. Causa raiz: buflen começa em 4102 (PAR) e cada par IAC decrementa em 2 — ele aterrissa em 0 limpo, nunca em 1. O underflow precisa de paridade quebrada. Lição: ler a máquina de estados vence pulverizar.

  2. Tamanho de buffer errado. A primeira tentativa calibrada assumiu um buffer de 1024 bytes. O real é MAXPATHLEN+8 = 4104 no Linux/glibc. A inundação parou 3KB antes do alvo. Lição: meça o alvo, não assuma o alvo.

  3. Primeiro SIGSEGV. Padrão cíclico de Bruijn (Aa0Aa1...) colocou o slot de retorno em buf+4152, validado de forma cruzada duas vezes (matemática do frame + deslocamento do padrão). Lição: o padrão cíclico é uma fita métrica, não um exploit.

  4. Controle de RIP. Definir o slot para 0x4141414141414141 travou a própria instrução ret — x86-64 recusa endereços não canônicos, e a falha aterrissa em ret, com nosso valor esperando no backtrace. Lição: um crash em ret com seu valor no frame = controle.

  5. Shellcode acima do slot de ret → corrompido. 8 bytes sobrescritos por um ponteiro de heap (0x4d7838 — posteriormente identificado como a alocação do pool cmd_rec). Os frames de pilha acima do slot pertencem a funções ainda trabalhando entre o pouso e o sequestro. Lição: o estouro não é a última escrita; o programa continua vivendo na pilha que você acabou de vandalizar.

  6. "Zona morta" abaixo do slot → também rabiscada. As próprias variáveis locais de pr_cmd_read (cmd, buflen, cp) vivem bem ali e continuam sendo armazenadas durante o parsing.

  7. Investigação forense com watchpoint de hardware. watch *(long*)ADDR no gdb transformou o mistério em uma câmera: cada escrita no endereço corrompido, com backtrace, em ordem. Lição: quando a pergunta é "quem escreveu esta memória?", a resposta está a um comando do gdb de distância.

  8. Leia a referência, depois entenda-a. O módulo canônico confirmou a arquitetura invertida. Ler outro exploit depois de construir seu próprio modelo mental é estudo; antes, é cópia.

Lições aprendidas

  • size_t nunca fica negativo — ele fica gigantesco. Underflow inteiro em um contador de espaço restante é um estouro de pilha com passos extras.
  • Paridade é uma arma. Quando uma primitiva decrementa de 2 em 2, você controla o underflow controlando ímpar/par, não apenas o tamanho.
  • Caracteres ruins são uma questão de protocolo. Nosso shellcode evita \x0a (termina a leitura) e sobrevive a \xff (escape TELNET) por design.
  • Servidores prefork perdoam crashes. O filho morre, o pai continua aceitando: tentativas infinitas. Engenharia de confiabilidade faz parte do exploit.
  • Meça e explore o mesmo artefato. Uma diferença de 11 bytes em argv[0] (binário da árvore de build vs binário instalado) deslocou toda a pilha em 0x40 e invalidou silenciosamente um exploit perfeito.
  • O manipulador de sinais confessa. O ProFTPD captura SIGSEGV e registra "terminating (signal 11)" — o alvo lhe diz que morreu, mesmo quando o kernel permanece quieto.

Referências

  • Commit da correção: https://github.com/proftpd/proftpd/commit/3cc69b8388
  • CVE: https://nvd.nist.gov/vuln/detail/CVE-2010-4221
  • Módulo canônico: modules/exploits/linux/ftp/proftp_telnet_iac.rb (rapid7/metasploit-framework)
  • Laboratório irmão (bug de lógica, mesmo daemon): CVE-2015-3306 mod_copy

Autor

Construído por diegslva, aprendendo em público — de "nunca escrevi um exploit" a RCE pré-autenticação com shellcode feito à mão, em um dia documentado. Se este repositório lhe ensinou algo, retribua.

Baixar ferramenta