Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
exim-rce-cve-2018-6789 — Questo repository fornisce un ambiente di apprendimento per capire come funziona un exploit RCE di Exim per CVE-2018-6789. | Kitploit
Strumenti/GitHubGitHub/martinclauss/exim-rce-cve-2018-6789
Analisi delle VulnerabilitàExploitDebuggerApprendimento e FormazioneBinary ExploitationLab e Pratica
GitHubmartinclauss/exim-rce-cve-2018-6789

exim-rce-cve-2018-6789

Questo repository fornisce un ambiente di apprendimento per capire come funziona un exploit RCE di Exim per CVE-2018-6789.

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
1171 mese faNon ancora revisionato

Ambiente di Apprendimento per Exim RCE (CVE-2018-6789)

Descrizione

Questo è un insieme di file, script, appunti, ... per configurare un ambiente in cui investigare la vulnerabilità RCE di Exim (CVE-2018-6789). Può essere utilizzato per eseguire il debug di Exim, scrivere exploit, tracciare le chiamate alle funzioni di Exim, imparare la gestione personalizzata della memoria di Exim (storeblocks), scoprire come funziona un exploit reale, ...

Dovrebbe essere utilizzato solo per scopi accademici!

Requisiti

  • Vagrant con libvirt/KVM (il plugin vagrant-libvirt)
  • Docker (solo se decidi di eseguire Docker sulla tua macchina host e non all'interno della VM Vagrant)

Configurazione

Scarica il codice sorgente di Exim eseguendo

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

VM

Nella directory principale è presente un Vagrantfile. Utilizza libvirt come provider di virtualizzazione. La box viene scaricata direttamente dal mirror di Fedora tramite box_url perché i download da Vagrant Cloud sono attualmente interrotti (migrazione HCP); Fedora pubblica solo box libvirt e VirtualBox su di esso (nessun VMware), e un box_url diretto è specifico del provider, quindi questa configurazione è mirata solo a libvirt.

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

memory = 8192 # in MiB
cpus = 4

Vagrant.configure("2") do |config|
  # Vagrant Cloud downloads are broken; pull the box from Fedora's mirror
  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

Puoi modificare la configurazione come preferisci, ma tieni presente che, ad esempio, lo script setup_vm.sh utilizza dnf per installare i pacchetti. Se vuoi usare Ubuntu, devi sostituire le righe dnf install con apt-get install e adattare i nomi dei pacchetti di conseguenza. Tuttavia, non vi è garanzia che la configurazione funzioni correttamente.

Quando sei soddisfatto della tua configurazione, esegui semplicemente:

root@kitploit:~
$ vagrant up

per configurare la macchina e successivamente

root@kitploit:~
$ vagrant ssh

per connetterti. Se non sai come usare Vagrant, dai un'occhiata qui: https://www.vagrantup.com/intro/getting-started/

Container Docker

Vagrant mappa la directory corrente (cioè il repository che hai appena clonato) come directory condivisa su /vagrant. Per creare ed eseguire l'immagine Docker per Exim, inserisci i seguenti comandi all'interno della tua VM (vagrant ssh)

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

La prima volta ci vorrà molto più tempo perché Exim verrà compilato dal sorgente. Se modifichi script di debug o altri file che verranno copiati nel container Docker, puoi sempre usare ./scripts/reset_docker.sh per ricostruire l'immagine Docker. Ovviamente, puoi anche estrarre le righe necessarie dallo script ed eseguirle come comandi singoli.

Quando tutto è finito, dovresti vedere una console di root:

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

Le strane stringhe potrebbero apparire diverse sulla tua macchina, ma ora ti trovi in un container Docker Debian in esecuzione in una VM Fedora sulla tua macchina host.

Utilizzo della VM e del container

Innanzitutto, puoi creare due sessioni SSH con vagrant ssh in due finestre di terminale. Una può essere utilizzata per eseguire exploit e interagire con Exim tramite SMTP. L'altra viene utilizzata per avviare, eseguire, eseguire il debug, ... di Exim all'interno del container Docker. ASLR è disabilitato nella VM, quindi puoi impostare breakpoint affidabili che non cambiano durante le sessioni di debug.

Esempio di sessione:

Primo terminale:

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

Secondo terminale:

root@kitploit:~
$ vagrant ssh
[vagrant@localhost vagrant]$ cd /vagrant
[vagrant@localhost vagrant]$ ./scripts/reset_docker.sh
...
# ora sei all'interno del container Debian Docker
root@99296cf63016:/opt# ./run_exim.sh
root@99296cf63016:/opt# ./attach_exim.sh

Lo script run_exim.sh termina ed Exim rimane in esecuzione in background. Lo script ./attach_exim.sh dovrebbe collegare gdb al processo demone di Exim in esecuzione e fornire un output come questo:

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.

Exim è in esecuzione e in attesa di richieste. I breakpoint impostati provengono dal file debugging/breakpoints. Puoi usare Ctrl+C per interrompere il processo e dare il controllo a gdb. Potresti anche eseguire uno degli script di exploit forniti per testare se tutto funziona come previsto:

Primo terminale:

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

Secondo terminale:

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>

Puoi eliminare tutti i breakpoint con d e continuare con c per lasciare che lo script sploit_0.py venga eseguito fino a quando non termina:

Secondo terminale:

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

Primo terminale:

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 il processo figlio che hai appena debugato (a cui ti sei collegato) termina (ad es. [Inferior 2 (process 42) exited with code 01]) puoi uscire da gdb ed eseguire di nuovo ./attach_exim.sh.

Script GDB

Sotto debugging puoi trovare alcuni script che potrebbero essere utili. Uno degli script è showmem.py. Ti permette di ispezionare gli storeblocks di Exim e i corrispondenti heap chunks. Puoi eseguirlo all'interno di gdb con il 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:

Le regioni di memoria indentate sono gli storeblocks, le altre regioni sono heap chunks (glibc). Attualmente questa è un'approssimazione poiché non ho incrociato i chunk in uso con le free list di glibc, quindi potrebbero esserci alcune indicazioni errate di blocchi usati/liberi. Puoi sempre usare i comandi bins, heap, ... di pwndbg come fonte aggiuntiva di informazioni!

Nota: Con libvirt / KVM la cartella /vagrant viene sincronizzata tramite rsync, quindi dopo aver modificato i file sull'host esegui vagrant rsync (o tieni in esecuzione vagrant rsync-auto) per copiare le modifiche nella VM prima di ricostruire il container.

Struttura

root@kitploit:~
.
├── debugging                # Script relativi a GDB
│   ├── breakpoints
│   ├── gdbinit
│   ├── showmem.py
│   └── trace.py
├── Dockerfile               # Dockerfile per compilare e fare debug di Exim
├── Exim                     # Codice sorgente per la versione vulnerabile di Exim
├── exim_code_backup         # Backup del codice sorgente vulnerabile di Exim
│   └── exim-fc6d65867e82009a6e0671771728d41d3423a790.zip
├── exim_files               # File di Exim patchati per compilare Exim correttamente
│   ├── configure
│   ├── eximon.conf
│   ├── Makefile
│   └── Makefile-Linux
├── README.md
├── scripts                  # Script di supporto per eseguire il debug di Exim
│   ├── attach_exim.sh
│   ├── reset_docker.sh
│   ├── run_exim.sh
│   └── setup_vm.sh
├── sploits                  # Script di exploit incrementali e uno script per trovare il 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 per creare la VM che ospita il container Docker

Script di Exploit

Gli script di exploit si trovano sotto sploits. Sono costruiti in modo incrementale per rendere più facile comprendere i diversi passaggi. Sono quasi identici ai passaggi forniti da @straightblast426 su medium.com.

sploit_10.py è lo script finale che dovrebbe mostrare l'RCE in un unico script. Questo script non genera una shell inversa ma crea un file in /tmp. Puoi modificarlo modificando la seguente riga:

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

Tieni presente che lo script sploit_10.py fornito non è l'unico modo per sfruttare la vulnerabilità. Esistono, ad esempio, altri modi per organizzare l'heap!

Limitazioni

La preparazione (grooming) è sensibile all'ambiente: mantieni host_lookup = disabilitato (un nome client reverse-DNS inquina l'heap che l'exploit prepara) e il container su debian:bullseye (la preparazione sopravvive solo con la glibc 2.31 di Debian, non con quella di Ubuntu o di bookworm). Ciò significa anche che questo repository funzionerà (così com'è) solo fino a quando sarà disponibile una distribuzione che fornisce glibc 2.31 (rilasciata per la prima volta nel 2020)!

Il puntatore next verrà modificato con un indirizzo noto precedentemente costante (che dovrebbe funzionare anche per te se utilizzi la configurazione identica). Se lanciassi questo exploit contro un altro Exim in esecuzione, non funzionerebbe (le probabilità sono molto piccole). Potresti aggirare ASLR con un po' di brute-forcing. Funziona abbastanza bene poiché Exim si biforca (clona) per gestire le richieste dei client. Ciò significa che la disposizione complessiva della memoria rimane la stessa e hai una possibilità realistica di forzare il puntatore next. Se non sai cos'è il puntatore next, dovresti prima leggere i riferimenti.

Se compili exim in modo leggermente diverso, la posizione del puntatore next potrebbe essere diversa. Devi trovare l'indirizzo dello storeblock che contiene acl_smtp_rcpt. Segui questi passaggi e modifica il puntatore nei rispettivi file sploit_xx.py:

root@kitploit:~
# connettiti alla VM con: vagrant ssh
./run_exim.sh
./attach_exim.sh

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

Lo storeblock con indirizzo 0x55555562e6c0 contiene anche acl_smtp_rcpt:

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

Quindi, negli script di exploit, sostituiscilo con l'indirizzo visualizzato con il comando smem:

root@kitploit:~
# ...
# address of the ACL strings storeblock (not the chunk)
address_of_acl_storeblock = 0x55555562E6C0
# ...

Riferimenti

  • 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)
Scarica lo strumento