Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
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
exim-rce-cve-2018-6789 — Este repositório fornece um ambiente de aprendizado para entender como um exploit RCE do Exim para CVE-2018-6789 funciona. | Kitploit
Ferramentas/GitHubGitHub/martinclauss/exim-rce-cve-2018-6789
Análise de VulnerabilidadesExploraçãoDepuradoresAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHubmartinclauss/exim-rce-cve-2018-6789

exim-rce-cve-2018-6789

Este repositório fornece um ambiente de aprendizado para entender como um exploit RCE do Exim para CVE-2018-6789 funciona.

Ver Repositório
1172há 1 mêsAinda 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

Ambiente de Aprendizagem Exim RCE (CVE-2018-6789)

Descrição

Este é um conjunto de ficheiros, scripts, notas, ... para configurar um ambiente para investigar o Exim RCE (CVE-2018-6789). Pode ser utilizado para depurar o Exim, escrever exploits, rastrear chamadas de funções do Exim, aprender sobre a gestão de memória personalizada do Exim (storeblocks), descobrir como funciona um exploit do mundo real, ...

Deve ser utilizado apenas para fins académicos!

Requisitos

  • Vagrant com libvirt/KVM (o plugin vagrant-libvirt)
  • Docker (apenas se decidir executar Docker no seu host e não dentro da VM Vagrant)

Configuração

Descarregue o código fonte do Exim executando

root@kitploit:~
$ git submodule update --init

VM

Existe um Vagrantfile no diretório raiz. Utiliza libvirt como fornecedor de virtualização. A box é obtida diretamente do espelho do Fedora via porque as transferências do Vagrant Cloud estão atualmente quebradas (migração HCP); o Fedora publica apenas boxes libvirt e VirtualBox lá (sem VMware), e um direto é específico do fornecedor, portanto esta configuração visa apenas libvirt.

box_url
box_url
root@kitploit:~
# -*- mode: ruby -*-
# vi: set ft=ruby :

memory = 8192 # em MiB
cpus = 4

Vagrant.configure("2") do |config|
  # Transferências do Vagrant Cloud estão quebradas; puxar a box do espelho do Fedora
  config.vm.box = "fedora-44-cloud-base"
  config.vm.box_url = "https://download.fedoraproject.org/pub/fedora/linux/releases/44/Cloud/x86_64/images/Fedora-Cloud-Base-Vagrant-libvirt-44-1.7.x86_64.vagrant.libvirt.box"

  config.vm.provider "libvirt" do |lv|
    lv.memory = memory
    lv.cpus = cpus
  end

  config.vm.provision "shell", inline: <<-SHELL
  	/vagrant/scripts/setup_vm.sh
  SHELL
end

Pode alterar a configuração conforme desejar, mas tenha em mente que, por exemplo, o script setup_vm.sh usa dnf para instalar pacotes. Se quiser usar Ubuntu, deve substituir as linhas dnf install por apt-get install e ajustar os nomes dos pacotes em conformidade. No entanto, não há garantia de que a configuração funcione corretamente.

Quando estiver satisfeito com a sua configuração, basta executar:

root@kitploit:~
$ vagrant up

para configurar a máquina e depois

root@kitploit:~
$ vagrant ssh

para se conectar a ela. Se não souber como usar o Vagrant, veja aqui: https://www.vagrantup.com/intro/getting-started/

Contentor Docker

O Vagrant mapeia o diretório atual (ou seja, o repositório que acabou de clonar) como um diretório partilhado para /vagrant. Para criar e executar a imagem Docker para o Exim, insira os seguintes comandos dentro da sua VM (vagrant ssh)

root@kitploit:~
[vagrant@localhost ~]$ cd /vagrant
[vagrant@localhost vagrant]$ ./scripts/reset_docker.sh

A primeira vez demorará muito mais porque o Exim será compilado a partir do código fonte. Se modificar scripts de depuração ou outros ficheiros que serão copiados para o contentor docker, pode sempre usar ./scripts/reset_docker.sh para reconstruir a imagem Docker. Certamente, também pode extrair apenas as linhas necessárias do script e executá-las como comandos individuais.

Quando tudo estiver concluído, deverá ver uma consola root:

root@kitploit:~
Successfully tagged exim:latest
787f310ef922a1e519cf8bb47f1c4fed5f510da705e7ceefd48f160c980e969c
root@787f310ef922:/opt#

As strings estranhas podem parecer diferentes na sua máquina, mas agora está num contentor Debian Docker a executar dentro de uma VM Fedora na sua máquina host.

Utilização da VM e do contentor

Primeiro, pode criar duas sessões SSH com vagrant ssh em duas janelas de terminal. Uma pode ser usada para executar exploits e interagir com o Exim via SMTP. A outra é usada para iniciar, executar, depurar, ... o Exim dentro do contentor Docker. ASLR está desativado na VM, para que possa definir pontos de interrupção fiáveis que não mudem durante as sessões de depuração.

Exemplo de sessão:

Primeiro terminal:

root@kitploit:~
$ vagrant ssh
[vagrant@localhost vagrant]$

Segundo terminal:

root@kitploit:~
$ vagrant ssh
[vagrant@localhost vagrant]$ cd /vagrant
[vagrant@localhost vagrant]$ ./scripts/reset_docker.sh
...
# agora está dentro do contentor Debian Docker
root@99296cf63016:/opt# ./run_exim.sh
root@99296cf63016:/opt# ./attach_exim.sh

O script run_exim.sh termina e o Exim executa em segundo plano. O script ./attach_exim.sh deve anexar gdb ao processo do daemon Exim em execução e dar-lhe um resultado como este:

root@kitploit:~
...
pwndbg: loaded 170 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)

Attaching to process 14
Reading symbols from /usr/exim/bin/exim-4.89_1-1-fc6d6586-XX-1...done.
...
0x00007ffff6b7f5e3 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:84
84	../sysdeps/unix/syscall-template.S: No such file or directory.
Breakpoint 1 at 0x5555555c03d2: file smtp_in.c, line 1762.
Breakpoint 2 at 0x5555555c051d: file smtp_in.c, line 1884.
Breakpoint 3 at 0x55555556a2c8: file base64.c, line 154.
Breakpoint 4 at 0x5555555c6aca: file smtp_in.c, line 3690.

O Exim está em execução e à espera de pedidos. Os pontos de interrupção que foram definidos vêm do ficheiro debugging/breakpoints. Pode usar Ctrl+C para interromper o processo e dar controlo ao gdb. Também pode executar um dos scripts de exploit fornecidos para testar se tudo está a funcionar como esperado:

Primeiro terminal:

root@kitploit:~
[vagrant@localhost ~]$ cd /vagrant/sploits/
[vagrant@localhost sploits]$ ./sploit_0.py
[+] Opening connection to localhost on port 25: Done

Segundo terminal:

root@kitploit:~
Thread 2.1 "exim" hit Breakpoint 2, smtp_reset (reset_point=reset_point@entry=0x555555843078) at smtp_in.c:1884
1884	{
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
──────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────
 RAX  0x555555843078 ◂— 0x0
 RBX  0x0
 RCX  0x555555824b40 (store_last_get) —▸ 0x555555843078 ◂— 0x0
 RDX  0x555555820b30 (yield_length) ◂— 0x15800001c38
 RDI  0x555555843078 ◂— 0x0
 RSI  0x0
 R8   0x3
 R9   0x52
 R10  0x73
 R11  0x246
 R12  0x5555555ec7fa ◂— 'daemon.c'
 R13  0x555555843078 ◂— 0x0
 R14  0x0
 R15  0x0
 RBP  0x5555555ee3db ◂— and    byte ptr [rax], ah /* '  %s\n' */
 RSP  0x7ffffffbe528 —▸ 0x5555555c31d1 (smtp_setup_msg+67) ◂— mov    dword ptr [rip + 0x260b6d], 0
 RIP  0x5555555c051d (smtp_reset) ◂— push   rbp
────────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────
 ► 0x5555555c051d <smtp_reset>       push   rbp
   0x5555555c051e <smtp_reset+1>     push   rbx
   0x5555555c051f <smtp_reset+2>     sub    rsp, 8
   0x5555555c0523 <smtp_reset+6>     mov    rbp, rdi
   0x5555555c0526 <smtp_reset+9>     mov    qword ptr [rip + 0x263657], 0 <0x555555823b88>
   0x5555555c0531 <smtp_reset+20>    mov    dword ptr [rip + 0x263645], 0 <0x555555823b80>
   0x5555555c053b <smtp_reset+30>    mov    dword ptr [rip + 0x26364f], 0 <0x555555823b94>
   0x5555555c0545 <smtp_reset+40>    mov    dword ptr [rip + 0x263699], 0 <0x555555823be8>
   0x5555555c054f <smtp_reset+50>    mov    dword ptr [rip + 0x263687], 0 <0x555555823be0>
   0x5555555c0559 <smtp_reset+60>    mov    dword ptr [rip + 0x263679], 0 <0x555555823bdc>
   0x5555555c0563 <smtp_reset+70>    mov    dword ptr [rip + 0x263677], 0 <0x555555823be4>
────────────────────────────────────────────[ SOURCE (CODE) ]─────────────────────────────────────────────
In file: /opt/exim/src/src/smtp_in.c
   1879 Returns:    nothing
   1880 */
   1881
   1882 static void
   1883 smtp_reset(void *reset_point)
 ► 1884 {
   1885 recipients_list = NULL;
   1886 rcpt_count = rcpt_defer_count = rcpt_fail_count =
   1887   raw_recipients_count = recipients_count = recipients_list_max = 0;
   1888 cancel_cutthrough_connection("smtp reset");
   1889 message_linecount = 0;
────────────────────────────────────────────────[ STACK ]─────────────────────────────────────────────────
00:0000│ rsp  0x7ffffffbe528 —▸ 0x5555555c31d1 (smtp_setup_msg+67) ◂— mov    dword ptr [rip + 0x260b6d], 0
01:0008│      0x7ffffffbe530 —▸ 0x7ffffffbe600 ◂— 0x0
02:0010│      0x7ffffffbe538 —▸ 0x7ffffffbe540 —▸ 0x555555605f1a ◂— add    byte ptr [rip + 0x25203a73], ah
03:0018│      0x7ffffffbe540 —▸ 0x555555605f1a ◂— add    byte ptr [rip + 0x25203a73], ah
04:0020│      0x7ffffffbe548 —▸ 0x555555843078 ◂— 0x0
05:0028│      0x7ffffffbe550 ◂— 0x0
06:0030│      0x7ffffffbe558 —▸ 0x7ffff6b7f5e3 (__select_nocancel+10) ◂— cmp    rax, -0xfff
07:0038│      0x7ffffffbe560 ◂— 0x7ffffffbe560
──────────────────────────────────────────────[ BACKTRACE ]───────────────────────────────────────────────
 ► f 0     5555555c051d smtp_reset
   f 1     5555555c31d1 smtp_setup_msg+67
   f 2     55555556de43 daemon_go+10909
   f 3     55555556de43 daemon_go+10909
   f 4     555555583ca5 main+21601
   f 5     7ffff6abe2e1 __libc_start_main+241
──────────────────────────────────────────────────────────────────────────────────────────────────────────
Breakpoint smtp_reset
pwndbg>

Pode apagar todos os pontos de interrupção com d e continuar com c para deixar o script sploit_0.py executar até terminar:

Segundo terminal:

root@kitploit:~
Breakpoint smtp_reset
pwndbg> d
pwndbg> c
Continuing.
[Inferior 2 (process 42) exited with code 01]

Primeiro terminal:

root@kitploit:~
...
220 787f310ef922 ESMTP Exim 4.89_1-1-fc6d6586-XX Mon, 02 Mar 2020 14:47:24 +0000
250-787f310ef922 Hello test.example.org [172.17.0.1]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-AUTH PLAIN
250-CHUNKING
250-PRDR
250 HELP

501 Invalid base64 data
[*] Closed connection to localhost port 25

Se o processo bifurcado que acabou de depurar (ao qual se anexou) terminar (por exemplo, [Inferior 2 (process 42) exited with code 01]), pode sair do gdb e executar ./attach_exim.sh novamente.

Scripts GDB

Em debugging pode encontrar alguns scripts que podem ser úteis. Um dos scripts é showmem.py. Permite inspecionar os storeblocks do Exim e os chunks de heap correspondentes. Pode executá-lo dentro do gdb com o comando smem:

root@kitploit:~
pwndbg> smem
...
[SHOWMEM]: 0x5555558402b0: heap chunk of size 0x000004b0 (used) / data:
[SHOWMEM]: 0x555555840760: heap chunk of size 0x00000030 (used) / data: /lib/x86_64-linux-gnu
[SHOWMEM]: 0x555555840790: heap chunk of size 0x00000050 (used) / data: ...UUU
[SHOWMEM]: 0x5555558407e0: heap chunk of size 0x000000e0 (used) / data:
[SHOWMEM]: 0x5555558408c0: heap chunk of size 0x00000370 (free) / data: .~....
[SHOWMEM]: 0x555555840c30: heap chunk of size 0x00000040 (used) / data:
[SHOWMEM]: 0x555555840c70: heap chunk of size 0x00002020 (used) / data:
[SHOWMEM]:   0x555555840c80: storeblock of size 0x00002000      / data:
[SHOWMEM]: 0x555555842c90: heap chunk of size 0x00002020 (used) / data:
[SHOWMEM]:   0x555555842ca0: storeblock of size 0x00002000      / data: root
[SHOWMEM]: 0x555555844cb0: heap chunk of size 0x00008010 (used) / data:
[SHOWMEM]: 0x55555584ccc0: heap chunk of size 0x00002010 (used) / data:
[SHOWMEM]: 0x55555584ecd0: heap chunk of size 0x00001010 (used) / data: 220 99296cf63016 ESMTP Exim 4.89_1-1-fc6d6586-XX M
[SHOWMEM]: 0x55555584fce0: heap chunk of size 0x0001d320 (free) / data:

As regiões de memória indentadas são os storeblocks; as outras regiões são chunks de heap (glibc). Atualmente, isto é uma aproximação, pois não verifiquei os chunks em uso com as listas livres da glibc, portanto pode haver algumas indicações erradas de blocos usados/livres. Pode sempre usar os comandos bins, heap, ... do pwndbg como fonte adicional de informação!

Nota: Com libvirt / KVM, a pasta /vagrant é sincronizada via rsync, portanto, após editar ficheiros no host, execute vagrant rsync (ou mantenha vagrant rsync-auto em execução) para copiar as suas alterações para a VM antes de reconstruir o contentor.

Estrutura

root@kitploit:~
.
├── debugging                # Scripts relacionados com GDB
│   ├── breakpoints
│   ├── gdbinit
│   ├── showmem.py
│   └── trace.py
├── Dockerfile               # Dockerfile para compilar e depurar o Exim
├── Exim                     # Código fonte para a versão vulnerável do Exim
├── exim_code_backup         # cópia de segurança do código fonte vulnerável do Exim
│   └── exim-fc6d65867e82009a6e0671771728d41d3423a790.zip
├── exim_files               # Ficheiros do Exim corrigidos para compilar o Exim corretamente
│   ├── configure
│   ├── eximon.conf
│   ├── Makefile
│   └── Makefile-Linux
├── README.md
├── scripts                  # Scripts auxiliares para depurar o Exim
│   ├── attach_exim.sh
│   ├── reset_docker.sh
│   ├── run_exim.sh
│   └── setup_vm.sh
├── sploits                  # Scripts de exploit incrementais e um script para encontrar o byte 0xf1
│   ├── exim_0xf1.py
│   ├── smtp.py
│   ├── sploit_0.py
│   ├── sploit_1.py
│   ├── sploit_2.py
│   ├── sploit_3.py
│   ├── sploit_4.py
│   ├── sploit_5.py
│   ├── sploit_6.py
│   ├── sploit_7.py
│   ├── sploit_8.py
│   ├── sploit_9.py
│   └── sploit_10.py
└── Vagrantfile              # Vagrantfile para criar a VM que hospeda o contentor Docker

Scripts de Exploit

Os scripts de exploit podem ser encontrados em sploits. Eles são construídos incrementalmente para facilitar a compreensão dos diferentes passos. São quase idênticos aos passos fornecidos por @straightblast426 no medium.com.

sploit_10.py é o script final que deve demonstrar o RCE num único script. Este script não abre uma shell reversa, mas cria um ficheiro em /tmp. Pode modificar isto editando a seguinte linha:

root@kitploit:~
cmd = '/bin/bash -c "touch /tmp/pwned"'

Por favor, note que o script sploit_10.py fornecido não é a única forma de explorar a vulnerabilidade. Existem, por exemplo, outras formas de organizar o heap!

Limitações

O grooming é sensível ao ambiente: mantenha host_lookup = desativado (um nome de cliente DNS reverso polui o heap que o exploit prepara) e o contentor em debian:bullseye (o grooming só sobrevive na glibc 2.31 do Debian, não na do Ubuntu ou do bookworm). Isto também significa que este repositório só funcionará (como está) enquanto existir uma distro disponível que forneça glibc 2.31 (lançada pela primeira vez em 2020)!

O ponteiro next será alterado com um endereço constante previamente conhecido (que também deve funcionar para si se usar a configuração idêntica). Se lançasse este exploit contra outro Exim em execução, não funcionaria (as probabilidades são muito pequenas). Poderia contornar o ASLR com algum brute-force. Isto funciona bastante bem, pois o Exim bifurca (clona) a si próprio para lidar com pedidos de clientes. Isso significa que o layout geral da memória permanece o mesmo e obtém uma hipótese realista de fazer brute-force do ponteiro next. Se não sabe o que é o ponteiro next, deve ler primeiro as referências.

Se compilar o exim de forma ligeiramente diferente, a localização do ponteiro next pode ser diferente. Deve encontrar o endereço do storeblock que contém acl_smtp_rcpt. Siga estes passos e ajuste o ponteiro nos respetivos ficheiros sploit_xx.py:

root@kitploit:~
# conectar à VM com: vagrant ssh
./run_exim.sh
./attach_exim.sh

# pwndbg inicia, depois Ctrl-C
pwndbg> smem
[SHOWMEM]: 0x55555562e6b0: heap chunk of size 0x00002020 (used) / data: .2cUUU
[SHOWMEM]:   0x55555562e6c0: storeblock of size 0x00002000      / data: /usr/exim/configure
...

O storeblock com endereço 0x55555562e6c0 também contém acl_smtp_rcpt:

root@kitploit:~
pwndbg> p acl_smtp_rcpt
$1 = (uschar *) 0x55555562e7f0 "acl_check_rcpt"

Então, nos scripts de exploit, substitua-o pelo endereço conforme exibido com o comando smem:

root@kitploit:~
# ...
# endereço do storeblock das strings ACL (não do chunk)
address_of_acl_storeblock = 0x55555562E6C0
# ...

Referências

  • https://devco.re/blog/2018/03/06/exim-off-by-one-RCE-exploiting-CVE-2018-6789-en/ (backup)
  • https://medium.com/@straightblast426/my-poc-walk-through-for-cve-2018-6789-2e402e4ff588 (backup)
Baixar ferramenta