Skip to content
KitploitKITPLOIT
工具博客
Log in
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
exim-rce-cve-2018-6789 — 该仓库提供了一个学习环境,用于理解针对CVE-2018-6789的Exim远程代码执行漏洞利用的工作原理。 | Kitploit
工具/GitHubGitHub/martinclauss/exim-rce-cve-2018-6789
漏洞分析漏洞利用调试器学习与教育二进制利用实验室与实践
GitHubmartinclauss/exim-rce-cve-2018-6789

exim-rce-cve-2018-6789

该仓库提供了一个学习环境,用于理解针对CVE-2018-6789的Exim远程代码执行漏洞利用的工作原理。

查看仓库
117172个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Exim RCE (CVE-2018-6789) 学习环境

描述

这是一套文件、脚本、笔记等,用于搭建环境以研究 Exim RCE (CVE-2018-6789)。可用于调试 Exim、编写漏洞利用代码、追踪 Exim 函数调用、了解 Exim 自定义内存管理(storeblocks)、理解真实世界漏洞利用的工作原理等。

仅应用于学术目的!

要求

  • Vagrant 配合 libvirt/KVM(vagrant-libvirt 插件)
  • Docker(仅当你决定在宿主机上运行 Docker 而非在 Vagrant 虚拟机内时)

设置

通过执行以下命令下载 Exim 的源代码:

$ git submodule update --init

虚拟机

根目录下有一个 Vagrantfile。它使用 libvirt 作为虚拟化提供程序。该 box 通过 box_url 直接从 Fedora 镜像拉取,因为 Vagrant Cloud 下载目前不可用(HCP 迁移);Fedora 仅在那里发布 libvirt 和 VirtualBox 的 box(无 VMware),且直接 box_url 是提供程序相关的,因此此配置仅针对 libvirt。

# -*- mode: ruby -*-
# vi: set ft=ruby :

memory = 8192 # 单位 MiB
cpus = 4

Vagrant.configure("2") do |config|
  # Vagrant Cloud 下载不可用;从 Fedora 镜像拉取 box
  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

你可以根据需要更改配置,但请注意,例如 setup_vm.sh 脚本使用 dnf 安装软件包。如果你想使用 Ubuntu,则必须将 dnf install 替换为 apt-get install 并调整相应的软件包名称。然而,不保证配置能正确工作。

当配置文件满意后,只需运行:

$ vagrant up

来设置机器,然后运行:

$ vagrant ssh

来连接到它。如果你不了解如何使用 Vagrant,请参考:https://www.vagrantup.com/intro/getting-started/

Docker 容器

Vagrant 将当前目录(即你刚刚克隆的仓库)作为共享目录映射到 /vagrant。要创建并运行 Exim 的 Docker 镜像,请在虚拟机内部(vagrant ssh)输入以下命令:

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

第一次会花费更长时间,因为 Exim 将从源码构建。如果你修改了调试脚本或其他将被复制到 Docker 容器中的文件,可以随时使用 ./scripts/reset_docker.sh 重新构建 Docker 镜像。当然,你也可以只提取脚本中的必要行,作为单独命令执行。

一切完成后,你应该会看到一个 root 控制台:

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

这些奇怪的字符串在你的机器上可能看起来不同,但你现在已处于一个 Debian Docker 容器中,该容器运行在宿主机的 Fedora VM 内。

虚拟机与容器的使用

首先,你可以在两个终端窗口中分别通过 vagrant ssh 创建两个 SSH 会话。一个用于运行漏洞利用代码并通过 SMTP 与 Exim 交互。另一个用于在 Docker 容器中启动、运行、调试 Exim。ASLR 在虚拟机中已禁用,因此你可以设置可靠的断点,这些断点在调试会话期间不会改变。

示例会话:

第一个终端:

$ vagrant ssh
[vagrant@localhost vagrant]$

第二个终端:

$ vagrant ssh
[vagrant@localhost vagrant]$ cd /vagrant
[vagrant@localhost vagrant]$ ./scripts/reset_docker.sh
...
# 现在你已进入 Debian Docker 容器
root@99296cf63016:/opt# ./run_exim.sh
root@99296cf63016:/opt# ./attach_exim.sh

run_exim.sh 脚本退出后,Exim 在后台运行。./attach_exim.sh 脚本会将 gdb 附加到正在运行的 Exim 守护进程上,并显示类似如下的输出:

...
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 正在运行并等待请求。设置的断点来自 debugging/breakpoints 文件。你可以使用 Ctrl+C 中断进程并将控制权交给 gdb。你还可以运行提供的某个漏洞利用脚本,以测试一切是否按预期工作:

第一个终端:

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

第二个终端:

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>

你可以用 d 删除所有断点,然后用 c 继续执行,让 sploit_0.py 脚本运行直至退出:

第二个终端:

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

第一个终端:

...
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

如果你刚才调试的(附加到的)派生进程退出(例如 [Inferior 2 (process 42) exited with code 01]),你可以退出 gdb 并重新运行 ./attach_exim.sh。

GDB 脚本

在 debugging 目录下可以找到一些可能有用的脚本。其中之一是 showmem.py,它允许你检查 Exim 的 storeblocks 以及相应的堆块。你可以在 gdb 中使用 smem 命令运行它:

下载工具