Поиск dll из kernela

Тема в разделе "WASM.NT.KERNEL", создана пользователем vx1d, 30 янв 2019.

  1. vx1d

    vx1d Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    118
    Есть ли способ найти dl по имени во всех процессах из kernel mode не делая инжект в user mode (для поиска там)?
     
  2. q2e74

    q2e74 Active Member

    Публикаций:
    0
    Регистрация:
    18 окт 2018
    Сообщения:
    999
    а как сделать инжект из кернела в юзер?
     
  3. vx1d

    vx1d Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    118
    черз APC например, поиск на форуме
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    ну допустим можно найти PEB через QueryInformationProcess, затем зачитать PEB_LDR_DATA из памяти и распарсить ее руками... но тут нужно еще помнить, что тут есть много мест, где можно накосячить... например, что внутри WOW64 у процесса есть два PEB'а, нужен именно 32-битный... если есть возможность загрузить драйвер до запуска целевого процесса, то можно решить через PsSetLoadImageNotifyRoutine... можно из ядра запустить вспомогательный процесс от система или от юзера и использовать Module32First/Module32Next из тулхелпа...
     
  5. vx1d

    vx1d Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    118
    ну да я наверно так и поступлю: перечислю процессы, приатачусь к каждому и чезер PEB перечислю модули
     
  6. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
  7. vx1d

    vx1d Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    118
    перед доступом к user space хочу проверить доступность через ProbeForRead, но она если что бросит исключение, которое я не смогу обработать,
    так как у меня шелкод и обработчик исключения не зарегистрирован (код x64)
    Есть ли альтернативные способы проверить доступность юзермодной памяти?
    --- Сообщение объединено, 1 фев 2019 ---
    Я что то не понял вот функция, а где проверки?

    Код (ASM):
    1. PAGE:00000001405505E0     ; void __stdcall ProbeForRead(const void *Address, SIZE_T Length, ULONG Alignment)
    2. PAGE:00000001405505E0                             public ProbeForRead
    3. PAGE:00000001405505E0     ProbeForRead            proc near                        ; DATA XREF: .pdata:00000001403D18D8o
    4. PAGE:00000001405505E0 000                         sub     rsp, 28h
    5. PAGE:00000001405505E4 028                         test    rdx, rdx
    6. PAGE:00000001405505E7 028                         jz      short PAGE_140550609
    7. PAGE:00000001405505E7
    8. PAGE:00000001405505E9 028                         dec     r8d
    9. PAGE:00000001405505EC 028                         test    rcx, r8
    10. PAGE:00000001405505EF 028                         jnz     short PAGE_14055060E
    11. PAGE:00000001405505EF
    12. PAGE:00000001405505F1 028                         lea     rax, [rcx+rdx]
    13. PAGE:00000001405505F5 028                         mov     rdx, 7FFFFFFF0000h
    14. PAGE:00000001405505FF 028                         cmp     rax, rdx
    15. PAGE:0000000140550602 028                         ja      short PAGE_140550614
    16. PAGE:0000000140550602
    17. PAGE:0000000140550604 028                         cmp     rax, rcx
    18. PAGE:0000000140550607 028                         jb      short PAGE_140550614
    19. PAGE:0000000140550607
    20. PAGE:0000000140550609
    21. PAGE:0000000140550609     PAGE_140550609:                                          ; CODE XREF: ProbeForRead+7j
    22. PAGE:0000000140550609                                                              ; ProbeForRead+36j
    23. PAGE:0000000140550609 028                         add     rsp, 28h
    24. PAGE:000000014055060D 000                         retn
    25. PAGE:000000014055060D
    26. PAGE:000000014055060E     ; ---------------------------------------------------------------------------
    27. PAGE:000000014055060E
    28. PAGE:000000014055060E     PAGE_14055060E:                                          ; CODE XREF: ProbeForRead+Fj
    29. PAGE:000000014055060E 028                         call    ExRaiseDatatypeMisalignment
    30. PAGE:000000014055060E
    31. PAGE:0000000140550613     ; ---------------------------------------------------------------------------
    32. PAGE:0000000140550613 028                         int     3                        ; Trap to Debugger
    33. PAGE:0000000140550613
    34. PAGE:0000000140550614     ; ---------------------------------------------------------------------------
    35. PAGE:0000000140550614
    36. PAGE:0000000140550614     PAGE_140550614:                                          ; CODE XREF: ProbeForRead+22j
    37. PAGE:0000000140550614                                                              ; ProbeForRead+27j
    38. PAGE:0000000140550614 028                         mov     eax, [rdx]
    39. PAGE:0000000140550616 028                         jmp     short PAGE_140550609
    40. PAGE:0000000140550616
    41. PAGE:0000000140550616     ProbeForRead            endp
    42.  
     
  8. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Проверка на читабельность сводится к этому:
    *(PBYTE)(UsermodeAddress)

    Чтобы проверить без чтения, можешь пройтись по PTE и посмотреть, присутствует ли страница в памяти. НО! Это не сработает, если страница сброшена в файл подкачки, и проверить её наличие можно только через ProbeForRead и try..except.
    --- Сообщение объединено, 1 фев 2019 ---
    Способ проще (внутри тоже читает PTE и тоже не покажет присутствие сброшенной в подкачку страницы):
    Код (C):
    1. KeStackAttachProcess(...);
    2. PHYSICAL_ADDRESS Phys = MmGetPhysicalAddress(UsermodeAddress);
    3. KeUnstackDetachProcess(...);
    4. if (Phys.QuadPart != 0) {
    5.     // Память есть
    6. }
     
    Последнее редактирование модератором: 1 фев 2019
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Подкачка происходит при выборке(обращении прямом) из страницы. Состояние области памяти хранится в виде системных высокоуровневых структур(VAD etc). А для работы с ними есть соотвествующий интерфейс(апи). Штатная апи NtQueryVM к примеру.

    А есчо можно использовать любую процедуру, которая защищена от исключений(seh). Она вернёт соответствующий статус, после выборки по заданному адресу. Это использовалось именно в шеллах, для обхода NX защиты(передача управления на доверенный обработчик при фаултах).
     
  10. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Экспортируется ядром только в последних Win, или искать сигнатурами и привязываться к билдам ~

    Хм, точно, тоже хорошее решение. Не подумал об этом варианте
     
  11. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Значит вы много чего не знаете :)

    Через передачу указателя на выборку из шелла использовались многие апи, а есчо были манипуляции с фреймами(seh_prolog). Что бы доступ из км не закрэшил ось. Это довольно старая техника.

    Тут решение очевидно, раз шелл - обращаемся в память через системные апи, которые обёрнуты сех. А для получения списка модулей листаем через такого типа выборку загрузочные списки. Можно поизвращаться, дёрнуть какие то апи, которые дадут список проекций, но как вы заметили - не экспортные, либо придётся их искать, либо впрыскивать код в юзер что бы это вызвать. Размер кода будет куда больше, чем безопасный проход по загрузочным структурам. Это не найдёт образы, сформированные протекторами/пакерами/загрузчиками. Думаю наверно тс это и не надо.
     
  12. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Indy_
    Шо поделать, я не из VX'овой среды, у меня задачи сделать максимально надёжно, портабельно и с минимумом андока, не сталкивался с подобными техниками)
     
  13. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Это использовалось часто. Во первых проверка памяти через сервисный вызов - ядро возвращает статус, но не вызывает исключение. Тут немного иная задача, км. Был руткит, точнее сервисный монитор(обработка ловушек через KDR) - сайд(2013).

    Архитектура была довольно продуманной, именно там первый раз использовалась данная техника.

    У меня на ядиске это есть https://yadi.sk/d/uQZFHH8REhsEx vx

    Смотри пролог и работу с ним:

    Были и другие проекты где такое использовалось.
     
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.455
    Адрес:
    Россия, Нижний Новгород
    Жесть какая! Пробежался мельком, надо разбираться. На выходных гляну подробнее, спасибо за сурсы
     
  15. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    HoShiMin,

    Там всё просто. Жесть была при попытке использовать код, который выполняет подкачку, для скрытия в памяти. Вот там была жесть. Но так и не получилось.