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

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

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

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

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

Категории

Все категории
Loading categories
MemITM — Инструмент для выполнения атаки «человек посередине» в памяти | Kitploit
Инструменты/GitHubGitHub/amossys/memitm
Динамический анализ (песочница)Криминалистика памятиЭксплуатацияОбратная инженерияОтладчикиФаззингАнализ Бинарных Файлов
GitHubamossys/memitm

MemITM

Инструмент для выполнения атаки «человек посередине» в памяти

Репозиторий
126277 лет назадПроверено Kitploit

Популярное

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

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

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

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

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

Что такое инструмент MemITM?

Инструмент MemITM (Mem In The Middle) был разработан для удобного перехвата «сообщений» в памяти процессов Windows. Мы разработали множество пользовательских инструментов перехвата памяти для захвата сетевых сообщений до шифрования или IPC-сообщений, а также для их проверки или изменения с целью фазинга. Каждый инструмент был очень специфичным, не универсальным, реализованным на C/ASM, и его было нелегко использовать/поддерживать/адаптировать.

Инструмент MemITM был разработан для решения этих проблем и состоит из:

  • скрипта IDA Python, который генерирует файл «config», указывающий, где и как должны быть размещены точки перехвата (относительный адрес, как найти буфер и его размер, как установить хук и т.д.);
  • DLL-файла, который будет внедрен в целевой процесс и загрузит конфигурацию и установит хуки;
  • инжектора DLL-файла, который загрузит DLL в целевой процесс;
  • python-скрипта, который взаимодействует с внедренной DLL/хуками и в реальном времени получает перехваченные буферы (и может изменять их) с помощью очень простых колбэков, которые вы можете модифицировать по своему усмотрению.

Вы можете скачать его (исходники + скомпилированная версия) здесь: https://github.com/Amossys/MemITM

Насколько прост MemITM? (Пример1: WriteFile)

Допустим, вы хотите перехватывать записи в файл (есть более простые способы сделать это, но это для примера) в конкретном процессе Windows. Запись в файл выполняется функцией WriteFile, которая экспортируется из kernelbase.dll и соответствует схеме BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, ...). WriteFile — это функция __fastcall: lpBuffer указывается регистром RDX, а NumberOfBytesToWrite — R8. Давайте перехватим эти буферы.

  1. откройте файл «kernelbase.dll» в IDA Pro, загрузите скрипт generate.idapython.py и просто выполните getHook(LocByName("WriteFile"), "rdx","r8"), а затем updateConfig("config.bin").
  2. запустите блокнот, а затем python memitm.py notepad.exe config.bin.

Вот и всё! Хук установлен на функцию WriteFile, а функции «logger» и «fuzzer» из memitm.py будут получать копию буфера.

Мой буфер не указывается регистром! (Пример2: NtCreateFile)

Функция getHook позволяет указывать регистры для буфера и его размера, но в некоторых случаях это может быть не так. Допустим, вы хотите перехватывать системные вызовы NtCreateFile и получать имя файла. NtCreateFile соответствует схеме NTSTATUS NtCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, ...), и имя файла можно получить через ObjectAttributes->ObjectName->Buffer (размер: ObjectAttributes->ObjectName->Length * sizeof(WCHAR)).

getHook также позволяет указывать shellcode в параметре t1customOpcodes вместо регистров. Этот shellcode должен:

  • помещать указатель на буфер в регистр RCX;
  • помещать размер буфера в регистр RDX;
  • не нарушать состояние стека.

В случае с NtCreateFile мы можем просто выполнить этот код ASM для выполнения работы:

root@kitploit:~
mov rax, [r8+0x10]    ; rax is now ObjectAttributes->ObjectName
mov rcx, [rax + 0x10] ; rcx is now ObjectAttributes->ObjectName->Buffer
mov rdx, [rax]        ; rdx is now ObjectAttributes->ObjectName->Length
and rdx, 0xFFFF       ; Length is a USHORT 
shl rdx, 1            ; and must be *2

Соберем это (используя, например, онлайн-дизассемблер): 498B4010488B4810488B104881E2FFFF000048D1E2. Теперь наш вызов getHook должен быть таким: getHook(LocByName("NtCreateFile", t1customOpcodes="498B…E2").

Могу ли я перехватывать несколько вызовов?

Да! Файл конфигурации может содержать определения нескольких точек перехвата, и функция getHook добавляет их в файл. Вы можете устанавливать точки перехвата в нескольких модулях. Например, вы можете одновременно перехватывать сообщения ALPC и IOCTL.

Вы сможете различать их по «идентификатору сообщения» в колбэках python.

Ой, BSOD/зависание системы!

Не волнуйтесь, также есть простой HTTP-сервер (logserver.py) и функция httpNetSend, которые позволяют отправлять ваши тестовые примеры (и изменения) на удаленный хост в реальном времени.

Как мне выполнять фазинг?

Что ж, вы можете начать с использования функции bufferBitFlip, чтобы... переворачивать несколько битов. Логирование сырых сообщений позволит вам написать свой собственный диссектор и начать вручную реализовывать лучший фаззер :). Помните: вы не можете изменить размер буфера!

Например, в нашем примере с WriteFile следующая функция fuzzer заменит «hello» на «world»:

root@kitploit:~
def fuzzer(data, msgID=None, pid = 0):
   return data.replace("hello","world")

Пример3: разбор сообщений ALPC

Например, для сообщений ALPC может быть следующая настройка memitm.py:

root@kitploit:~
def logger(data, msgID=None, pid=0):
    totalLen = 0
    dataLen = 0
    typ = 0
    dataInfoOffset = 0
    cid = 0
    tid = 0
    messageID = 0
    clientViewSize = 0
    # skip the PORT_MESSAGE header (0x18 bytes)
    if len(data) > 0x18:
        totalLen = struct.unpack("<H",data[:2])[0]
        dataLen = struct.unpack("<H",data[2:4])[0]
        typ = struct.unpack("<H",data[4:6])[0]
        dataInfoOffset = struct.unpack("<H",data[6:8])[0]
        zeroInit = struct.unpack("<L",data[4:8])[0]
        cid = struct.unpack("<L",data[8:0xC])[0]
        tid = struct.unpack("<L",data[0xC:0x10])[0]
        messageID = struct.unpack("<L",data[0x10:0x14])[0]
        clientViewSize = struct.unpack("<L",data[0x14:0x18])[0]
    logMessage = "ALPC message : %x:%x - %x:%x - %d:%d - %x - %x" % (totalLen, dataLen, typ, dataInfoOffset, cid, tid, messageID, clientViewSize)
    print logMessage
    return

Как это работает внутри?

Скрипт IDA Pro содержит простой движок хукинга, который позволяет перемещать несколько инструкций в определенную область (производный от нашего инструмента DIMCT). Он должен обрабатывать множество крайних случаев, таких как инструкции, относительные по памяти, перекрестные ссылки и т.д., и, вероятно, будет выдавать много сообщений «не могу установить хук здесь», если вы попытаетесь перехватывать очень маленькие базовые блоки (<5 байт для x86-двоичных файлов, <12 байт для x64), содержащие несколько перекрестных ссылок. Для получения дополнительной информации просто прочитайте исходный код :).

Он генерирует следующую информацию в файле конфигурации:

  • имя модуля;
  • относительный адрес точки перехвата;
  • область хука перехвата (также известная как «T1 trampoline»), которая помещает буфер/длину в RCX/RDX и вызывает процедуру логирования DLL;
  • область хука восстановления (также известная как «T2 trampoline»), которая восстанавливает контекст и выполняет замененные инструкции перед возвратом к точке перехвата;
  • перемещения области хука восстановления для относительных инструкций, которые были преобразованы в абсолютные и должны быть исправлены.

Инжектор DLL — это простой инжектор DLL (использующий CreateRemoteThread/LoadLibraryA).

Сама DLL инициализирует область разделяемой памяти и ожидает данные конфигурации (область разделяемой памяти имеет 3 общих поля: идентификатор сообщения разделяемой памяти, размер сообщения и буфер сообщения). После получения она анализирует и устанавливает хуки в память, и после этого обновление конфигурации не допускается (вы должны завершить процесс, если хотите установить новые хуки). Любой установленный хук попадет в функцию DLL genericHookFunction. Эта функция просто заполняет область памяти (защищенную критическими секциями) данными буфера, его размером и идентификатором сообщения (установленным в старших битах поля идентификатора сообщения разделяемой памяти). Для уведомления процесса python используются 2 события, чтобы сигнализировать о новых сообщениях и ожидать, пока процесс их исправит (тайм-аут составляет 2 секунды). Если буфер был обновлен, исходный буфер также изменяется.

Скрипт memitm.py запускает процесс инжектора и ожидает создания разделяемой памяти. Затем он отправляет конфигурацию и ожидает события сообщения. Когда оно получено, разделяемая память читается, и функции logger и fuzzer вызываются с буфером, идентификатором процесса и идентификатором сообщения. Если функция logger возвращает буфер, отличный от исходного, и его размер равен, он записывается в область разделяемой памяти. Затем сигнализируется событие «ACK», и скрипт ожидает новое сообщение.

Вот и всё!

Надеемся, этот инструмент будет полезен, любая помощь/отзывы будут оценены! Кроме того, если вы француз и любите Ренн, мы нанимаем :)

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