![]() |
[Вступление]
Хочу сразу заметить, что изначально статья писалась для Windows XP, замечания по Windows Vista/7 в самом конце статьи. Недавно по работе, а именно в рамках разворачивания информационного стенда компании с её сайтом, возникла одна интересная задача - заменить ctrl+alt+del (CAD) на свою комбинацию клавиш, чтоб пользователь не мог никуда уйти из положенной области просмотра и нахулиганить. Казалось бы ничего сложного, просто комбинация клавиш... Однако, поискав в интернетах, я не нашел готового решения - в разных местах люди писали мол комбинация "зашита" в код Windows и поменять её нереал и т.д. Тогда было решено обратиться к дяде Руссиновичу и узнать, что же там за хитрости такие с этой магической комбинацией клавиш. [Кто виноват и что делать?] Открыв небезызвестную книгу Windows Internals, я прозрел - не надо лезть в самые дебри Windows, не надо писать драйверы для перехвата нажатий клавиатуры, всё оказалось вроде не так сложно. После нажатия ctrl+alt+del система заботливо сообщает процессу winlogon.exe о нажатии этой комбинации, и не только этой, после чего winlogon предпринимает действия типа вызова меню в котором можно поменять пользователя, вызвать диспетчер задач и ещё кучу всего. Естественно, было решено перехватывать нашу магическую комбинацию здесь. Итак процесс определен, а как же это сделать? Данный процесс владеет собственным окном, которое имеет класс "SAS window class", а само окно называется "SAS window", ему то и посылаются сообщения о нажатых клавишах. Кстати SAS расшифровывается как Secure Attention Sequence, именно этой безопасной комбинацией и является ctrl+alt+del. Чтобы перехватить данную комбинацию надо неким образом подменить оконную функцию обработки сообщений. И тут на помощь нам приходить старый добрый сплайсинг функций (майкрософт называет это метод detour). [От слов к делу] Итак, нам нужно перехватить оконную функцию winlogon.exe, там некоторым образом обработать сообщение о том, что нажата SAS, и зарегистрировать свою комбинацию клавиш, которая и подменит ctrl+alt+del. Для всех вышеописанных действий необходимо написать инжектор и dll, код которых приведу ниже и поясню пару моментов, которые вызвали затруднения, однако саму процедуру сплайсинга не буду подробно описывать ибо по этой теме есть куча статей, например http://www.rsdn.ru/article/baseserv/IntercetionAPI.xml и http://wasm.ru/series.php?sid=8. Код dll: Код:
#include "windows.h"Теперь осталось подгрузить нашу библиотеку в winlogon.exe. Для этого потребуется отдельная программа инжектор: Код:
#include [Заключение] Таким вот образом была укрощена магическая комбинация CAD. Естественно, данную технику можно использовать как в хороших целях, так и в плохих (например писать winlock), но в данный момент в разработке находятся методы противодействия сплайсингу, так что ждите следующие статьи посвященные этому. Кому интересны подробности разворачивания информационного стенда на основе браузера Opera, милости прошу в ПМ. Всех благ и успехов в освоении глубин операционных систем =) [Замечания/дополнения] Замечания касаются только процесса inject dll в новых версиях Windows. С выходом Windows Vista/7 разработчики постарались залатать различные бреши в безопасности, внедрив технологию UAC и реализовав разделение пользовательских сессий. Попробуем разобраться, что представляют из себя эти виды защиты. Начнем с UAC. В Windows Vista и 7 разработчики решили оставить для пользователей только две группы: сообственно обычные пользователи и администраторы. С группой обычных пользователей все ясно - нет прав, либо иди гуляй, либо получай доступ от имени того у кого есть права (необходимо ввести логин/пароль). Если же в систему входит член группы админов, то для него создается два маркера доступа, один действительно админский позволяющий творить все, что душе угодно, а другой с обычным уровнем доступа. Причем после входа админа в систему первый пользовательский процесс, по умолчанию это Userinit.exe (можно понапихать своих процессов через реестр), запускается именно с маркером обычного уровня доступа, остальные процессы такие как explorer.exe наследуют этот уровень доступа. Сделано это все для того, что бы пользователи могли увидеть, что приложению необходим повышенный уровень привелегий (например для изменения данных в системных директориях и ветках реестра, чем пользуются многие малвари). Чем это может помешать провести inject dll? Да по большому счету ничем, кроме того, что придется согласиться повысить уровень привелегий приложения, кликнув на ОК во всем занкомом окошке. А учитывая, что большинство пользователей, из-за отсутсвия компьютерной грамотности, всегда тычут в OK, либо и вовсе отключают надоедливый UAC, то данный вид защиты не эффективный. Для чего может понадобиться повысить привелегии при инжекте? Для получения привелегии SeDebugPrivilege, которая позволяет выполнять функциию OpenProcess(), вне зависимости от дескриптора защиты открываемого процесса. Итак, а теперь камень преткновения inject dll в Windows Vista/7 - изоляция терминальных сессий. Каждый пользователь, авторизованный в системе теперь имеет собственную сессию, у админа одна, у NT AUTHORITY\SYSTEM другая и соотвественно процессы запущенные от разных пользователей выполняются в разных сессиях (в Windows XP все выполнялось в одной сессии). На что же это влияет при inject dll? Оказывается вам не удасться выполнить CreateRemoteThread(), если вызывающий её процесс и процесс, в котром необходимо удаленно создать поток находятся в разных сессиях, или что тоже самое запущенны от разных пользователей. Если все происходит в одной сессии, т.е. в процессах запущенных одним пользователем, то инжект работает как часы, аналогично Win XP. А как же быть если хочется заинжектиться в системный процесс типа winlogon.exe, в который мы так удачно внедрялись выше под Windows XP? На этот вопрос есть ответ тут. В кратце - авторы предлагают на выбор два метода. Либо использование недокументированной функции NtCreateThreadEx() из ntdll.dll с параметрами взятыми с потолка, скорее всего они были получены в ходе реверса процесса запуска потоков от системы. Либо создавать сервис, который будет запускаться от имени системы и дальше мы сможем инжектиться только в системные процессы за счет него. Первый способ интересен, однако такой функции нет в XP и она недокументирована. Второй способ годится только для инжекта в системные процессы, но не пользьзовательские, да и вообще создание сервиса, его регистрация требует некоторых дополнительных усилий. А теперь одна удивительная вещь - если инжект запускать от имени системы все той же PsExec.exe (для этого запускаем консоль от имени админа и там набираем что-то типа psexec.exe -s -i inject.exe), то все проходит просто на ура, наверно ясно почему, в свете предыдущих объяснений. Однако стоит заметить, что в Windos Vista/7 не получится перехватить CAD кодом написанным выше, по причине того, что Winlogon был изменен и функцией FindWindow(L"SAS window class", L"SAS window") вы окно не найдете, потому что окна с таким классом и именем тупо нет. VERte][, 10.11.11 |
методы противодействия сплайсингу давно уже разработаны неким Flintta с, тогда ещё более менее уважаемого форума, ксакепа, и его практически готовое решение валяеться на васме.
|
Цитата:
|
Цитата:
|
Включие обратно!
Пуск - Выполнить - "gpedit.msc" Там "Конфигурация пользователя" - "Административные шаблоны" - "Система" - "Сделать недоступными средства редактирования реестра" - сделайте в "Отключена". В том же районе ""Конфигурация пользователя" - "Административные шаблоны" - "Система" - "Возможности Ctrl+Alt+Del" - "Запретить диспетчер задач" - в "Отключена". |
Как символично
Цитата:
Но, уважаемый Билл, есть нюанс, например этот http://www.xakep.ru/post/57477/ |
От себя хочу сделать важное дополнение.
Нафига извращаться с шелкодом? Под Win XP kernel32.dll подгружена во все процессы по одинаковому адресу. по этому ход такой 1) открыли процесс 2) записали туда имя DLL с полным путём 3) в своей проге через GetProcAddress получили адрес LoadLibraryA 4) CreateRemoteThread на адрес LoadLibrary а в параметре - адрес памяти где хранится строка имени dll 4) Далее WaitForSingleObject чтобы дождаться заверщения потока 5) GetExitThreadCode (или както так) чтобы получить код возврата поток. Если ноль, значит DLL не грузанулась. Иначе её Адрес в памяти. 6) Освобождаем память занятую под строчку с именем DLL И еще важно знать что под Win 7 такое не прокатит. потому что там запрещено создавать удаленные потоки в чужом адресном пространстве. (хотя контекст перебивать можно вроде) |
slesh, полезно, не знал об этом
|
в плохих целях особо не используешь,т.к. отслеживание оконного класса ДЗ и сокрытие его,либо банальное отключение произведут нужный эффект.А за статейку +.
|
Ломаю голову.. а что мешало просто ограничить юзерам права? Видать были на то причины.
За статью спасибо, думаю использовать это можно не только в целях CAD. |
| Время: 06:40 |