CreateRemoteThread и сеансы

Тема в разделе "WASM.WIN32", создана пользователем NDIS, 13 авг 2008.

  1. NDIS

    NDIS NDIS

    Публикаций:
    0
    Регистрация:
    16 авг 2007
    Сообщения:
    41
    Адрес:
    Москва
    Привет.

    Задача

    Есть служба, работает как и положено от имени LocalSystem, т.е. имеет все необходимые привилегии, - отладка, TCB и прочая. Необходимо из этой службы внедрять определённую DLL в произвольный процесс. Желательно не необязательно внедрять её ещё до исполнения какого-либо кода нового процесса.

    Решение

    Открытие процесса по его ID и создание удалённого потока с точкой входа в LoadLibrary. Решение это классическое и рабочее. Но есть у него одно но.

    Проблема

    Читаем MSDN по поводу CreateRemoteThread:

    Проверил, действительно это так. Т.е. службы (и моя в том числе) выполняются в сеансе под номером 0. При входе другого пользователя в систему создаётся сеанс с номером 1, затем с номером 2 и т.д. Таким образом, если попытаться запустить удалённый поток в процессе, который выполняется в сеансе 1, то функция вернёт ошибку и никакой поток запущен не будет.

    Вопросы

    1. Возможно ли как-нибудь обойти данное ограничение более-менее документированным способом? Всё таки у меня служба, которая имеет чуть ли не максимальные привилегии в системе, если не говорить о режиме ядра.
    2. Если обойти это невозможно, тогда что ещё посоветуете для внедрения DLL из службы в любой процесс, выполняемый в любом сеансе? Желательно при этом не связываться с Native API, а обойтись только Kernel API или режимом пользователя.

    Спасибо.
     
  2. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Делай инжэкт APC - ZwQueueApcThread (QueueUserApc).
     
  3. Nero_n

    Nero_n New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2008
    Сообщения:
    33
    SetThreadContext может быть? т.е. установить eip на LoadLibrary, а после возврата поток может восстановить свой контекст через NtContinue.
     
  4. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Пока не будет выполнена инициализация ntdll никак не получится заюзать LoadLibrary().
    blast
    Очередь потока отпадает, не универсально.
    Nero_n
    Это тоже до инициализации работать не будет.

    Возможное решение в R3. Установить нотификатор на создание процессов или потоков(что проблемно из юзермода). В случае если нотификатор только сигнализирует создание процесса без возможности его контроля суспендить потоки. После создания процесса и до начала исполнения главного потока инжектить код загрузящий модуль посредством LdrLoadDll() и изменить Win32StartAddress потока(прежде сохранить его для последцющего восстановления) на этот код с помощью NtSetInformationThread(ThreadQuerySetWin32StartAddress). После чего поток начнёт исполнение не с ModuleEntryPoint модуля из которого создан процесс а из внедрённого кода, но уже после инициализации модулей в статическом импорте(все модули обработают событие DLL_PROCESS_ATTACH в контексте этого потока). Если необходим более высокий уровень контроля, соответственно код должен начать исполняться раньше инициализации всех модулей кроме ntdll и kernel32(ниже нельзя, загрузчик не инициализирован) то можно установить обработчик исключений(до инициализации вроде юзается DbgBreakPoint) или использовать обычные хуки. Вариантов много.
     
  5. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    И в чем же заключается эта не универсальность?
     
  6. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    запускать процесс в нужной сессии, передав ему PID процесса в который нужно инжектится. Когда будешь в одной сессии с жертвой, тогда удаленный поток сработает.
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    blast
    Поток обработает APC только когда войдёт в сервис ожидания и эта обработка будет разрешена, а до ModuleEntryPoint таковых нет и неизвестно когда будут.
     
  8. NDIS

    NDIS NDIS

    Публикаций:
    0
    Регистрация:
    16 авг 2007
    Сообщения:
    41
    Адрес:
    Москва
    Это первое, что пришло мне в голову. Однако, хотелось бы обойтись без дополнительных процессов.
     
  9. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    NDIS
    посмотри как в вмварных тулз это сделано - сервис + на каждую сессию два(!) екзешника
    екзешники прописаны в автостарте
    наверняка ведь ребята тоже страдали этой проблемой ;')

    наверно можно в любую сессию заинжектица как-то через жопу (может через дебуг апи?)
    но я лично сделал как у вмваре
     
  10. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    документированно только через создание процесса в нужной сессии. Пооблемы начинаются с XP fast user switching, далее терминальные сервисы и виста.
     
  11. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    Clerk
    не совсем так, пример c apc можно найти на рсдне
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    infern0
    Как так ???
    Когда поток входит в сервис ожидания(напр. NtDelayExecution, NtWaitForSingleObject и др.) одним из параметров является разрешение на обработку APC. Если поток ждёт, обработка APC разрешена и очередь не пуста, то начинает исполняться обработчик. В каждом вновь созданном потоке в очереди стоит событие и он начнёт его обрабатывать как только выйдет из остановленного состояния - это и есть событие LdrInitializeThunk начала работы потока из точки входа его в юзермод KiUserApcDispatcher(PspUserThreadStartup -> KeInitializeApc(pLdrInitializeThunk) -> KeInsertQueueApc). До начала исполнения ModuleEntryPoint нет сервисов в которых поток ждёт чтолибо да есчо и с разрешением на обработку очереди потока. Если вызвать NtQueueApcThread, что добавит событие в очередь потока, поток может вообще никогда не обработать его. Лишь когда гдето в коде он войдёт в сервис ожидания, вызвав функцию к примеру типа Sleep(), он обработает событие.
    Пример инжекта есть везде, это юзают все всилу простоты вызова. Но инжект на этапе инитиализации процесса невозможен посредством APC.
     
  13. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    apc инжект позволяет выполнить код непосредственно _перед_ началом выполнения главной нити приложения (либо перед выполнением dllmain любой выбранной дллки). Посмотри пример на рсдн.
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    хз
    Не представляю как. Где посмотреть ?
     
  15. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    http://rsdn.ru/article/baseserv/InjectDll.xml
    Это чтоли ? Тут же в кернелмоде :lol:
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Я напутал со NtSetInformationThread(ThreadQuerySetWin32StartAddress), оноже не влияет ни начто, туплю ппц.. тока щас допёрло(как ктото заметил наверно я ебанулсо)). Надо использовать NtSetContextThread.
     
  17. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    infern0
    зачем документировано? мы люди не гордые :)
    смотри:
    1) виндбг умеет аттачица к любому процессу в любой сессии
    2) у него есть один екстенжын, а именно logexts, который инжектит себя в таргет апликейшын

    осталось только посмотреть как он ето делает и вуаля
    Мне лениво а топикстартер может и попробует

    ЗЫ: проверил на всякий случай - поднял вару 2к3, застратил нотепад, зашол в нее с хоста mstsc.exe, запустил виндбг, зааттачился к нотепаду и сказал !logexts.logi

    ProcessExplorer подтвердил факт загрузки logexts.dll в нотепад
     
  18. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    DebugActiveProcess судя по всему не различает сессии. По крайней мере упоминания об этом в мсдн нету, в отличии от CreateRemoteThread. Но для инжекта это как-то не очень подходит ;)
     
  19. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    ps: http://www.osronline.com/DDKx/appendix/enhancements5_5ppv.htm

    Cross Session Debugging
    Windows XP supports cross-session debugging. Previously, all debugging was done against the Microsoft Win32® environment subsystem (csrss.exe) running on the computer. This caused potential problems, because on Terminal Services each client has its own Csrss process, so that debugging could not be done across terminal sessions. For example, if User1 logged in running Notepad, a second user, such as a system administrator, couldn’t perform a terminal session into the same server and debug User1’s Notepad process. The debugger code for Windows XP, along with accompanying kernel changes, supports such cross session debugging scenario.
     
  20. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    короче я немного поковырялся в logexts.dll - не годится, отбой
    инжектит он через Get/SetThreadContext, поэтому ненадежно

    ну тогда не знаю, инферно прав - только через процессы