Всем привет, решил скопировать сюда тоже свою статью с васма:https://wasm.in/threads/chto-takoe-...ta-i-analiz-primenenija-anklava-v-bleke.33910
Изначально писал сюда под конкурс, но понял что на данный момент у меня знаний нехватает для написания статей под конкурс, т.к. получаются сборные статьи из нескольких статей, которые уже есть в паблике, либо частичные переводы, что может как минимум нарушать правила конкурса, ну и если сравнивать с другими статьями, к сожалению недотягивает что-бы конкурировать с ними...
Но тем не менее кому-то такие статьи могут быть интересны.)))
Мотивация написать такую статью, было то-что часто слышу, что есть такой самый крутой анклав, который может прятать данные ваших программ от реверсера, антивирусов и даже операционной системы.
Звучит как в сказке, а действительно было-бы не плохо прятать какие-то данные от лишних глаз реверсера, или еще кого.
Я начал разбираться, а как можно создать такой анклав и что-то сделать с ним ?
Кому интересно, предлагаю прочитать эту статью.
Хочу отметить, что статья направлена больше для новичков, которые мало понимают что такое SGX и даёт поверхностные знания, что это за технология.
Итак, что-же такое анклав ?
Если кратко, то весь смысл Intel SGX (А мы будем говорить именно про него) по сути сводится к тому-что, в процессоре есть какая-то защищенная область памяти, которая доступна только процессору, больше никто даже операционная система доступ туда получить не может, по сути это и есть анклав.
В модели SGX приложение делится на доверенную и ненадежную часть. Недоверенная часть - это та часть, которая взаимодействует с остальной системой, а также создает анклав, который считается безопасной частью приложения (Это доверенная часть).
Внутри анклава хранятся важные данные, доступные только процессору.
Все экземпляры анклава изолированы друг от друга, поэтому они могут взаимодействовать только через свою ненадежную часть.
Доверенный и недоверенный код жестко связываются между собой ключами шифрования с использованием протокола Диффи-Хеллмана.
За процедуру подписи отвечает процессор, где и хранится ключ обмена информации, обновляющийся каждый раз при перезагрузке системы. Содержимое анклавов хранится в общей памяти, используемой пользовательскими приложениями, однако хранение происходит в зашифрованном виде. Расшифровать содержимое может только процессор.
Вообще по теме много публикаций есть, цель этой статьи дать начальное представление о SGX, также показать как сделать каркас проекта для дальнейших экспериментов.
Ещё пару строк про функции ECALL и OCALL:
Доверенная часть представляет из себя набор функций и процедур, называемых ECALL (Enclave Call). Сигнатура таких функций должна быть прописана в специальном header-файле, а их реализация в файле с исходным кодом доверенного приложения, которое будет выполняться в процессоре.
Enclave Call – Это реализация программы в анклаве.
Также необходимо прописать прототипы тех функций, которые можно будет вызвать изнутри анклава в недоверенное приложение, такие функции называются OCALL (Outside Call). Прототипы прописываются в том же заголовочном файле, где и ECALL-функции, а реализация, в отличие от ECALL, прописывается соответственно в недоверенной части приложения.
Давайте перейдем к реализации простого примера:
Итак предлагаю написать демонстрационный пример, который просто передаст какие-то защищенные данные из анклава в наше приложение.
Ну например, пусть в анклаве у нас будет хранится какой-то буфер:
сhar* enclave_secret = "I am enclave !";
Этот буфер нам и нужно передать в наше приложение, в будущем эти наработки можно использовать как каркас, для написания более сложных приложений, например внутри анклава можно реализовать алгоритмы шифрования/расшифрования, ну тогда вы будете уже передавать приложению расшифрованные данные и т. д.
Итак, что-же нам нужно для работы:
1)Скачать и установить Visual Studio, я использую 2019 версию...
2)Cкачать и установить SDK для работы с SGX:https://software.intel.com/content/www/us/en/develop/topics/software-guard-extensions/sdk.html
В процессе скачки, будет предложена утомительная регистрация, но думаю вы справитесь...)))
На этапе установки будет предложено интегрировать пакет разработки в имеющуюся на компьютере версию VS, сделайте это.
Итак запускаем вижуалку и создаём проект:
Далее такое окно:
Тут я оставил всё как есть:
Затем добавим к созданному решению, ещё один проект: обычное консольное приложение C++.
В результате у нас должно быть что-то такое в обозревателе решений:
Теперь необходимо связать анклав с нашей программой консоли (Это недоверенная часть), для этого жмем правой кнопкой на проекте «Console_demo»:
Теперь нужно изменить некоторые свойства проекта «Console_demo» и «Enclave_demo»:
ОБЯЗАТЕЛЬНО СДЕЛАЙТЕ ЭТИ НАСТРОЙКИ ДЛЯ ДВУХ ПРОЕКТОВ:
Ещё необходимо обозначить в свойствах решения главный проект.
Всё мы закончили настройки, теперь давайте кодить…)
У нас два решения:
«Console_demo» и «Enclave_demo»:
Из сгенерированных файлов, нам будет интересно три файла:
1) Enclave_demo.edl – Это по сути заголовочный файл, туда мы пропишем имена и прототипы ECALLs и OCALLs функций (Проект «Enclave_demo»).
2) Enclave_demo.cpp – Это доверенная часть приложения (Проект «Enclave_demo»). Тут будет реализация ECALLs.
3) Console_demo.cpp – Это недоверенная часть приложения (Проект «Console_demo»). Тут будет реализация OCALLs.
Пропишем реализацию Console_demo.cpp:
Реализация Enclave_demo.cpp:
Реализация заголовочного файла Enclave_demo.edl:
В итоге после запуска консольного приложения, отрабатывает функция анклава ecall_function доверенного приложения, которая вызывает функцию в недоверенное приложение ocall_function и будет вывод: +++ OCALL output: I am enclave !
Далее функция ecall_function, копирует данные из анклава в буфер недоверенного приложения и этот буфер мы и распечатываем.
И будет вывод: +++ ECALL Output: I am enclave !
Выводы:
Как видите если использовать SDK от интела и Visual Studio, то работать с анклавами достаточно не сложно, нужно просто реализовать ECALLs/OCALLs функции для обмена с анклавом из вашего приложения.
Пример проекта можно глянуть в гите:https://github.com/XShar/Enclave_demo
Теперь можно-ли это применять в малваре ?
С одной стороны не плохо-бы делать так криптовку/раскриптовку строк, или самого зверька, реализовав весь алгоритм в ECALL функции.
Но тут есть негативные моменты:
1. Не все процессоры поддерживают SGX.
А поддерживают только новые компьютеры, начиная с 2016-2017 годов.
2. На некоторых компьютерах поддержку нужно включать в биос.
Ну и самый распространенный миф, что эта технология может обойти детект в памяти, при работе например крипторов, увы, но думаю что нет, т.к. память процесса должна-быть видна в системе, а раз она видна в системе, значит будет видна и антивирусу.
В целом плюсы этой технологии в том-что вы можете сами реализовывать ECALL - функции и то-что реализовано в этой функции не должно-быть доступно антивирусу и реверсеру.)
Надеюсь данная статья даст объяснение новичкам что такое SGX, также приведенный тут проект можно использовать для экспериментов и дальнейшего изучения технологии.)
Изначально писал сюда под конкурс, но понял что на данный момент у меня знаний нехватает для написания статей под конкурс, т.к. получаются сборные статьи из нескольких статей, которые уже есть в паблике, либо частичные переводы, что может как минимум нарушать правила конкурса, ну и если сравнивать с другими статьями, к сожалению недотягивает что-бы конкурировать с ними...
Но тем не менее кому-то такие статьи могут быть интересны.)))
Мотивация написать такую статью, было то-что часто слышу, что есть такой самый крутой анклав, который может прятать данные ваших программ от реверсера, антивирусов и даже операционной системы.
Звучит как в сказке, а действительно было-бы не плохо прятать какие-то данные от лишних глаз реверсера, или еще кого.
Я начал разбираться, а как можно создать такой анклав и что-то сделать с ним ?
Кому интересно, предлагаю прочитать эту статью.
Хочу отметить, что статья направлена больше для новичков, которые мало понимают что такое SGX и даёт поверхностные знания, что это за технология.
Итак, что-же такое анклав ?
Если кратко, то весь смысл Intel SGX (А мы будем говорить именно про него) по сути сводится к тому-что, в процессоре есть какая-то защищенная область памяти, которая доступна только процессору, больше никто даже операционная система доступ туда получить не может, по сути это и есть анклав.
В модели SGX приложение делится на доверенную и ненадежную часть. Недоверенная часть - это та часть, которая взаимодействует с остальной системой, а также создает анклав, который считается безопасной частью приложения (Это доверенная часть).
Внутри анклава хранятся важные данные, доступные только процессору.
Все экземпляры анклава изолированы друг от друга, поэтому они могут взаимодействовать только через свою ненадежную часть.
Доверенный и недоверенный код жестко связываются между собой ключами шифрования с использованием протокола Диффи-Хеллмана.
За процедуру подписи отвечает процессор, где и хранится ключ обмена информации, обновляющийся каждый раз при перезагрузке системы. Содержимое анклавов хранится в общей памяти, используемой пользовательскими приложениями, однако хранение происходит в зашифрованном виде. Расшифровать содержимое может только процессор.
Вообще по теме много публикаций есть, цель этой статьи дать начальное представление о SGX, также показать как сделать каркас проекта для дальнейших экспериментов.
Ещё пару строк про функции ECALL и OCALL:
Доверенная часть представляет из себя набор функций и процедур, называемых ECALL (Enclave Call). Сигнатура таких функций должна быть прописана в специальном header-файле, а их реализация в файле с исходным кодом доверенного приложения, которое будет выполняться в процессоре.
Enclave Call – Это реализация программы в анклаве.
Также необходимо прописать прототипы тех функций, которые можно будет вызвать изнутри анклава в недоверенное приложение, такие функции называются OCALL (Outside Call). Прототипы прописываются в том же заголовочном файле, где и ECALL-функции, а реализация, в отличие от ECALL, прописывается соответственно в недоверенной части приложения.
Давайте перейдем к реализации простого примера:
Итак предлагаю написать демонстрационный пример, который просто передаст какие-то защищенные данные из анклава в наше приложение.
Ну например, пусть в анклаве у нас будет хранится какой-то буфер:
сhar* enclave_secret = "I am enclave !";
Этот буфер нам и нужно передать в наше приложение, в будущем эти наработки можно использовать как каркас, для написания более сложных приложений, например внутри анклава можно реализовать алгоритмы шифрования/расшифрования, ну тогда вы будете уже передавать приложению расшифрованные данные и т. д.
Итак, что-же нам нужно для работы:
1)Скачать и установить Visual Studio, я использую 2019 версию...
2)Cкачать и установить SDK для работы с SGX:https://software.intel.com/content/www/us/en/develop/topics/software-guard-extensions/sdk.html
В процессе скачки, будет предложена утомительная регистрация, но думаю вы справитесь...)))
На этапе установки будет предложено интегрировать пакет разработки в имеющуюся на компьютере версию VS, сделайте это.
Итак запускаем вижуалку и создаём проект:
Далее такое окно:
Тут я оставил всё как есть:
Затем добавим к созданному решению, ещё один проект: обычное консольное приложение C++.
В результате у нас должно быть что-то такое в обозревателе решений:
Теперь необходимо связать анклав с нашей программой консоли (Это недоверенная часть), для этого жмем правой кнопкой на проекте «Console_demo»:
Теперь нужно изменить некоторые свойства проекта «Console_demo» и «Enclave_demo»:
ОБЯЗАТЕЛЬНО СДЕЛАЙТЕ ЭТИ НАСТРОЙКИ ДЛЯ ДВУХ ПРОЕКТОВ:
Ещё необходимо обозначить в свойствах решения главный проект.
Всё мы закончили настройки, теперь давайте кодить…)
У нас два решения:
«Console_demo» и «Enclave_demo»:
Из сгенерированных файлов, нам будет интересно три файла:
1) Enclave_demo.edl – Это по сути заголовочный файл, туда мы пропишем имена и прототипы ECALLs и OCALLs функций (Проект «Enclave_demo»).
2) Enclave_demo.cpp – Это доверенная часть приложения (Проект «Enclave_demo»). Тут будет реализация ECALLs.
3) Console_demo.cpp – Это недоверенная часть приложения (Проект «Console_demo»). Тут будет реализация OCALLs.
Пропишем реализацию Console_demo.cpp:
C:
#define ENCLAVE_FILE "Enclave.signed.dll" //Библиотека, через которую осуществляется подпись анклава
#define BUFFER_LEN 256 //Размер буфера данных, которые мы отправляем в анклав
#include "sgx_urts.h" //Базовый заголовочный файл, в котором реализованы функции управления анклавом
#include "Enclave_demo_u.h" //Подключение автоматически сгенерированного файла
#include "stdio.h"
void ocall_function(char* buf) //OCALL функция для вывода текстовой строки - секрета из анклава. Вызов из анклава.
{
printf("+++ OCALL output: %s\n", buf);
}
static sgx_enclave_id_t enclave_id = 0; // id анклава, в проекте может быть несколько анклавов, каждый со своим id
static sgx_status_t enclave_ret = SGX_SUCCESS; //Статус выполнения операции
static sgx_launch_token_t enclave_token = { 0 }; //Массив нициализации токена запуска для анклава
static int enclave_token_updated = 0; // Флаг, что токен запуска не был изменен
static char buffer[BUFFER_LEN]; // Буфер, в который будет записан секрет из анклава
int main()
{
sgx_status_t ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &enclave_token, &enclave_token_updated, &enclave_id, NULL); //Функция создания анклава
if (ret != SGX_SUCCESS)
{
printf("+++ Failed to create enclave with error number: %#x\n", ret);
return 0;
}
ecall_function(enclave_id, buffer, BUFFER_LEN); //Вызов ECALL функции
printf("\n+++ ECALL Output: %s\n", buffer); //Вывод полученного секрета
system("pause");
}
Реализация Enclave_demo.cpp:
C:
#include "Enclave_demo_t.h"
#include "sgx_trts.h"
#include <cstring>
void ecall_function(char* str, size_t len)
{
char* secret = "I am enclave !"; // Наша секретная фраза
memcpy(str, secret, len); //Копируем секрет по адресу, которую получили
ocall_function(secret); //Вызов OCALL-функции
}
Реализация заголовочного файла Enclave_demo.edl:
C:
enclave {
from "sgx_tstdc.edl" import *;
trusted {
/* define ECALLs here. */
public void ecall_function([out, size=len] char* str, size_t len);
};
untrusted {
/* define OCALLs here. */
void ocall_function([in, string] char* buf);
};
};
В итоге после запуска консольного приложения, отрабатывает функция анклава ecall_function доверенного приложения, которая вызывает функцию в недоверенное приложение ocall_function и будет вывод: +++ OCALL output: I am enclave !
Далее функция ecall_function, копирует данные из анклава в буфер недоверенного приложения и этот буфер мы и распечатываем.
И будет вывод: +++ ECALL Output: I am enclave !
Выводы:
Как видите если использовать SDK от интела и Visual Studio, то работать с анклавами достаточно не сложно, нужно просто реализовать ECALLs/OCALLs функции для обмена с анклавом из вашего приложения.
Пример проекта можно глянуть в гите:https://github.com/XShar/Enclave_demo
Теперь можно-ли это применять в малваре ?
С одной стороны не плохо-бы делать так криптовку/раскриптовку строк, или самого зверька, реализовав весь алгоритм в ECALL функции.
Но тут есть негативные моменты:
1. Не все процессоры поддерживают SGX.
А поддерживают только новые компьютеры, начиная с 2016-2017 годов.
2. На некоторых компьютерах поддержку нужно включать в биос.
Ну и самый распространенный миф, что эта технология может обойти детект в памяти, при работе например крипторов, увы, но думаю что нет, т.к. память процесса должна-быть видна в системе, а раз она видна в системе, значит будет видна и антивирусу.
В целом плюсы этой технологии в том-что вы можете сами реализовывать ECALL - функции и то-что реализовано в этой функции не должно-быть доступно антивирусу и реверсеру.)
Надеюсь данная статья даст объяснение новичкам что такое SGX, также приведенный тут проект можно использовать для экспериментов и дальнейшего изучения технологии.)