Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2018-6789 — Эксплойт для CVE-2018-6789 — переполнение буфера в куче при декодировании base64 в Exim, обеспечивающее удалённое выполнение кода через перекрытие чанков и манипуляцию строками ACL. | Kitploit
Инструменты/GitHubGitHub/beraphin/cve-2018-6789
Анализ уязвимостейЭксплуатацияCTFОбучение и ОбразованиеЭксплуатация Бинарных ФайловЛаборатории и Практика
GitHubberaphin/cve-2018-6789

CVE-2018-6789

Эксплойт для CVE-2018-6789 — переполнение буфера в куче при декодировании base64 в Exim, обеспечивающее удалённое выполнение кода через перекрытие чанков и манипуляцию строками ACL.

Репозиторий
3166 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2018-6789

Настройка окружения

Установка зависимостей

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

Скачать старую версию 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

Затем изменить Local/Makefile Для удобства все каталоги указывают на текущий каталог

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

Это упрощает отладку Затем скомпилировать и установить

make install

Изменить ./configure, просто перезаписать следующим содержимым

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

Запуск

./bin/exim -bd -d-receive

Анализ уязвимости

Сначала проанализируем патч в base64.c: 1 Здесь result — это буфер для хранения результата декодирования base64, полученный с помощью store_get. Можно заметить, что вычисление размера до патча было некорректным: когда size находится в диапазоне 4n~4n+3, вычисленный размер одинаков, но b64decode при декодировании аргумента, длина которого не кратна 4, декодирует на один-два байта больше.

Например, отправим

auth_md5('Hf'*42)

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 00  │....│....│....│....│
+0040 0x711da0  20 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │.aaa│aaaa│aaaa│aaaa│

Попробуем

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│

Переполнение на два байта

Механизм управления памятью Exim

Чтобы повысить производительность, exim реализовал собственную систему управления памятью поверх существующей кучи. Она действует как промежуточный буфер между кодом и glibc, целью которого является уменьшение количества вызовов malloc и free. 2 Для exim отдельный блок кучи называется storeblock. Каждый раз при использовании из него выделяется буфер подходящего размера. Если storeblock заканчивается, выделяется новый storeblock через malloc. Для каждого storeblock его структура представляет собой простой односвязный список:

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

Основные API для работы с кучей находятся в store.c:

store_get
store_release
store_extend
store_reset

store_get используется для получения буфера. Ключевой код:

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

Как видно, минимальная длина запрашиваемого store_block равна STORE_BLOCK_SIZE, то есть 8192.

Таким образом, store_block размером 8192 вместе со своим заголовком и заголовком блока кучи имеет общий размер 0x2020. 3

Каждый раз, когда exim выполняет команду, отправленную клиентом, и команда выполняется успешно, вызывается store_reset, чтобы освободить ненужные кэши и лишние store_block. Под успешным выполнением здесь понимается корректный формат команды, отсутствие недопустимых символов в почтовом ящике и т.д.; в противном случае store_reset не вызывается.

Идея эксплуатации

Эта уязвимость — классическая off-by-one (хотя на самом деле можно переполнить два байта), но из-за малого количества переполняемых байтов невозможно напрямую перезаписать чувствительные структуры в куче. Поэтому необходимо использовать некоторые особенности ptmalloc, чтобы расширить влияние уязвимости, превратив её в более масштабное переполнение или overlap. Для off-by-one существует классический метод: увеличение чанка (chunk enlarge) -> перекрытие чанков (chunk overlap). Изменяя размер чанка на больший и подделывая заголовок для обхода проверок glibc, можно добиться перекрытия чанков и, следовательно, более широкого охвата перезаписи.

Основной процесс: chunk enlarge -> chunk overlap -> искажение указателя next в storeblock, затем вызов store_reset, что приводит к освобождению произвольного чанка. При повторном выделении этого чанка можно изменить его содержимое (type confusion). meh в своей статье рекомендует изменять чанк, содержащий строки ACL, поскольку в обработке строк ACL есть возможность выполнения команд. Синтаксис команды для выполнения в ACL:

${run{command}}

Примерная раскладка кучи выглядит следующим образом: 4

Здесь первый чанк — это чанк, полученный в результате декодирования base64, используемый для off-by-one. Поэтому он должен располагаться в конце storeblock. Для удобства мы просто запрашиваем чанк размером больше 0x2020 для хранения результата декодирования base64; Второй чанк — sender_helo_name, используется для перезаписи следующего чанка. sender_helo_name хранится не в storeblock, а выделяется напрямую через malloc:

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

Таким образом, размер произвольный; Третий чанк — чанк, полученный от декодирования base64, используется для подделки заголовка и перезаписи. Он должен находиться в начале storeblock. Для удобства также запрашиваем размер 0x2020.

Exploit

Мой эксплойт также получен пошагово, следуя анализу других в интернете. Общая идея та же, но раскладка кучи немного отличается от других, поэтому некоторые небольшие параметры различаются.

Скачать инструмент