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

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

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

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

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

Категории

Все категории
Loading categories
HintInject — PoC-проект для внедрения shellcode в Hint/Name Table | Kitploit
Инструменты/GitHubGitHub/frkngksl/hintinject
Генерация полезной нагрузкиЭксплуатацияШелл-кодТестирование на ПроникновениеАнализ Бинарных ФайловРазработка Полезной Нагрузки
GitHubfrkngksl/hintinject

HintInject

PoC-проект для внедрения shellcode в Hint/Name Table

Репозиторий
114224 месяцев назадПроверено Kitploit

Популярное

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

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

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

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

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

HintInject

HintInject — это инструмент для внедрения и загрузки шелл-кода, который я разработал, экспериментируя со структурами PE-файла и таблицы импорта (Import Directory Table). Он принимает сырой шелл-код и разбивает его на фрагменты, помещая их в записи Hint/Name Table, доступные через Import Lookup Table поддельной записи импортируемой DLL в исполняемом файле-загрузчике. Затем загрузчик объединяет эти фрагменты для выполнения шелл-кода. Не знаю, является ли эта техника новой, но я решил поделиться ей ради интереса.

Процесс загрузки DLL

Прежде чем объяснить, как работает HintInject, я хочу кратко описать процесс загрузки DLL, ссылаясь на пост на Stack Overflow.

Чтобы получить информацию о требуемых DLL и функциях/импортах, нужно сначала обратиться к Import Directory Table. Import Directory Table — это таблица записей, по одной для каждой импортируемой DLL. Эти записи содержат указатель на имя импортируемой DLL, указатель на Import Lookup Table, указатель на Import Address Table и другие поля для различной информации.

Проще говоря, Import Lookup Table ведёт к информации об импортах, а Import Address Table — к адресам импортов. Однако, когда исполняемый файл находится на диске или непосредственно перед процессом загрузки DLL, Import Address Table идентична Import Lookup Table. Содержимое Import Address Table перезаписывается адресами импортов во время процесса загрузки DLL.

Не вдаваясь в подробности, взглянем на диаграмму ниже, чтобы увидеть взаимосвязь между этими тремя таблицами.

Если углубиться, то Import Lookup Table не хранит имена импортов напрямую. Для функций, импортируемых по имени, он содержит RVA записей Hint/Name Table. Эти записи хранят имена функций в виде строк ASCII, завершающихся нулём. Поэтому определение структуры записи Hint/Name Table выглядит следующим образом:

root@kitploit:~
typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    CHAR   Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; 

Поле Hint здесь — это фактически индекс в таблицу указателей на имена экспорта DLL. Оно используется для ускорения поиска позиции этого импорта. Таким образом, мы можем обобщить взаимосвязь между Import Lookup Table и Hint/Name Table с помощью диаграммы ниже.

В итоге, чтобы найти DLL и её импорты, нужно выполнить следующие шаги:

  1. Перейти к Import Directory Table из массива DataDirectory Optional Header.
  2. Пройти по записям Import Directory Table, чтобы найти нужную DLL, проверив её поле имени.
  3. После нахождения правильной записи перейти к её Import Lookup Table, используя поле OriginalFirstThunk.
  4. Пройти по всем записям в Import Lookup Table, которые являются указателями на записи Hint/Name Table.
  5. Проверить имена импортов из поля Name записей Hint/Name Table.

Как работает HintInject?

Недавно, изучая технику ImportDLLInjection, опубликованную x86matthew, я узнал, как добавить поддельную запись в Import Directory DLL, загруженных в память. После этого я захотел разработать небольшой проект, который добавляет поддельную запись напрямую в таблицу импорта бинарного файла на диске — и ради интереса, и для освежения знаний. Просматривая процесс загрузки DLL для этого проекта, я обратил внимание на поле Hint в записях Hint/Name Table, используемых в этом процессе.

Согласно документации MSDN, я узнал, что это поле используется Windows Loader для нахождения адреса данного импорта (импортируемого по имени) непосредственно из таблицы имён экспорта DLL, в которой он находится. Однако в том же документе говорилось, что если функцию не удаётся найти с помощью этого поля, она ищется бинарным поиском в таблице имён экспорта DLL. Основываясь на этой фразе, я решил, что указание неверного значения для этого поля не нарушит процесс загрузки DLL.

Как я упомянул выше, для каждой импортируемой функции существует запись в Hint/Name Table. Другими словами, для каждого импорта у нас есть 2 байта для использования. Объединив несколько импортов, можно получить достаточно полей Hint для хранения вредоносного шелл-кода. В результате можно использовать загрузочный бинарный файл, чтобы встроить шелл-код в записи Hint/Name поддельной записи импортируемой DLL. Этот загрузочный файл может получить доступ к этим записям, чтобы объединить шелл-код для выполнения во время выполнения.

HintInject можно использовать для создания такого загрузчика, который хранит шелл-код в своей таблице Hint/Name. Сначала он создаёт новый раздел с именем .rrdata и копирует текущий каталог импорта в этот раздел. После этого он добавляет новую поддельную запись, импорты которой будут использоваться для хранения входного шелл-кода. Оставшиеся байты раздела используются для хранения Import Lookup Table, Import Address Table, имени DLL и Hint/Name Table новой поддельной записи. На последнем этапе HintInject использует поля Hint импортов для размещения фрагментов входного шелл-кода.

Пример импортов загрузочного бинарного файла:

Screen Shot 2022-05-08 at 11 43 42

Использование

  1. Соберите проект с опцией Release.
  2. Запустите HintInject.exe с вашим шелл-кодом в сыром формате и путём к выходному файлу, чтобы создать загрузчик шелл-кода: HintInject.exe <Shellcode File> <Output Name>
  3. Запустите загрузчик для непосредственного выполнения шелл-кода, или вы можете указать PID для внедрения шелл-кода: Loader.exe <PID>
  4. При желании вы можете изменить метод внедрения шелл-кода, изменив функцию InjectShellcode в файле HintInjectLoader/Main.cpp.

Протестировано на Windows 10 19044 с Visual Studio 2019:

Ограничения

  1. Что касается поддельных записей DLL в загрузчике, выполняющем шелл-код, то и DLL, и имена импортируемых функций должны действительно существовать. В противном случае при запуске исполняемого файла загрузчика возникает ошибка отсутствия DLL. Поэтому в проекте я использовал несколько легитимных DLL из System32.
  2. Если размер вашего шелл-кода великоват и не удаётся создать загрузчик для него, вы можете добавить другие DLL в массив dllNames в файле DllNamesForFakeImports.h.
  3. Для каждого созданного загрузчика импортируемые функции выбираются случайным образом. Однако, если вы хотите изменить порядок DLL, используемых для создания поддельных записей, вам также следует отредактировать массив dllNames в файле DllNamesForFakeImports.h. По умолчанию HintInject будет выбирать функции из DLL в соответствии с порядком массива. Другими словами, инструмент сначала выбирает экспортируемые функции из user32.dll; если размер шелл-кода превышает 2 * количество экспортов user32.dll, он также начинает использовать экспорты advapi32.dll и других.
root@kitploit:~
static LPCSTR dllNames[] = {"user32.dll","advapi32.dll","gdi32.dll","wininet.dll","comctl32.dll","shell32.dll","wsock32.dll","oleaut32.dll","ws2_32.dll","urlmon.dll"};

Ссылки

  • https://stackoverflow.com/questions/32841368/whats-the-difference-between-the-import-table-import-adress-table-and-import
  • https://0xrick.github.io/win-internals/pe6/
  • https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#hintname-table
  • https://www.x86matthew.com/view_post?id=import_dll_injection

Отказ от ответственности

Только для авторизованного тестирования безопасности. Несанкционированное использование этого инструмента против систем без явного разрешения является незаконным.

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