• [ Регистрация ]Открытая и бесплатная
  • Tg admin@ALPHV_Admin (обязательно подтверждение в ЛС форума)

Статья Модуль 2 MalDev Academy на русском

stihl

Moderator
Регистрация
09.02.2012
Сообщения
1,179
Розыгрыши
0
Реакции
510
Deposit
0.228 BTC
stihl не предоставил(а) никакой дополнительной информации.
Модуль 2 Maldev Academy Модуль под моей редакцией состоит из двух частей.

  • Первая - это ознакомительный модуль с концепцией хранения и управления ОЗУ
  • Вторая - это обзор минимально необходимого функционала WinApi
m18.jpg


Часть 1 “Виртуальная память и ее хранение.”

Virtual Memory & Paging


Память в ОС не отображается напрямую в ОЗУ. Вместо этого виртуальные адреса памяти используются процессами, которые отображаются на адреса физической памяти. Для этого есть несколько причин, но в конечном итоге цель состоит в том, чтобы сэкономить как можно больше физической памяти. Виртуальная память может отображаться на физическую память, но также может храниться на диске. Благодаря адресации виртуальной памяти становится возможным, чтобы несколько процессов совместно использовали один и тот же физический адрес, имея при этом уникальный адрес виртуальной памяти. Виртуальная память основана на концепции страничного обмена памятью, которая делит память на фрагменты по 4 КБ, называемые «страницы».

m19.jpg


Page State

Страницы, находящиеся в виртуальном адресном пространстве процесса, могут находиться в одном из трех состояний:

  • Free — страница не зафиксирована и не зарезервирована. страница недоступна для процесса. Она доступна для резервирования, фиксации или одновременной фиксации и фиксации. Попытка чтения или записи на свободную страницу может привести к исключению нарушения доступа.
  • Reserved — страница зарезервирована для будущего использования. Диапазон адресов не может использоваться другими функциями распределения. страница недоступна и не имеет физического хранилища, связанного с ней. Она доступна для фиксации.
  • Committed - Затраты памяти были выделены из общего размера RAM и файлов подкачки на диске. страница доступна, и доступ контролируется одной из констант защиты памяти.Система инициализирует и загружает каждую зафиксированную страницу в физическую память только во время первой попытки чтения или записи на эту страницу.Когда процесс завершается, система освобождает хранилище для зафиксированных страниц.
Page Protection Options

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

  • PAGE_NOACCESS - Отключает любой доступ к зафиксированной области страниц. Попытка чтения, записи или выполнения зафиксированной области приведет к нарушению доступа.
  • PAGE_EXECUTE_READWRITE - Позволяет читать, писать и выполнять. Это крайне не рекомендуется использовать, и обычно это IoC, поскольку память редко бывает одновременно доступной для записи и выполнения.
  • PAGE_READONLY - Разрешает доступ только для чтения к выделенному региону страниц. Попытка записи в выделенный регион приводит к нарушению прав доступа.
Memory Protection

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

  • DEP — это функция защиты памяти на системном уровне, встроенная в операционную систему, начиная с Windows XP и Windows Server 2003. Если параметр защиты страниц установлен на PAGE_READONLY, то DEP предотвратит выполнение кода в этой области памяти.
  • ASLR — это метод защиты памяти, используемый для предотвращения эксплуатации уязвимостей повреждения памяти. ASLR случайным образом упорядочивает позиции адресного пространства ключевых областей данных процесса, включая базу исполняемого файла и позиции стека, кучи и библиотек.
m26.jpg


x86 vs x64 Memory Space

При работе с процессами Windows важно учитывать, является ли процесс x86 или x64. Процессы x86 имеют меньший объем памяти — 4 ГБ 0xFFFFFFFF, тогда как x64 имеет значительно больший объем памяти — 128 ТБ 0xFFFFFFFFFFFFFFFF.

Allocating Memory Example

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

//Выделение 100 bytes буфера памяти

// Метод 1 - Используем malloc()
PVOID pAddress = malloc(100);

// Метод 2 - Используем HeapAlloc()
PVOID pAddress = HeapAlloc(GetProcessHeap(), 0, 100);

// Метод 3 - Используем LocalAlloc()
PVOID pAddress = LocalAlloc(LPTR, 100);

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

m20.jpg


Writing To Memory Example

Ниже пример записи в память. В нем используется memcpy.

PVOID pAddress = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
CHAR* cString = "I'm a cool hacker. Fsociety";
memcpy(pAddress, cString, strlen(cString));

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

m21.jpg


Freeing Allocated Memory

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

  • Выделение с помощью malloc требует использования функции free.
  • Выделение с помощью HeapAlloc требует использования функции HeapFree.
  • Выделение с помощью LocalAlloc требует использования функции LocalFree.
Ниже показан HeapFree в действии, освобождение выделенной памяти по адресу 0000023ADE449900. Обратите внимание, что адрес 0000023ADE449900 все еще существует в процессе, но его исходное содержимое было перезаписано случайными данными.
m22.jpg


m23.jpg


Часть 2 “Основы WinApi”

m28.jpg


Windows Data Types

В Windows API есть много типов данных помимо общеизвестных (например, int, float). Типы данных документированы и их можно посмотреть Для просмотра ссылки Войди или Зарегистрируйся.

Некоторые из распространенных типов данных перечислены ниже:

  • DWORD- 32-битное целое число без знака, используемое как в 32-битных, так и в 64-битных системах для представления значений от 0 до (2^32 - 1).
DWORD dwVariable = 42;

  • size_t- Используется для представления размера объекта. Это 32-битное целое число без знака в 32-битных системах, представляющее значения от 0 до (2^32 - 1). С другой стороны, это 64-битное целое число без знака в 64-битных системах, представляющее значения от 0 до (2^64 - 1).
SIZE_T sVariable = sizeof(int);

  • VOID- Указывает на отсутствие определенного типа данных.
void* pVariable = NULL;

  • PVOID- 32-битный или 4-байтный указатель любого типа данных на 32-битных системах. Альтернативно, 64-битный или 8-байтный указатель любого типа данных на 64-битных системах.
PVOID pVariable = &SomeData;

  • HANDLE- Значение, указывающее конкретный объект, которым управляет операционная система (например, файл, процесс, поток).
HANDLE hFile = CreateFile(...);

  • HMODULE- Дескриптор модуля. Это базовый адрес модуля в памяти. Примером МОДУЛЯ может быть файл DLL или EXE.
HMODULE hModule = GetModuleHandle(...);

  • LPCSTR/PCSTR- Указатель на постоянную строку с нулевым завершением из 8-битных символов Windows (ANSI). «L» означает «long», что произошло от периода 16-битного программирования Windows, в настоящее время это не влияет на тип данных, но соглашение об именовании все еще существует. «C» означает «constant» или переменная только для чтения. Оба эти типа данных эквивалентны const char*.
LPCSTR lpcString = "Hello, world!";
PCSTR pcString = "Hello, world!";

  • LPSTR/PSTR- То же самое, что LPCSTRи PCSTR, единственное отличие в том, что LPSTRи PSTR не указывают на константную переменную, а вместо этого указывают на читаемую и записываемую строку. Оба эти типа данных эквивалентны char*.
LPSTR lpString = "Hello, world!";
PSTR pString = "Hello, world!";

  • LPCWSTR\PCWSTR- Указатель на константную строку с нулевым завершением из 16-битных символов Windows Unicode (Unicode). Оба эти типа данных эквивалентны const wchar*.
LPCWSTR lpwcString = L"Hello, world!";
PCWSTR pcwString = L"Hello, world!";

  • PWSTR\LPWSTR- То же самое, что LPCWSTRи PCWSTR, единственное отличие в том, что ‘PWSTR’ и ‘LPWSTR’ не указывают на константную переменную, а вместо этого указывают на читаемую и записываемую строку. Оба эти типа данных эквивалентны wchar*.
LPWSTR lpwString = L"Hello, world!";
PWSTR pwString = L"Hello, world!";

  • wchar_t- То же самое, wcharчто используется для представления широких символов.
wchar_t wChar = L'A';
wchar_t* wcString = L"Hello, world!";

  • ULONG_PTR- Представляет беззнаковое целое число того же размера, что и указатель на указанной архитектуре, то есть на 32-битных системах ULONG_PTR будет иметь размер 32 бита, а на 64-битных системах — 64 бита. На протяжении всего курса ULONG_PTR будет использоваться для манипулирования арифметическими выражениями, содержащими указатели (например, PVOID). Перед выполнением любой арифметической операции указатель будет подвергнут приведению типа к ULONG_PTR. Этот подход используется для того, чтобы избежать прямого манипулирования указателями, которое может привести к ошибкам компиляции.
PVOID Pointer = malloc(100);
Pointer = (ULONG_PTR)Pointer + 10;

Data Types Pointers

Windows API позволяет разработчику объявлять тип данных напрямую или указатель на тип данных. Это отражено в именах типов данных, где типы данных, начинающиеся с «P», представляют указатели на фактический тип данных, а те, которые не начинаются с «P», представляют сам фактический тип данных. будет очень полезным позже при работе с API Windows, имеющими параметры, которые являются указателями на тип данных. Примеры ниже показывают, как тип данных “P” выглядит без указателя.

  • PHANDLE то же самое, что и HANDLE*.
  • PSIZE_T то же самое, что и SIZE_T*.
  • PDWORD то же самое, что и DWORD*.
ANSI & Unicode Functions Большинство функций Windows API имеют две версии, заканчивающиеся на «A» или на «W». Например, есть CreateFileA и CreateFileW. Функции, заканчивающиеся на «A», предназначены для обозначения «ANSI», тогда как функции, заканчивающиеся на «W», представляют Unicode или «Wide».

Главное отличие, которое следует иметь в виду, заключается в том, что функции ANSI будут принимать типы данных ANSI в качестве параметров, тогда как функции Unicode будут принимать типы данных Unicode. Например, первый параметр для CreateFileA — это LPCSTR, который является указателем на постоянную строку с нулевым завершением из 8-битных символов Windows ANSI. С другой стороны, первый параметр для CreateFileW — это LPCWSTR, указатель на постоянную строку с нулевым завершением из 16-битных символов Unicode.

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

char str1[] = "fsociety";// 9 байт (fsociety + нулевой байт ).

wchar str2[] = L"fsociety";// 18 байт, каждый символ — 2 байта (нулевой байт также 2 байта)

In and Out Parameters

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

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

BOOL fsociety(OUT int* num){
*num = 123;
return TRUE;
};
int main(){
int a = 0;
fsociety(&a);
};

Имейте в виду, что использование ключевых слов OUT и IN призвано облегчить разработчикам понимание того, что ожидает функция и что она делает с этими параметрами. Однако стоит отметить, что исключение этих ключевых слов не влияет на то, считается ли параметр выходным или входным параметром.

m27.jpg


Analyze Return Type & Parameters

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

Кроме того, обратите внимание, что все параметры функции являются in. Это означает, что функция не возвращает никаких данных из параметров, поскольку все они являются in. Помните, что ключевые слова в квадратных скобках, такие как in, out, и optional, предназначены исключительно для справки разработчиков и не оказывают никакого фактического влияния.

HANDLE CreateFileW(
[in] LPCWSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);

Use The Function

В примере кода ниже представлен пример использования CreateFileW. Он создаст текстовый файл с именем fsociety.txt на рабочем столе текущего пользователя.

Handle hFile = INVALID_HANDLE_VALUE;
LPCWSTR filePath = L"C:\\Users\\maldevacademy\\Desktop\\fsociety.txt";
hFile = CreateFileW(filePath, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE){
printf("[-] CreateFileW Api Function Failed With Error : %d\n", GetLastError());
return -1;
};

Windows API Debugging Errors

Когда в функции возникает ошибка, они часто возвращают лог. Например, если в CreateFileW что-то пошло не так, возвращается сообщение INVALID_HANDLE_VALUE, указывающее на то, что файл не может быть создан. Чтобы получить больше информации о том, почему файл не может быть создан, необходимо получить код ошибки с помощью функции Для просмотра ссылки Войди или Зарегистрируйся.

m29.jpg


После извлечения кода его необходимо найти в Для просмотра ссылки Войди или Зарегистрируйся. Ниже приведены некоторые распространённые коды ошибок:

  • 5 - ERROR_ACCESS_DENIED
  • 2 - ERROR_FILE_NOT_FOUND
  • 87 - ERROR_INVALID_PARAMETERР
Windows Native API Debugging Errors

Вспомним модуль архитектуры Windows : NTAPI в основном экспортируются из ntdll.dll. В отличие от API Windows, эти функции не могут получить свой код ошибки через GetLastError. Вместо этого они возвращают код ошибки напрямую, который представлен типом NTSTATUS данных. NTSTATUS используется для представления статуса системного вызова или функции и определяется как 32-битное целое число без знака. Успешный системный вызов вернет значение STATUS_SUCCESS, которое равно 0. Ниже фрагмент кода показывает, как выполняется проверка ошибок системных вызовов.

NTSTATUS STATUS = NativeSyscallExample(...);
if (STATUS != STATUS_SUCCESS){`
printf("[!] NativeSyscallExample Failed With Status : 0x%0.8X \n", STATUS);
};

NT_SUCCESS Macroc

Другой способ проверки возвращаемого значения NTAPI — через NT_SUCCESS макрос. Он возвращает, TRUE если функция выполнена успешно, и FALSE если она не выполнена.

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

Ниже пример такого макроса.

NTSTATUS STATUS = NativeSyscallExample(...);
if (!NT_SUCCESS(STATUS)){
printf("[!] NativeSyscallExample Failed With Status : 0x%0.8X \n", STATUS);
};

m24.jpg


Надеюсь ваши мозги еще не поплавились и вы успешно доползли до конца этого модуля. Теперь дз или вы рассчитывали, что после прочтения данного модуля у вас и дз не будет?

Написать утилиту на Cи, которая выполняет следующие действия:

  • Статически выделяет память для хранения строки: “I’m a cool hacker. Soon I’ll fuck the whole world and I’ll have a cool botnet. fsociety”.
  • Копирует эту строку в выделенную память.
  • Получает путь к рабочему столу пользователя.
  • Создает текстовый файл с именем fsociety.txt на рабочем столе.
  • Записывает строку из статической памяти в созданный файл.
  • Обрабатывает возможные ошибки (например, ошибка создания файла, ошибка получения пути к рабочему столу).
m25.jpg
 
Activity
So far there's no one here
Сверху Снизу