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-2018-6789 — Exploit para CVE-2018-6789, um estouro de buffer no heap na decodificação base64 do Exim, alcançando execução remota de código por meio de sobreposição de chunks e manipulação de strings ACL. | Kitploit
Ferramentas/GitHubGitHub/beraphin/cve-2018-6789
Análise de VulnerabilidadesExploraçãoCTFAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHubberaphin/cve-2018-6789

CVE-2018-6789

Exploit para CVE-2018-6789, um estouro de buffer no heap na decodificação base64 do Exim, alcançando execução remota de código por meio de sobreposição de chunks e manipulação de strings ACL.

Ver Repositório
316há 6 anosAinda não revisado

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-2018-6789

Configuração do Ambiente

Instalar dependências

apt-get install gcc net-tools vim gdb python wget git make procps libpcre3-dev libdb-dev libxt-dev libxaw7-dev

Baixar versão antiga do exim

wget ftp://mirror.easyname.at/exim-ftp/exim/exim4/old/exim-4.89.tar.gz
tar -xvzf ./exim-4.89.tar.gz
cd ./exim-4.89
cp src/EDITME Local/Makefile
cp exim_monitor/EDITME Local/eximon.conf

Em seguida, modificar Local/Makefile Para conveniência, todos os diretórios apontam para o diretório atual

BIN_DIRECTORY=/home/zzx/EVA/cve-2018-6789/exim-4.89/bin
CONFIGURE_FILE=/home/zzx/EVA/cve-2018-6789/exim-4.89/configure
SPOOL_DIRECTORY=/home/zzx/EVA/cve-2018-6789/exim-4.89/exim
EXIM_USER=zzx
AUTH_PLAINTEXT=yes
AUTH_CRAM_MD5=yes
AUTH_TLS=yes

Isso facilita a depuração Depois compilar e instalar

make install

Modificar ./configure, sobrescrever com o conteúdo abaixo

acl_smtp_mail=acl_check_mail
acl_smtp_data=acl_check_data
begin acl
acl_check_mail:
  .ifdef CHECK_MAIL_HELO_ISSUED
  deny
    message = no HELO given before MAIL command
    condition = ${if def:sender_helo_name {no}{yes}}
  .endif

  accept

acl_check_data:
  accept

begin authenticators
fixed_cram:
  driver = cram_md5
  public_name = CRAM-MD5
  server_secret = ${if eq{$auth1}{ph10}{secret}fail}
  server_set_id = $auth1

Execução

./bin/exim -bd -d-receive

Análise da Vulnerabilidade

Primeiro, analisar o patch em base64.c: 1 Onde result é o buffer que armazena o resultado da decodificação base64, obtido pela função store_get Pode-se observar que o cálculo do size antes do patch está incorreto. Quando size está no intervalo 4n~4n+3, o tamanho calculado é igual, mas quando b64decode decodifica um parâmetro que não é múltiplo de 4, ele decodifica um ou dois bytes extras.

Por exemplo, enviando diretamente

auth_md5('Hf'*42)

size=0x40
Distribuição de memória resultante:

pwndbg> hexdump 0x711d60 0x50
+0000 0x711d60  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0010 0x711d70  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  │....│....│....│....│
+0020 0x711d80  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  │....│....│....│....│
+0030 0x711d90  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 00  │....│....│....│....│
+0040 0x711da0  20 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │.aaa│aaaa│aaaa│aaaa│

Testando novamente

auth_md5('Hf'*42+'HfH')

size=0x40

pwndbg> hexdump 0x711d60 0x50
+0000 0x711d60  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0010 0x711d70  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  │....│....│....│....│
+0020 0x711d80  df 1d f1 df  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  │....│....│....│....│
+0030 0x711d90  1d f1 df 1d  f1 df 1d f1  df 1d f1 df  1d f1 df 1d  │....│....│....│....│
+0040 0x711da0  f1 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │.aaa│aaaa│aaaa│aaaa│

Transbordou dois bytes

Mecanismo de Gerenciamento de Memória do Exim

Para melhorar o desempenho, o exim implementa seu próprio mecanismo de gerenciamento de memória sobre o mecanismo de heap padrão. Ele funciona como um buffer intermediário entre o código e o glibc, com o objetivo de reduzir o número de chamadas malloc e free 2 Para o exim, cada bloco de heap individual é chamado de storeblock. Cada vez que é usado, um buffer de tamanho apropriado é alocado a partir dele. Se um storeblock for completamente usado, outro storeblock é alocado via malloc. Para cada storeblock, sua estrutura é uma simples lista encadeada:

/* Structure describing the beginning of each big block. */
typedef struct storeblock {
  struct storeblock *next;
  size_t length;
} storeblock;

As principais APIs usadas pelo programa para gerenciamento de heap estão em store.c:

store_get
store_release
store_extend
store_reset

store_get é usado para obter um buffer. O código principal é o seguinte:

128 void *
129 store_get_3(int size, const char *filename, int linenumber)
....
145   int length = (size <= STORE_BLOCK_SIZE)? STORE_BLOCK_SIZE : size;
...
161   /* If there was no free block, get a new one */
162 
163   if (!newblock)
164     {
165     pool_malloc += mlength;           /* Used in pools */
166     nonpool_malloc -= mlength;        /* Exclude from overall total */
167     newblock = store_malloc(mlength);
...

Pode-se observar que o tamanho mínimo de um store_block solicitado é STORE_BLOCK_SIZE, ou seja, 8192.

Portanto, um store_block de tamanho 8192, adicionando seu cabeçalho de estrutura e o cabeçalho do heap, resulta em um tamanho total de 0x2020 3

Quando o exim executa um comando enviado pelo cliente e o comando é bem-sucedido, ele chama store_reset para liberar o cache desnecessário e os store_block excedentes. "Execução bem-sucedida" aqui inclui comandos com formato correto, e-mail sem caracteres ilegais, etc. Caso contrário, store_reset não é chamado.

Estratégia de Exploração

Esta vulnerabilidade é um clássico off-by-one (embora na verdade possa transbordar dois bytes). No entanto, como o número de bytes que transbordam é pequeno, não é possível sobrescrever diretamente estruturas sensíveis no heap. Portanto, é necessário usar algumas características do ptmalloc para ampliar o impacto da vulnerabilidade, transformando-a em um overflow de maior alcance, ou overlap. Para vulnerabilidades off-by-one, existe um método clássico: chunk enlarge -> chunk overlap. Ao aumentar o size de um chunk e forjar um cabeçalho de chunk para burlar a verificação de sanidade do glibc, é possível obter sobreposição de chunks e causar uma cobertura maior.

O processo principal é: chunk enlarge -> chunk overlap -> corromper o ponteiro next no storeblock, então acionar store_reset para liberar um chunk arbitrário. Ao solicitar esse chunk novamente, podemos modificar seu conteúdo (type confusion). Meh no artigo recomenda modificar o chunk onde a string ACL está localizada, porque no processamento da string ACL existe uma funcionalidade de execução de comandos. As strings ACL são muitas, mas a maioria é NULL (provavelmente relacionada ao arquivo de configuração). Aqui escolho a string acl_smtp_mail, cuja sintaxe para executar comandos é

${run{command}}

O layout aproximado do heap é o seguinte 4

O primeiro chunk é o chunk resultante da decodificação base64, usado para o off-by-one. Portanto, ele deve estar no final de um storeblock. Por conveniência, solicito diretamente um chunk maior que 0x2020 para armazenar o resultado da decodificação base64; O segundo chunk é sender_helo_name, usado para sobrescrever o próximo chunk. sender_helo_name não é armazenado em storeblock, mas alocado diretamente via malloc:

1832 static BOOL
1833 check_helo(uschar *s)
1834 {
...
1884 if (yield) sender_helo_name = string_copy_malloc(start);

Portanto, o tamanho é arbitrário; O terceiro chunk é o chunk resultante da decodificação base64, usado principalmente para forjar o cabeçalho e ser sobrescrito. Portanto, ele deve estar no início de um storeblock. Por conveniência, também solicito diretamente o tamanho 0x2020.

Exploit

Meu exploit também foi obtido passo a passo seguindo análises de outras pessoas na internet. A ideia geral permanece a mesma, mas o layout do heap é um pouco diferente, então alguns parâmetros pequenos são diferentes.

Baixar ferramenta