Парсинг ApiSet на Win10 и Win7-8.1

Тема в разделе "WASM.BEGINNERS", создана пользователем HoShiMin, 28 ноя 2017.

  1. RET

    RET Active Member

    Публикаций:
    7
    Регистрация:
    5 янв 2008
    Сообщения:
    687
    Адрес:
    Hell
  2. RET

    RET Active Member

    Публикаций:
    7
    Регистрация:
    5 янв 2008
    Сообщения:
    687
    Адрес:
    Hell
    Блин, здесь кодес прикреплю
     
  3. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    Остаются ручной маппинг, APC, AppInit_DLLs, оконные хуки и подмена импортов.

    Против маппинга - искать ничейную исполняемую память (обходится заморозкой процесса).
    Против APC - видел несколько ядерных каллбэков, возможно, что-то даст их перехват.
    Против реестра - перехват LoadAppInitDlls в kernel32 до его вызова из user32.
    Оконные хуки - поставить фильтр на загрузку модулей по аналогии с потоками.
    Импорты - сомневаюсь, что вообще возможно задетектить.
     
  4. RET

    RET Active Member

    Публикаций:
    7
    Регистрация:
    5 янв 2008
    Сообщения:
    687
    Адрес:
    Hell
    Дрянь оконные хуки - гляньте чем это каспер, например отрыгнет.....
    ADD: Вместо DllMain можно колбэки TLS заюзать.
     
  5. unc1e

    unc1e Active Member

    Публикаций:
    1
    Регистрация:
    28 июл 2017
    Сообщения:
    119
    HoShiMin, навесьте dacl, правда, имея права админа, это можно обойти
     
  6. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    Права админа есть у всех, кто будет обходить. В их распоряжении CheatEngine с драйвером и любой паблик инжектор (например, этот: http://extremeinjector.net/)
     
  7. unc1e

    unc1e Active Member

    Публикаций:
    1
    Регистрация:
    28 июл 2017
    Сообщения:
    119
    Есть еще пару фишек с правами на память, которые отваливают инжекторы (код дать не могу, ибо его не много, и он должен войти в выпуск inception 4)
     
    Aiks нравится это.
  8. Indy_

    Indy_ Well-Known Member

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

    > затем создаю поток на DllMain, то никто не сможет это предотвратить. Какими бы ни были проверки на валидность в моём собственном коде, я никак не смогу отследить стороннюю память и сторонние потоки.

    Вот я поэтому этот вопрос и задал. Вы частично сами ответили на свой вопрос. Что бы блокировать инжект нужно заблокировать адреса, сделав их не исполняемыми. Частично это сделано в ms-CFG, тупо добавлены карты в модуль, в которой отмечены адреса которые можно вызывать. Конечно это частное решение, общее отсюда происходит логически, запретить полностью выполнение в адресном пространстве, оставив лишь шлюзы, через которые управление можно передавать. Попробуйте дальше развить эту идею, вы придёте к тому, что я ранее описал :)

    Иначе же управление может быть передано как угодно и откуда угодна, иначе ваша задача не может быть решена.
     
  9. Indy_

    Indy_ Well-Known Member

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

    > Будь процесс хоть трижды под визором, никто не запретит рабочему потоку выполнить сторонний шелл и беспрепятственно вернуться обратно, пока процесс заморожен и ничего не может проверить

    go #28

    Визор нужен в данном случае для двух целей - реализовать глобальный анклав(код не исполняется, он транслируется/эмулируется) и выполнять валидацию выборок(потоков данных).

    Вы видимо как то не внимательно воспринимаете что я говорю, раз приходится по пять раз подробно описывать :)

    Я ведь даже вам видео показывал как это работает - всё впустую, к сожалению.
     
    Последнее редактирование: 5 дек 2017
  10. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    Видео видел, и сама идея понятна, но давайте, всё же, по порядку. С CFG знаком по этой статье: https://habrahabr.ru/company/dsec/blog/305960/
    Компилятор в коде явным образом вставляет проверку указателя перед его вызовом. Сама по себе битовая карта без явного вызова проверок никакой роли не играет.
    Следовательно, если мы выделим исполняемую память из чужого процесса в нашем, запишем туда что-то такое:
    Код (ASM):
    1.  
    2. mov rax, LoadLibrary
    3. mov rcx, LibName
    4. call rax
    5.  
    то вызов успешно произойдёт, ведь память исполняемая, а наш процесс даже не подозревает, что в его АП появился ещё один кусок, пока не составит карту памяти и не найдёт участок, который никто не выделял.
    Аналогично, если процесс пометит всю свою (именно свою!) память неисполняемой, я легко смогу вернуть права из чужого процесса, дёрнув NtProtectVirtualMemory. И на момент выполнения шелла заморожу процесс.

    Потому, чтобы сделать шелл бессмысленным, вижу единственный выход в том, чтобы создать минимальное окружение из потока визора, а весь остальной код каким угодно образом зашифровать прямо в рантайме, а все модули "отмапить", чтобы шелл кроме голого асма никакую функцию даже вызвать не мог ввиду её отсутствия. Дальше следуют чудеса трансляции\эмуляции.

    Но появляются проблемы с системой, которая не знает про наши шифрования -> нужно решать проблемы с ядерными каллбэками, с ресолвингом модулей и загрузкой новых библиотек.
     
  11. unc1e

    unc1e Active Member

    Публикаций:
    1
    Регистрация:
    28 июл 2017
    Сообщения:
    119
    А что мешает в таком случае пропатчить ваш поток визора до/во время его исполнения?
     
  12. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    А что значит "пропатчить поток"? Патчить код визора, чтобы он по своим алгоритмам корректно вызвал нужные мне функции? Рокет-саенс.
    Имхо, всё вышеописанное - обыкновенный виртуализующий криптор, как вмп, но с учётом всей памяти процесса, и работающий в рантайме.
     
  13. unc1e

    unc1e Active Member

    Публикаций:
    1
    Регистрация:
    28 июл 2017
    Сообщения:
    119
    -> А что значит "пропатчить поток"? Патчить код визора, чтобы он по своим алгоритмам корректно вызвал нужные мне функции? Рокет-саенс.
    "Рокет-саенс" создавать визор под ммо.
     
  14. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    Я и не спорю, но речь уже не о целесообразности, а о методах реализации антиинжекта в целом (включая вариант с визором) и возможных обходах. Тема интересна сама по себе.
     
    unc1e нравится это.
  15. Indy_

    Indy_ Well-Known Member

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

    > Аналогично, если процесс пометит всю свою (именно свою!) память неисполняемой, я легко смогу вернуть права из чужого процесса, дёрнув NtProtectVirtualMemory. И на момент выполнения шелла заморожу процесс.

    Заблокировать память обычная задача, можно это элементарно из км сделать. Можно сделать это и из юм, но с некоторым извратом(память можно заблокировать от удаления через рк атаку на некоторые теневые сервисы(MiCheckSecuredVad()), но для этого ранее должен быть изменён тип памяти):

    - Освобождаем приват память, скопировав содержимое в секцию.
    - Отображаем секцию на исходный адрес с нужными правами.
    - Вызываем в цикле теневые сервисы, которые удерживают юзер буфер через MmSecureVM().
    - Из второго потока выполняем рк атаку на первый, до блокировки буфера.
    - После этого сменить права доступа к области никак нельзя, пока поток не будет разморожен. Но и это можно блокировать, уничтожив контекст треда к примеру.

    > Дальше следуют чудеса трансляции\эмуляции.

    Так как код не передаётся в км(только данные), то можно его собирать частями, а так как получается только X-анклав, никаких проблем с км не возникает.

    unc1e,

    > А что мешает в таком случае пропатчить ваш поток визора до/во время его исполнения?

    А что это даст ?
    Захваченный поток таким образом вызвать ничего не может, вне залитой области памяти. Что бы реализовать какой то вызов апи или в общем кода из визора при использовании глобального анклава должен происходить рекурсивный запуск целевого кода под визором. Причём адрес входа(шлюз) заранее не известен.
     
    Последнее редактирование: 6 дек 2017
  16. HoShiMin

    HoShiMin Member

    Публикаций:
    0
    Регистрация:
    17 дек 2016
    Сообщения:
    95
    Indy_
    Хм, действительно, про ремаппинг не вспомнил. Вижу потенциальную проблему с секциями данных, которые после ремаппинга станут ридонли из-за невозможности мапить секции отдельно из-за ограничений по гранулярности. И возможное решение - все секции данных ремапнуть с нормальными правами, а код отдельным маппингом с правкой релоков и рантаймовым перенаправлением всех обращений к секции данных на новую.
     
  17. Indy_

    Indy_ Well-Known Member

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

    Код можно так же удалить из памяти или изменить его. Но для этого нужно знать все входы в код, я этот вопрос как то поднимал. Это обычно делается на этапе сборки апп. Для произвольного модуля нужен парсер, который обеспечивает нужное покрытие кода, что не всегда возможно. В частности для rip-адресации. Но можно в динамике накапливать указатели и обрабатывать код.

    Но сути это ведь не меняет. В данном случае либо возможность инжекта есть, либо её нет полностью. Что то частичное не может являться защитой.