Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
exim-rce-cve-2018-6789 — このリポジトリは、CVE-2018-6789 の Exim RCE エクスプロイトがどのように動作するかを理解するための学習環境を提供します。 | Kitploit
ツール/GitHubGitHub/martinclauss/exim-rce-cve-2018-6789
脆弱性分析エクスプロイトデバッガ学習と教育バイナリエクスプロイトラボと実践
GitHubmartinclauss/exim-rce-cve-2018-6789

exim-rce-cve-2018-6789

このリポジトリは、CVE-2018-6789 の Exim RCE エクスプロイトがどのように動作するかを理解するための学習環境を提供します。

リポジトリを見る
11721ヶ月前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Exim RCE (CVE-2018-6789) 学習環境

説明

これは、Exim RCE (CVE-2018-6789) を調査するための環境を構築するための、一連のファイル、スクリプト、メモなどのセットです。Exim のデバッグ、エクスプロイトの作成、Exim 関数呼び出しのトレース、Exim のカスタムメモリ管理 (storeblocks) についての学習、実際のエクスプロイトがどのように機能するかを調べるために使用できます。

これは学術的な目的のみに使用するべきです!

要件

  • libvirt/KVM を備えた Vagrant (vagrant-libvirt プラグイン)
  • Docker (Vagrant VM 内ではなく、ホスト上で Docker を実行する場合のみ)

セットアップ

次のコマンドを実行して Exim のソースコードをダウンロードします

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

VM

ルートディレクトリに Vagrantfile があります。これは仮想化プロバイダーとして libvirt を使用します。Vagrant Cloud のダウンロードが現在壊れているため (HCP 移行)、ボックスは box_url を介して Fedora のミラーから直接取得されます。Fedora はそこに libvirt と VirtualBox のボックスのみを公開しており (VMware はなし)、直接の box_url はプロバイダー固有であるため、このセットアップは 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

設定はお好みで変更できますが、例えば setup_vm.sh スクリプトは dnf を使用してパッケージをインストールすることに注意してください。Ubuntu を使用したい場合は、dnf install の行を apt-get install に置き換え、パッケージ名を適宜調整する必要があります。ただし、セットアップが正しく動作する保証はありません。

設定に満足したら、次のコマンドを実行するだけです:

root@kitploit:~
$ vagrant up

マシンをセットアップしたら、次を実行します:

root@kitploit:~
$ vagrant ssh

接続します。Vagrant の使い方がわからない場合は、こちらを参照してください: https://www.vagrantup.com/intro/getting-started/

Docker コンテナ

Vagrant はカレントディレクトリ (つまり、クローンしたばかりのリポジトリ) を共有ディレクトリとして /vagrant にマップします。Exim 用の Docker イメージを作成して実行するには、VM 内 (vagrant ssh) で次のコマンドを入力します。

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

初回は Exim がソースからビルドされるため、はるかに時間がかかります。デバッグスクリプトや、Docker コンテナにコピーされる他のファイルを変更した場合は、いつでも ./scripts/reset_docker.sh を使用して Docker イメージを再ビルドできます。もちろん、スクリプトから必要な行だけを抜き出して、単一のコマンドとして実行することもできます。

すべてが完了すると、root コンソールが表示されるはずです:

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

奇妙な文字列はお使いのマシンでは異なって見えるかもしれませんが、ホストマシン上の Fedora VM 内で実行されている Debian Docker コンテナに入ったことになります。

VM とコンテナの使用方法

まず、2つのターミナルウィンドウで vagrant ssh を使用して2つの SSH セッションを作成できます。1つはエクスプロイトを実行し、SMTP を介して Exim と対話するために使用できます。もう1つは、Docker コンテナ内で Exim を起動、実行、デバッグなどに使用します。VM では ASLR が無効になっているため、デバッグセッション中に変わらない信頼性の高いブレークポイントを設定できます。

セッション例:

最初のターミナル:

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

2番目のターミナル:

root@kitploit:~
$ vagrant ssh
[vagrant@localhost vagrant]$ cd /vagrant
[vagrant@localhost vagrant]$ ./scripts/reset_docker.sh
...
# now you are inside the Debian Docker container
root@99296cf63016:/opt# ./run_exim.sh
root@99296cf63016:/opt# ./attach_exim.sh

run_exim.sh スクリプトは終了し、Exim はバックグラウンドで実行されます。./attach_exim.sh スクリプトは、実行中の Exim デーモンプロセスに gdb をアタッチし、次のような出力を表示するはずです:

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 は実行され、リクエストを待機しています。設定されたブレークポイントは debugging/breakpoints ファイルに由来します。Ctrl+C を使用してプロセスを中断し、gdb に制御を渡すことができます。提供されているエクスプロイトスクリプトのいずれかを実行して、すべてが期待どおりに動作するかテストすることもできます:

最初のターミナル:

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

2番目のターミナル:

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>

d ですべてのブレークポイントを削除し、c で継続して sploit_0.py スクリプトを終了まで実行させることができます:

2番目のターミナル:

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

最初のターミナル:

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

デバッグしていたフォークされたプロセス (アタッチしていたプロセス) が終了した場合 (例: [Inferior 2 (process 42) exited with code 01])、gdb を終了して ./attach_exim.sh を再度実行できます。

GDB スクリプト

debugging の下に、役立つかもしれないスクリプトがいくつかあります。そのうちの1つは showmem.py です。これを使用すると、Exim の storeblock と対応するヒープチャンクを検査できます。gdb 内で 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:

インデントされたメモリ領域が storeblock で、それ以外の領域は (glibc の) ヒープチャンクです。現在、これは近似値です。使用中チャンクを glibc のフリーリストと照合していないため、使用済み/フリーブロックの表示が一部間違っている可能性があります。追加の情報源として、pwndbg の bins、heap などのコマンドをいつでも使用できます!

注: libvirt / KVM を使用する場合、/vagrant フォルダは rsync で同期されるため、ホスト上でファイルを編集した後、コンテナを再ビルドする前に vagrant rsync を実行するか (vagrant rsync-auto を実行し続けるか) して、変更を VM にコピーしてください。

構造

root@kitploit:~
.
├── debugging                # GDB related scripts
│   ├── breakpoints
│   ├── gdbinit
│   ├── showmem.py
│   └── trace.py
├── Dockerfile               # Dockerfile to build and debug Exim
├── Exim                     # Source code for the vulnerable Exim version
├── exim_code_backup         # backup of the Exim's vulnerable source code
│   └── exim-fc6d65867e82009a6e0671771728d41d3423a790.zip
├── exim_files               # Patched Exim files to build Exim correctly
│   ├── configure
│   ├── eximon.conf
│   ├── Makefile
│   └── Makefile-Linux
├── README.md
├── scripts                  # Helper scripts to debug Exim
│   ├── attach_exim.sh
│   ├── reset_docker.sh
│   ├── run_exim.sh
│   └── setup_vm.sh
├── sploits                  # Incremental exploit scripts and a script to find the 0xf1 byte
│   ├── 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 to create the VM that hosts the Docker container

エクスプロイトスクリプト

エクスプロイトスクリプトは sploits の下にあります。さまざまなステップを理解しやすくするために、段階的に構築されています。これらは medium.com の @straightblast426 が提供した手順とほぼ同じです。

sploit_10.py は、単一のスクリプトで RCE を実演する最終スクリプトです。このスクリプトはリバースシェルを起動するのではなく、/tmp の下にファイルを作成します。これは次の行を編集して変更できます:

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

提供されている sploit_10.py スクリプトが脆弱性を悪用する唯一の方法ではないことに注意してください。たとえば、ヒープを別の方法で整列させる方法もあります!

制限事項

グルーミングは環境に影響されやすいです: host_lookup = を無効のままにし (逆引き DNS クライアント名はエクスプロイトがグルーミングするヒープを汚染します)、コンテナは debian:bullseye のままにしてください (グルーミングは Debian の glibc 2.31 でのみ機能し、Ubuntu や bookworm では機能しません)。これはつまり、glibc 2.31 (2020年に最初にリリース) を提供するディストリビューションが利用可能である限り、このリポジトリは (現状のまま) のみ機能することを意味します!

next ポインタは、事前に判明している定数アドレスに変更されます (まったく同じセットアップを使用する場合、これも機能するはずです)。このエクスプロイトを別の実行中の Exim に仕掛けても機能しません (可能性は非常に低いです)。ある程度のブルートフォースで ASLR をバイパスできます。Exim はクライアントリクエストを処理するためにフォーク (クローン) するため、これはかなりうまく機能します。つまり、全体的なメモリレイアウトは同じままなので、next ポインタをブルートフォースする現実的なチャンスがあります。next ポインタが何かわからない場合は、最初に参考文献を読んでください。

exim を少し異なる方法でビルドすると、next ポインタの位置が異なる可能性があります。acl_smtp_rcpt を含む storeblock のアドレスを見つける必要があります。次の手順に従い、それぞれの sploit_xx.py ファイルのポインタを調整してください:

root@kitploit:~
# connect to VM with: vagrant ssh
./run_exim.sh
./attach_exim.sh

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

アドレス 0x55555562e6c0 の storeblock には acl_smtp_rcpt も含まれています:

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

したがって、エクスプロイトスクリプトでは、smem コマンドで表示されたアドレスに置き換えます:

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

参考文献

  • https://devco.re/blog/2018/03/06/exim-off-by-one-RCE-exploiting-CVE-2018-6789-en/ (バックアップ)
  • https://medium.com/@straightblast426/my-poc-walk-through-for-cve-2018-6789-2e402e4ff588 (バックアップ)
ツールをダウンロード