Ошибка анализа файлов Easy Grade Pro 4.1, используемая в качестве учебного примера, чтобы показать новичкам, как начать исследование уязвимостей с помощью обратной разработки.
Образовательный пример, созданный, чтобы показать новичкам, что исследование уязвимостей через обратную разработку возможно с самого начала.
Этот репозиторий возник из необходимости иметь простой пример, который можно использовать при обучении новичков, начинающих заниматься исследованием уязвимостей, особенно тех, кто интересуется обратной разработкой.
После завершения курса, тренинга или магистерской программы по эксплуатации или анализу бинарных файлов многие студенты чувствуют, что настоящее исследование уязвимостей находится далеко за пределами их уровня. Они обычно ассоциируют обратную разработку с очень продвинутыми темами, такими как уязвимости ядра, эксплуатация браузеров, исследование прошивок или сложные современные цели, и из-за этого считают, что они еще не готовы. На практике проблема не в недостатке знаний, а в отсутствии реалистичной отправной точки.
Я хотел пример, который мог бы показать, что с навыками, полученными во время базового курса, уже можно взять реальную программу, понять, как она работает, вызвать сбой и выявить настоящую ошибку.
Этот репозиторий – именно такой пример. Речь идет не о поиске сложной уязвимости, а о том, чтобы показать, что новички могут начать с чего-то маленького, воспроизводимого и понятного, и при этом заниматься настоящим исследованием уязвимостей.
Этот репозиторий напрямую связан с моим докладом «The Path That Leads to Your First CVE», в котором я объясняю, что существует множество способов войти в мир исследования уязвимостей, и что каждый человек обычно выбирает свой путь в зависимости от своих интересов.
Некоторые начинают с аудита исходного кода, другие – с обратной разработки, третьи – с веб-безопасности, а четвертые – с исследования технологий. Все эти пути верны, но важно понимать, что в каждой области есть точки входа, подходящие для новичков.
Примеры путей для начинающих включают:
Такие цели могут выглядеть базовыми, но они обучают тем же ключевым навыкам, которые потребуются позднее при работе со сложными системами.
Этот репозиторий представляет один из таких путей для начинающих в области обратной разработки.
Уязвимость, задокументированная здесь, была найдена путем анализа старого приложения, понимания того, как разбирается его формат файлов, и выявления ошибки программирования, приводящей к сбою. Само воздействие не является сложным, но процесс реален, воспроизводим и полезен для изучения того, как на самом деле происходит исследование уязвимостей.
Это именно тот пример, который я использую, объясняя «The Path That Leads to Your First CVE», чтобы показать, что обратная разработка – это верный путь с самого начала, и что начинать с простых целей не только допустимо, но часто является лучшим способом обучения.
Когда вы только начинаете, современные приложения часто слишком сложны. Они используют защиты, средства смягчения и кодовые базы, которые трудно понять без большого опыта. Старое ПО – другое дело.
Устаревшие приложения не создавались с учетом современных практик безопасности. Они часто содержат простые ошибки разбора, небезопасные операции с памятью и логические ошибки, которые можно понять с помощью базовых навыков реверс-инжиниринга. Это делает их идеальными для обучения.
Используя старую программу, вы можете: выполнить реверс-инжиниринг бинарного файла, понять формат файла, вызвать сбой, проанализировать сбой, локализовать ошибку, задокументировать проблему и сообщить об уязвимости. Другими словами, вы осваиваете базовые навыки, необходимые каждому исследователю уязвимостей.
Именно об этом данный пример.
Этот пример важен, потому что он демонстрирует нечто очень простое:
Если вам нравится обратная разработка, вы можете следовать этому пути с самого начала. Чтобы стать мастером, могут потребоваться годы, но чтобы начать делать реальную работу, ждать годы не нужно.
Уязвимость (CVE-2025-70330) затрагивает логику разбора файлов Easy Grade Pro 4.1 при загрузке проприетарных файлов оценок формата .EGP.
Приложение восстанавливает внутренние структуры журнала, считывая поля с фиксированными позициями из файла и используя эти значения в качестве смещений внутри загруженного буфера файла. Эти смещения впоследствии используются для вычисления размеров памяти и копирования данных в динамически выделяемые буферы.
При нормальных условиях файл проходит несколько структурных проверок, прежде чем разбор продолжится. Однако после успешного прохождения этих проверок синтаксический анализатор доверяет значениям смещений, хранящимся внутри файла, не проверяя, остаются ли они в границах загруженного буфера.
Изменяя определенные байты внутри в остальном корректного файла .EGP, можно исказить эти внутренние вычисления смещений. Когда анализатор впоследствии использует эти значения, он пытается прочитать память за пределами допустимой области файла, что приводит к нарушению доступа и сбою приложения.
Это состояние соответствует чтению за пределами границ (CWE-125), что приводит к локальному отказу в обслуживании при открытии специально созданного файла.
Формат файла .EGP анализируется с использованием подхода на основе смещений. Вместо последовательной обработки файла анализатор считывает внутренние структуры, содержащие начальные и конечные смещения, описывающие, где в файле должны находиться определенные блоки данных.
Эти смещения используются для вычисления размера области памяти и копирования данных из загруженного буфера файла во вновь выделенную память.
Уязвимую логику можно обобщить следующим образом:
size = offset_end - offset_start + 1
buffer = calloc(1, size)
memcpy(buffer, file_buffer[offset_start - base_offset], size)
После прохождения файлом начальных проверок валидации анализатор предполагает, что смещения, хранящиеся в файле, верны. Никакой проверки того, что вычисленный исходный указатель остается внутри загруженного буфера файла, не выполняется.
Если смещения управляются контролируемым образом, анализатор может попытаться прочитать память за пределами допустимой области, что вызывает нарушение доступа во время операции memcpy().
Не каждый поврежденный файл .EGP вызывает сбой.
Анализатор выполняет несколько проверок согласованности, прежде чем дойдет до уязвимого пути кода. Если структура файла слишком повреждена, приложение останавливает разбор на раннем этапе и сообщает, что журнал поврежден.
Однако некоторые модификации сохраняют внутренние структуры достаточно согласованными, чтобы пройти начальные проверки, но при этом приводят к неверным значениям смещений на более поздних этапах разбора.
Когда это происходит, анализатор достигает более глубоких процедур, где эти смещения считаются доверенными и используются в операциях копирования памяти, что в конечном итоге приводит к чтению за пределами границ.
Сбой можно вызвать, модифицировав корректный файл .EGP и вставив управляемые данные по определенному смещению.
Доказательство концепции работает следующим образом:
Пример параметров, используемых в PoC:
Эта модификация сохраняет файл достаточно структурно верным для прохождения начальных проверок, но искажает внутренние вычисления смещений, используемые анализатором позднее, что в итоге вызывает сбой приложения.
При открытии поврежденного файла под отладчиком приложение вылетает во время операции копирования памяти.
Наблюдаемое исключение – нарушение доступа, вызванное недопустимым чтением памяти.
Во время отладки недопустимый указатель, используемый memcpy(), происходит из вычислений смещений, полученных из разобранных структур файла. Когда эти смещения ссылаются на память за пределами загруженного буфера файла, исходный указатель указывает на неотображенный адрес, что вызывает сбой.
Это подтверждает, что уязвимость вызвана отсутствием проверки границ при разборе файла.
Эта уязвимость затрагивает продукт, срок поддержки которого истек; он больше не поддерживается поставщиком.
Проблема задокументирована в образовательных и исследовательских целях, а также для того, чтобы дать начинающим конкретный пример того, как можно шаг за шагом анализировать программное обеспечение, чтобы понять, как появляются ошибки и как находятся реальные уязвимости.