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

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

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

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

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

Категории

Все категории
Loading categories
writeup_split — Описание уязвимости переполнения кучи в программе split из состава GNU coreutils. CVE-2024-0684 | Kitploit
Инструменты/GitHubGitHub/valentin-metz/writeup_split
Анализ уязвимостейЭксплуатацияСтатьи и ИсследованияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubvalentin-metz/writeup_split

writeup_split

Описание уязвимости переполнения кучи в программе split из состава GNU coreutils. CVE-2024-0684

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

Популярное

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

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

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

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

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

Аннотация

CVE-2024-0684

Уязвимость в программе "split" из набора GNU coreutils позволяет переполнение кучи с контролируемыми пользователем данными.

Она была внесена в 40bf1591bb4362fa91e501bcec7c2029c5f65a43 4 марта 2023 года. Исправление было выпущено с c4c5ed8f4e9cd55a12966d4f520e3a13101637d9 17 января 2024 года.

Затронутые версии: GNU coreutils v9.4; v9.3; v9.2

Подтверждение концепции: Пример файла split_me в этом репозитории можно использовать для вызова аварийного завершения в затронутых версиях.

root@kitploit:~
split -C 1024 ./split_me

Это приведет к аварийному завершению split с ошибкой сегментации (SIGABRT).

Обнаружение:

Я обнаружил эту уязвимость при попытке автоматизировать извлечение данных из систем, изолированных от сети, используя QR-коды. QR-коды, сгенерированные с помощью qrencode, имеют емкость около 4000 символов, поэтому потребовалось интенсивное использование split. В одном конкретном тестовом случае split аварийно завершился с ошибкой сегментации.

Изоляция:

Поскольку GNU coreutils являются открытым исходным кодом, мы можем использовать исходный код для выявления ошибки, вместо того чтобы обратно проектировать бинарный файл. В проектах с открытым исходным кодом нужно быть максимально конкретным в отчете об ошибке, желательно указать точный коммит и строку, которые внесли ошибку, а также предложить исправление. Это позволяет мейнтейнерам быстро проверить ваш отчет и сокращает время ответа.

При проверке ошибки в разных системах, я заметил, что аварийное завершение происходит только в относительно недавних версиях split. Если у вас есть хороший и плохой коммиты, это позволяет выполнить бинарный поиск по истории коммитов, чтобы найти коммит, который фактически внес ошибку.

Git предоставляет специальный инструмент для этого случая: git bisect. Он автоматически предложит коммиты для тестирования и позволит отметить их как хорошие или плохие. В итоге вы получите коммит, который внес ошибку; в нашем случае:

root@kitploit:~
commit 40bf1591bb4362fa91e501bcec7c2029c5f65a43
Author: Paul Eggert <[email protected]>
Date:   Sat Mar 4 11:42:16 2023 -0800

    split: prefer signed integers to size_t
    
    This allows for better runtime checking with gcc
    -fsanitize=undefined.
    * src/split.c: Include idx.h.
    (open_pipes_alloc, n_open_pipes, suffix_length)
    (set_suffix_length, input_file_size, sufindex, outbase_length)
    (outfile_length, addsuf_length, create, cwrite, bytes_split)
    (lines_split, line_bytes_split, lines_chunk_split)
    (bytes_chunk_extract, ofile_open, lines_rr, main):
    Prefer signed integers (typically idx_t) to size_t.

 src/split.c | 105 ++++++++++++++++++++++++++++++------------------------------
 1 file changed, 52 insertions(+), 53 deletions(-)

Затем мы можем скомпилировать программу (желательно с адресным санитайзером), чтобы найти точную строку, на которой происходит аварийное завершение. Имея всего около 50 строк для просмотра, становится легко выявить ошибку. В нашем случае аварийное завершение произошло в вызове memcpy() с неверными индексами. И действительно, если проверить область вокруг вызова memcpy(), мы находим diff, который изменяет вычисления индексов непосредственно перед:

root@kitploit:~
@@ -816,15 +820,10 @@
           /* Update hold if needed.  */
           if ((eoc && split_rest) || (!eoc && n_left))
             {
-              size_t n_buf = eoc ? split_rest : n_left;
+              idx_t n_buf = eoc ? split_rest : n_left;
               if (hold_size - n_hold < n_buf)
-                {
-                  if (hold_size <= SIZE_MAX - bufsize)
-                    hold_size += bufsize;
-                  else
-                    xalloc_die ();
-                  hold = xrealloc (hold, hold_size);
-                }
+                hold = xpalloc (hold, &hold_size, n_buf - (hold_size - n_hold),
+                                -1, sizeof *hold);
               memcpy (hold + n_hold, sob, n_buf);
               n_hold += n_buf;
               n_left -= n_buf;

Если откатить эти изменения и перекомпилировать, split обрабатывает все наши тестовые случаи без ошибок.

Осталось только пройтись по логике, чтобы проверить ошибку и разработать исправление.

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