ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

Сейчас, когда BOF стали обычным явлением для агентов Windows, некоторые говорят о том, что им нужна версия, отличная от Windows. В этой статье у нас есть кое-что для вас: то же самое, но для Linux/Mac. Процесс создания загрузчиков памяти одинаков, независимо от типа формата файла. В этом случае мы просто рассмотрим различия между процессом для объектов COFF и объектов ELF. Создание загрузчиков памяти для файлов ELF не является чем-то новым. Единственная новая вещь здесь — добавление внутренних функций Cobalt Strikes BOF. ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

ПОНИМАНИЕ ФОРМАТА ELF

В отличие от того, что мы сделали с COFFLoader, структуры заголовков для файлов ELF доступны. Он начинается со структуры Elf64_Ehdr, которая содержит тип, машину, точку входа и всю необходимую информацию о разделах. Вторая структура — это структура Elf64_Phdr (заголовки программ), реализованная в виде массива записей. В данном случае он не используется, так как ничего не связывается, поэтому его можно пропустить. Последние две структуры Elf64_Shdr (заголовки разделов) или Elf64_Sym (символы) будут использоваться для большей части загрузки. Заголовки разделов определяют размер, смещение и разрешения, которые будут использоваться для выделения, загрузки и установки разрешений.

ОПРЕДЕЛЕНИЕ СТРУКТУР

Для этого мы можем сделать одно из двух: мы можем либо переопределить структуры, чтобы они были более переносимыми, либо другим решением является копирование предопределенного заголовка с небольшими изменениями. В этом не было бы необходимости, если бы вы собирались создавать только системы на базе Linux или BSD, которые используют файлы elf, но для Mac вам это понадобится, поскольку заголовок недоступен. В случае с этим проектом я делаю заголовок «minimal_elf» на основе заголовков FreeBSD. Основная причина использования заголовков FreeBSD вместо LGPL в Linux — это просто лицензирование. Ниже приведены скриншоты всех структур заголовков, которые нам нужно будет переопределить.

ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

Структура Ehdr из elf.h

ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

Структура Shdr из elf.h

ELFLOADER: ЕЩЕ ОДИН ЗАГРУЗЧИК В ПАМЯТИ

Структура Sym из elf.h

РАЗБОР ФОРМАТА

Как только вы определили все структуры, вы можете начать синтаксический анализ объектного файла. Процесс почти такой же, как и при написании COFFLoader. Основные отличия заключаются в том, что вы устанавливаете структуру Ehdr в качестве начала считываемых байтов, получаете смещения для заголовка программы, заголовков разделов и заголовков символов, затем перебираете заголовки разделов, чтобы загрузить разделы в память, и повторяете процесс. для обработки всех перемещений и символов.

СВЯЗЫВАНИЕ/ЗАГРУЗКА

При переборе заголовков разделов мы можем выделить память с помощью «mmap», скопировать память с помощью «memcpy», обработать перемещения в отдельном цикле, а затем «mprotect» все разделы с действительными разрешениями. С COFFLoader мы использовали тот же метод поиска функций, что и Cobalt Strike, для разрешения символов, тогда как для этого мы собираемся разрешать с использованием библиотек ОС по умолчанию. В случае Linux мы используем libc, а Mac — libSystemB, оба используют «dlsym» с переопределенным RTLD_DEFAULT соответствующих значений.

СОЗДАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ

В этом все отличается от проекта COFFLoader. Чтобы построить объектные файлы, вам нужно построить с несколькими флагами. Для x86 вам нужно использовать «-fno-stack-protector» и «-fno-pie». Для x86_64 вам просто нужно использовать «-fPIC», а остальное примерно то же самое. При создании функций, специфичных для Mac, вам нужно дважды проверить ОС с помощью «uname», а затем использовать «dlopen»/«dlsym» для разрешения символов и определения всех функций, которые вы собираетесь использовать. На данный момент в проекте нет таких примеров, но будет работать над несколькими примерами.

Пример построения объекта whoami

ВЫПОЛНЕНИЕ

После того, как все разделы скопированы, перемещения обработаны и разрешения установлены, остается только запустить код. Для этого мы можем просто сохранить указатель символа точки входа, в данном случае «go», привести его к указателю, а затем запустить указатель.

Сравнение строк, сохранение указателя.

Запуск указателя.

Пример вывода из объектного файла uname.

ЗАКЛЮЧЕНИЕ

Теперь, когда у нас есть версия ELF, мы можем использовать ее в разных операционных системах (Linux и Mac) без необходимости компилировать для каждой ОС. Объединив эту версию с версией COFFLoader, мы можем использовать стандартный процесс для совместного использования возможностей между агентами и платформами как для систем *nix, так и для Windows.

Практические ссылки по статье

     •           https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf64.h

            •           https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf_common.h

            •           https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf32.h

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Click to rate this post!
[Total: 0 Average: 0]

Leave a reply:

Your email address will not be published.